Welcome to Doom9's Forum, THE in-place to be for everyone interested in DVD conversion.

Before you start posting please read the forum rules. By posting to this forum you agree to abide by the rules.

 

Go Back   Doom9's Forum > General > Subtitles

Reply
 
Thread Tools Search this Thread Display Modes
Old 20th April 2009, 20:11   #1  |  Link
ps auxw
Registered User
 
Join Date: Apr 2009
Posts: 102
AviSynth rendered subtitles to BluRay SUP/PGS and BDN XML (v2.08)

AVS to BluRay SUP/PGS and BDN XML


News

As of version 2.00, avs2bdnxml supports direct conversion to the BluRay SUP format. This is still somewhat experimental, but seems to work for many people.


History

First, a bit of history. I wrote avs2bdnxml in late 2008 as the result of a discussion with Daiz in the x264 IRC channel. Back then, there wasn't a reasonable way to actually do something useful with BDN XML files, so I mostly forgot about it. Now there are at least two programs, which can convert BDN XML+PNG to BD-SUP format. This resulted in me fixing a couple of bugs, and then deciding to post it here.


Purpose

Now, what does it do, you might ask. The answer to this is pretty simple. avs2bdnxml takes an AviSynth script which outputs RGBA, and turns it into a BDN XML file + PNG files. Now, it seems that Ulf wrote something similar. The main difference is that avs2bdnxml can convert anything AviSynth can generate to BDN XML (just make sure it still looks good after being palletized), not just subtitles.

For example you can turn the following (and combinations thereof) into BluRay subtitles:
  • Anything that VSFilter can render. SRT, (animated) ASS/SSA, etc..
  • Logos/pictures.
  • RGBA video overlays made with Adobe AfterEffects.


Usage
  1. First you'll need an AviSynth script. If you have a regular subtitle file you want to render using VSFilter (you'll need at least VSFilter 2.39), do something like this:
    Code:
    video=AviSource("video.avi")
    MaskSub("subtitles.ext",video.width,video.height,video.framerate,video.framecount)
    If you have an RGBA video, do something like this instead:
    Code:
    AviSource("subtitles_RGBA.avi")
    FlipVertical()
  2. Now you'll have to run avs2bdnxml. Since it is a command line application, you'll either have to use cmd, some other shell or write a batch file.
    Code:
    Usage: avs2bdnxml [options] -o output input
    
    Input has to be an AviSynth script with RGBA as output colorspace
    
      -o, --output <string>        Output file in BDN XML format
                                   For SUP/PGS output, use a .sup extension
      -j, --seek <integer>         Start processing at this frame, first is 0
      -c, --count <integer>        Number of input frames to process
      -t, --trackname <string>     Name of track, like: Undefined
      -l, --language <string>      Language code, like: und
      -v, --video-format <string>  Either of: 480i, 480p,  576i,
                                              720p, 1080i, 1080p
      -f, --fps <float>            Either of: 23.976, 24, 25, 29.97, 50, 59.94
      -x, --x-offset <integer>     X offset, for use with partial frames.
      -y, --y-offset <integer>     Y offset, for use with partial frames.
      -d, --t-offset <string>      Offset timecodes by this many frames or
                                   given non-drop timecode (HH:MM:SS:FF).
      -s, --split-at <integer>     Split events longer than this, in frames.
                                   Disabled when 0, which is the default.
      -m, --min-split <integer>    Minimum length of line segment after split.
      -e, --even-y <integer>       Enforce even Y coordinates. [on=1, off=0]
      -a, --autocrop <integer>     Automatically crop output. [on=1, off=0]
      -p, --palette <integer>      Output 8bit palette PNG. [on=1, off=0]
      -n, --null-xml <integer>     Allow output of empty XML files. [on=1, off=0]
      -z, --stricter <integer>     Stricter checks in the SUP writer. May lead to
                                   less optimized buffer use, but might raise
                                   compatibility. [on=1, off=0]
      -u, --ugly <integer>         Allow splitting images in ugly ways.
                                   Might improve buffer problems, but is ugly.
                                   [on=1, off=0]
      -b, --buffer-opt <integer>   Optimize PG buffer size by image
                                   splitting. [on=1, off=0]
    Example:
    Code:
    avs2bdnxml -t Undefined -l und -v 1080p -f 23.976 -a1 -p1 -b0 -m3 -u0 -e0 -n0 -z0 -o output.xml input.avs
    Input and output are required settings. The rest are set to default, as per the example. Please note that the image files will be named 00000000_0.png, ..., 99999999_1.png, and will be written to the same directory as the XML file. Existing files with these names will be overwritten. XML files created with -b1 might not be supported by anything but Scenarist and EasyBD. You can generate SUP and BDN-XML output at the same time by specifying -o twice.
  3. To get SUP output, just change the output filename extension to .sup, for example: -o output.sup
  4. Wait until it's done. You should now have a nice BDN XML file, and a bunch of PNG files.
  5. For some programs, you have to convert the PNG files to 8bit RGBA palette. This doesn't apply to BDSup2Sub and BDSupEdit. You can also do this, using the -p switch.
  6. Use a program like BDSupEdit or BDSup2Sub to convert the BDN XML stuff to a BD-SUP file. The rest is left as an exercise for the reader.


Download

avs2bdnxml v2.08
Website


Changes

Version 2.08
  • Fix PNG filename references when used with timecode offsets.

Version 2.07
  • Fix two bugs in timecode parsing function
  • Move most inline assembly to yasm

Version 2.06
  • Add option to add an offset to output timecodes
  • Change return value when no events were detected to 0
  • Add option to allow writing of empty output files
  • Add option to enforce even Y coordinates (may help avoid problems with interlaced video in DVD related use cases)
  • Fix SSE2 with more recent GCC versions
  • Add option for stricter checks on buffer/palette limits for SUPs
  • Fix bug where LastEventOutTC could be one frame early
  • Add additional checks to commandline argument parsing
  • PNG files are now always placed in the same directory as the XML file

Version 2.05
  • Fix crash when using XML and SUP output

Version 2.04
  • Minor fixes
  • Code cleanup regarding linked lists
  • Add new minimal window finding code
  • Fix PGS output more, especially WDS handling
  • Fix old bug in RLE encoder

Version 2.03
  • Output some statistics about previous epoch in pgsparse in end packet
  • Fix unnecessary epoch splits due to bad buffer calculation and more.
  • Some small fixes

Version 2.02
  • It is now possible to use -o twice, with different output formats
  • Corrections to SUP timestamp calculation
  • PGS decode buffer should contain palettized image data, not RGBA. Buffer usage calculation fixed.

Version 2.01
  • Restrict number of composition objects within an epoch to 64

Version 2.00
  • Options --seek and --count were added, to allow for partial processing of input video
  • For debug purposes, a stand-alone SUP file parser was added in debug/
  • Experimental SUP output support

Version 1.13
  • By default, images are no longer split into to composition objects, if the result would look ugly. For example, descenders should no longer get put into their own image. Reverting back to the old behaviour is possible using the --ugly option.
  • Ensure minimum size of 8x8 for composition objects

Version 1.12
  • Fix error in example
  • Fix double free, which could result in broken images when image splitting and palletized output were enabled.

Version 1.11
  • Add option to not split lines, if the rest isn't a minimum of 3 (default) frames long
  • Images are now autocropped by default
  • Images are now converted to 8bit palette by default
  • Misc bugfixes that should've been fixed before

Version 1.10b
  • Splitting of images is now disabled by default

Version 1.10
  • Add option to split events longer than a given number of frames, to allow better seeking
  • Change image filename format to XXXXXXXX_X.png
  • Add option to optimize for Presentation Graphics buffer usage, by auto-cropping images, and splitting them into two separate ones to minimize surface area, when necessary (enabled by default)
  • Use getopts for commandline argument parsing
  • Add Makefile

Version 1.9
  • Correct calculation of timecodes. Integer only, now.
  • Remove support for drop timecodes. If anybody really needs them, and has a way to check calculated timecodes are correct, please tell me.

Version 1.8
  • Fix crash with certain frame sizes (unaligned buffer used with SSE2)

Version 1.7
  • Terminate using exit/return instead of abort (no more "crashes")

Version 1.6
  • Zero transparent pixels to guard against invisible color information (Slight slowdown, but more robustness)
  • Add SSE2 runtime detection
  • Correctly set DropFrame attribute

Version 1.5
  • Validate framerates
  • Make non-drop timecodes the default for 23.976, 29.97 and 59.94
  • Fix bad timecode calculation due to float math optimization
  • Add integer SSE2 optimization (but most time is spent in AviSynth)
  • Don't uselessly swap R and B channels

Last edited by ps auxw; 21st March 2015 at 17:44. Reason: Release of avs2bdnxml 2.08
ps auxw is offline   Reply With Quote
Old 27th July 2009, 05:30   #2  |  Link
OptimusX
Registered User
 
Join Date: Apr 2007
Posts: 20
I'd like to give this program a try, but I'm new to AVIsynth usage:

video=AviSource("video.avi")
MaskSub("subtitles.ext",video.width,video.height,video.framerate,video.framecount)

I'm trying to use an ASS file. What is the "avisource" referred to above? When using an ASS file, what is the video referenced to in this script?

How do I determine the "framecount" of the ASS file that I intend to use?
OptimusX is offline   Reply With Quote
Old 27th July 2009, 15:41   #3  |  Link
sneaker_ger
Registered User
 
Join Date: Dec 2002
Posts: 5,144
I too don't see what AviSource is supposed to do there but you may want to take a look at PunkGraphicStream which was published recently.
sneaker_ger is offline   Reply With Quote
Old 27th July 2009, 17:11   #4  |  Link
ps auxw
Registered User
 
Join Date: Apr 2009
Posts: 102
Quote:
Originally Posted by OptimusX View Post
I'd like to give this program a try, but I'm new to AVIsynth usage:

video=AviSource("video.avi")
MaskSub("subtitles.ext",video.width,video.height,video.framerate,video.framecount)

I'm trying to use an ASS file. What is the "avisource" referred to above? When using an ASS file, what is the video referenced to in this script?

How do I determine the "framecount" of the ASS file that I intend to use?
I am sorry if my description was a bit confusing. In this case "video.avi" is supposed to be the video the subtitles will be displayed on. I used it as a simple way of getting dimensions and length for the subtitle rendering. You can also use something like this:

Code:
MaskSub("subtitles.ass",1920,1080,23.976024,framecount)
Where framecount is the frame number of the underlying video after the last subtitle, or just the frame number of the last frame for the video the subtitles will be applied to. You can calculate it like this:
length in seconds * framerate

So if your last subtitle ends at 01:24:05.4 and the BluRay you will be mastering is 24000/1001 fps, your framecount will be: (60*60*1 + 60 * 24 + 5.4) * (24000 / 1001) = 120969 (round up)

Of course, you could also just use a high value for framecount that's sure to be more than enough (like 216000 for length below 2 hours). That'll just make conversion take a bit longer, but shouldn't hurt otherwise.

I hope things are a bit clearer now. If not, please ask.

Last edited by ps auxw; 27th July 2009 at 21:30.
ps auxw is offline   Reply With Quote
Old 30th July 2009, 01:19   #5  |  Link
OptimusX
Registered User
 
Join Date: Apr 2007
Posts: 20
Great explanation. I had a little problem because I didn't realize I had to manually add a plugin for AVISYNTH (vsfilter). I'm encoding some stuff now, so thank you for explaining so well!
OptimusX is offline   Reply With Quote
Old 7th August 2009, 07:02   #6  |  Link
hamletiii
Registered User
 
Join Date: Mar 2006
Posts: 116
I'm using aegisub to create the ass file, my video is NTSC 29.97fps nondrop, if I import the bdn-xml file straight into scenarist BD, the subtitle just gradually out of sync. So what process (framerate transform) do I need to apply, either on the original output or change the input framerate in command line?

The image output part is fine, quality is slightly better than tsmuxer (used fireworks to downgrade the pngs to 8 bit RGBA), but still has some white stuff uncleared on the outline (particularly visible in TotalMedia Theatre). So far the only tool that can generate perfect commercial quality Blu-ray subpicture is lemony pro, but that one is too hard to use. This tool seems promising, as long as if I can figure out how to get the timecodes fixed...
hamletiii is offline   Reply With Quote
Old 7th August 2009, 16:31   #7  |  Link
ps auxw
Registered User
 
Join Date: Apr 2009
Posts: 102
Quote:
Originally Posted by hamletiii View Post
I'm using aegisub to create the ass file, my video is NTSC 29.97fps nondrop, if I import the bdn-xml file straight into scenarist BD, the subtitle just gradually out of sync. So what process (framerate transform) do I need to apply, either on the original output or change the input framerate in command line?
Please try the following:
1) Call avs2bdnxml with FRAMERATE as 30. Calling it with 29.97 should produce drop timecodes.
2) If this is still no good, open the .xml file and set FrameRate="29.97" in the format tag.
Does this help with the desync?

Quote:
The image output part is fine, quality is slightly better than tsmuxer (used fireworks to downgrade the pngs to 8 bit RGBA), but still has some white stuff uncleared on the outline (particularly visible in TotalMedia Theatre). So far the only tool that can generate perfect commercial quality Blu-ray subpicture is lemony pro, but that one is too hard to use. This tool seems promising, as long as if I can figure out how to get the timecodes fixed...
The white pixels are most probably due to the 8bit conversion. Maybe a different program can give better results.
ps auxw is offline   Reply With Quote
Old 12th August 2009, 08:58   #8  |  Link
hamletiii
Registered User
 
Join Date: Mar 2006
Posts: 116
Yes, the 30fps corrected the drop problem, big thanks for the program and quick reply. But this option is not listed in the input:

FRAMERATE Either of: 23.976, 24, 25, 29.97, 50, 59.94

After getting the xml file, it has to be edited back to 29.97 since scenarist BD only takes 29.97 drop or non-drop.

And I assume for 23.976 non-drop source, I have to use 24 as input to avoid drop problem, right?

For the image quality, after I uncheck "Remove unused colors" in fireworks, the quality improves quite a bit. Now I have to look really close to see the white pixels, but they are there. So what's the reason you choose to output non 8bit RGBA pngs? It seems a little impractical to have true color pngs since most programs are designed to output BDMV structure.

Also I've tried the pinned PunkGraphicStream which has almost the same function as this one, except it only generates sup file ready to use for tsmuxer. That program uses libass which generates the sup file quite fast, while this program scans every frame of the video and output png one by one which takes quite some time. Have you considered to improve the efficiency of the program?

Last edited by hamletiii; 12th August 2009 at 09:03.
hamletiii is offline   Reply With Quote
Old 12th August 2009, 16:04   #9  |  Link
ps auxw
Registered User
 
Join Date: Apr 2009
Posts: 102
An updated version can be found in the first post.

Quote:
Originally Posted by hamletiii View Post
Yes, the 30fps corrected the drop problem, big thanks for the program and quick reply. But this option is not listed in the input:

FRAMERATE Either of: 23.976, 24, 25, 29.97, 50, 59.94
I have added 30 (non-drop) to the list.

Quote:
After getting the xml file, it has to be edited back to 29.97 since scenarist BD only takes 29.97 drop or non-drop.
avs2bdnxml should now write 29.97 to the XML file, even when 30 is given.

Quote:
And I assume for 23.976 non-drop source, I have to use 24 as input to avoid drop problem, right?
Yes, this is very likely.

Quote:
For the image quality, after I uncheck "Remove unused colors" in fireworks, the quality improves quite a bit. Now I have to look really close to see the white pixels, but they are there. So what's the reason you choose to output non 8bit RGBA pngs? It seems a little impractical to have true color pngs since most programs are designed to output BDMV structure.
The reasons for not outputting 8bit RGBA PNGs are simplicity and flexibility. I would have to add colour quantization to avs2bdnxml, to which there are quite a number of different approaches giving different quality. By outputting 32bit RGBA, different ways of quantization can be applied as the situation warrants. Also, both BDSupEdit and BDSup2Sub seem to include support for 32bit RGBA images, so at least conversion to SUP should be sufficiently painless these days. There should be a way to convert SUP back to BDNXML (with 8bit PNG) too.

Quote:
Also I've tried the pinned PunkGraphicStream which has almost the same function as this one, except it only generates sup file ready to use for tsmuxer. That program uses libass which generates the sup file quite fast, while this program scans every frame of the video and output png one by one which takes quite some time. Have you considered to improve the efficiency of the program?
At the moment, the frame comparison code is very unoptimized. I'll try to do something about this soonish. Of course, working directly with a subtitle file offers certain speed benefits (like only having to scan intervals with actual subtitles) that can not easily be surpassed with the approach avs2bdnxml uses, which, in turn, offers more flexibility for input formats.
ps auxw is offline   Reply With Quote
Old 15th August 2009, 14:29   #10  |  Link
hamletiii
Registered User
 
Join Date: Mar 2006
Posts: 116
Thanks for the quick update. Definitely looking forward to the optimized version.
And for downgrading from 32bit RGBA png, BDSup2Sub handles the job really well. I think it's either Fireworks or me screwed up in the process because the pngs from BDSup2Sub are really good, no more white pixels!
I've also tried time collision, and fade in/fade out, they import and compile fine in scenarist BD. The fading effect plays smoothly in Totalmedia Theatre.
hamletiii is offline   Reply With Quote
Old 15th August 2009, 23:18   #11  |  Link
sneaker_ger
Registered User
 
Join Date: Dec 2002
Posts: 5,144
I'm also having problems with subtitles being out of sync. I've attached a sample. Just compare the timing of the first and last line of the xml with the first and last line of the ass.
Attached Files
File Type: 7z async_subtitles.7z (112.8 KB, 152 views)

Last edited by sneaker_ger; 15th August 2009 at 23:25.
sneaker_ger is offline   Reply With Quote
Old 17th August 2009, 03:24   #12  |  Link
ps auxw
Registered User
 
Join Date: Apr 2009
Posts: 102
Quote:
Originally Posted by hamletiii View Post
Thanks for the quick update. Definitely looking forward to the optimized version.
And for downgrading from 32bit RGBA png, BDSup2Sub handles the job really well. I think it's either Fireworks or me screwed up in the process because the pngs from BDSup2Sub are really good, no more white pixels!
I've also tried time collision, and fade in/fade out, they import and compile fine in scenarist BD. The fading effect plays smoothly in Totalmedia Theatre.
I'll try to find some time to work on it in the next few days. Also, it's good to hear that BDSup2Sub solved the white pixel and the resulting subtitles play well.

Quote:
Originally Posted by sneaker_ger View Post
I'm also having problems with subtitles being out of sync. I've attached a sample. Just compare the timing of the first and last line of the xml with the first and last line of the ass.
Are you sure this is out of sync? Comparing the timestamps of the last/first non-comment lines, it looks fine to me. Please note that the last part in BDN XML timestamps (the 09 in 00:21:18:09) is given in frames, not hundredths of seconds.
ps auxw is offline   Reply With Quote
Old 17th August 2009, 15:14   #13  |  Link
sneaker_ger
Registered User
 
Join Date: Dec 2002
Posts: 5,144
Quote:
Originally Posted by ps auxw View Post
Are you sure this is out of sync? Comparing the timestamps of the last/first non-comment lines, it looks fine to me. Please note that the last part in BDN XML timestamps (the 09 in 00:21:18:09) is given in frames, not hundredths of seconds.
Ah, OK. I thought it was hundredths of seconds. Really strange way of mixing time and number of frames...

I got desync of the subtitles when playing the test Blu-Ray I created and thought this would be the cause. But since my PC is slow and I don't own a standalone Blu-Ray player yet it could just be my slow PC causing those problems. I'll try to investigate more.
sneaker_ger is offline   Reply With Quote
Old 17th August 2009, 19:43   #14  |  Link
Gokumon
Guest
 
Posts: n/a
Quote:
Originally Posted by sneaker_ger View Post
Ah, OK. I thought it was hundredths of seconds. Really strange way of mixing time and number of frames...
It's not that strange as other subtitle programs use this format as well to get frame accurate timing.
  Reply With Quote
Old 17th August 2009, 22:37   #15  |  Link
sneaker_ger
Registered User
 
Join Date: Dec 2002
Posts: 5,144
There are even more programs using that format?
I mean - why not go for frame numbers or time only - why mix? But whatever - not for me to decide, maybe there are valid reasons.
sneaker_ger is offline   Reply With Quote
Old 17th August 2009, 23:09   #16  |  Link
OptimusX
Registered User
 
Join Date: Apr 2007
Posts: 20
I was using a workflow of Aegisub -> DVD-Sup -> BD-Sup and would have a flicker problem with colliding subs.

Anyway, when I do Aegisub->avs2bdnxml->BD-Sup the "flicker problem" is gone! And the subs look really good! So far this is the only method that I know of when using many different sub styles that collide (as is common in anime subs).

Thank you!
OptimusX is offline   Reply With Quote
Old 17th August 2009, 23:30   #17  |  Link
ps auxw
Registered User
 
Join Date: Apr 2009
Posts: 102
Quote:
Originally Posted by sneaker_ger View Post
I got desync of the subtitles when playing the test Blu-Ray I created and thought this would be the cause. But since my PC is slow and I don't own a standalone Blu-Ray player yet it could just be my slow PC causing those problems. I'll try to investigate more.
Maybe your problem is drop/non-drop calculation difference, like it was for hamletiii? Please try calling avs2bdnxml with FRAMERATE as 24 instead of 23.976 and editing the resulting XML file to FrameRate="23.976", if necessary. Should this indeed turn out to be the problem again, I'll add it to the docs.
ps auxw is offline   Reply With Quote
Old 18th August 2009, 00:53   #18  |  Link
sneaker_ger
Registered User
 
Join Date: Dec 2002
Posts: 5,144
Thx, that seems to do the trick. But it's highly irritating having to set the wrong framerate to say the least. Can you explain to me why and in which cases this has to be done?

Another problem:
Code:
<Event Forced="False" InTC="00:16:30:13" OutTC="00:16:33:23">
<Graphic Width="1280" Height="720" X="0" Y="0">00023774.png</Graphic>
</Event>
<Event Forced="False" InTC="00:16:33:18" OutTC="00:16:35:04">
<Graphic Width="1280" Height="720" X="0" Y="0">00023851.png</Graphic>
It's an excerpt from the subtitle I created (the same as my attachment above) and as you can see the subtitles overlap. This leads to the first line being shown for a only a few ms for the start time of the second line.
sneaker_ger is offline   Reply With Quote
Old 18th August 2009, 04:32   #19  |  Link
OptimusX
Registered User
 
Join Date: Apr 2007
Posts: 20
I've experienced the timing issue as well. When working with a .ass file timed to 23.976 video, I was not able to get it to time properly until I called avs2bdnxml with "24" and manually edited the xml file to 23.976.
OptimusX is offline   Reply With Quote
Old 18th August 2009, 05:18   #20  |  Link
hamletiii
Registered User
 
Join Date: Mar 2006
Posts: 116
I found this thread explaining the drop/non-drop timecodes.
http://forum.doom9.org/showthread.php?t=73400

This is not the first subtitle software that requires a framerate conversion. DVDMaestro for instance requires 29.97 fps for input and 30 fps for output for any NTSC 29.97 non-drop source.

Maybe a second level prompt could be added if user choose 24fps as input:
Is the source 23.976 non-drop frame or 24p?
If 23.976 non-drop frame -> xml writes 23.976 in the field
If 24p -> xml writes 24 in the field.
hamletiii is offline   Reply With Quote
Reply

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +1. The time now is 13:04.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2018, vBulletin Solutions Inc.