SSA subtitle burn in
authorjstebbins <jstebbins.hb@gmail.com>
Tue, 28 Sep 2010 22:10:49 +0000 (22:10 +0000)
committerjstebbins <jstebbins.hb@gmail.com>
Tue, 28 Sep 2010 22:10:49 +0000 (22:10 +0000)
Anime fans rejoice! This patch adds SSA subtitle burn-in support with libass.
Therefore SSA subtitles should now be rendered in full quality, with the
appropriate embedded fonts and positioning information.
Thanks to davidfstr

git-svn-id: svn://svn.handbrake.fr/HandBrake/trunk@3557 b64f7644-9d1e-0410-96f1-a4d463321fa5

32 files changed:
contrib/fontconfig/A00-mingw-disableShared.patch [new file with mode: 0644]
contrib/fontconfig/module.defs [new file with mode: 0644]
contrib/fontconfig/module.rules [new file with mode: 0644]
contrib/freetype/module.defs [new file with mode: 0644]
contrib/freetype/module.rules [new file with mode: 0644]
contrib/libass/A00-configure.patch [new file with mode: 0644]
contrib/libass/module.defs [new file with mode: 0644]
contrib/libass/module.rules [new file with mode: 0644]
contrib/libxml2/module.defs [new file with mode: 0644]
contrib/libxml2/module.rules [new file with mode: 0644]
contrib/mp4v2/module.defs
gtk/src/Makefile.am
gtk/src/hb-backend.c
gtk/src/subtitlehandler.c
libhb/common.c
libhb/common.h
libhb/decssasub.c
libhb/decvobsub.c
libhb/encavcodec.c
libhb/hb.c
libhb/internal.h
libhb/module.defs
libhb/render.c
libhb/stream.c
libhb/sync.c
libhb/work.c
macosx/Controller.m
macosx/HBSubtitles.m
macosx/HandBrake.xcodeproj/project.pbxproj
make/include/main.defs
test/module.defs
test/test.c

diff --git a/contrib/fontconfig/A00-mingw-disableShared.patch b/contrib/fontconfig/A00-mingw-disableShared.patch
new file mode 100644 (file)
index 0000000..1fd7474
--- /dev/null
@@ -0,0 +1,73 @@
+--- fontconfig-2.8.0/configure 2009-11-18 15:49:41.000000000 -0800
++++ fontconfig-2.8.0/configure 2010-09-09 21:23:24.000000000 -0700
+@@ -825,6 +825,8 @@
+ ms_librarian
+ OS_WIN32_FALSE
+ OS_WIN32_TRUE
++OS_WIN32_ENABLE_SHARED_TRUE
++OS_WIN32_ENABLE_SHARED_FALSE
+ LTCXXCOMPILE
+ LTCOMPILE
+ DOLT_BASH
+@@ -11782,6 +11784,14 @@
+   OS_WIN32_FALSE=
+ fi
++ if test "$os_win32-$enable_shared" = "yes-yes"; then
++  OS_WIN32_ENABLE_SHARED_TRUE=
++  OS_WIN32_ENABLE_SHARED_FALSE='#'
++else
++  OS_WIN32_ENABLE_SHARED_TRUE='#'
++  OS_WIN32_ENABLE_SHARED_FALSE=
++fi
++
+ if test "$os_win32" = "yes"; then
+   # Extract the first word of "lib.exe", so it can be a program name with args.
+@@ -15155,6 +15165,13 @@
+ Usually this means the macro was only invoked conditionally." >&2;}
+    { (exit 1); exit 1; }; }
+ fi
++if test -z "${OS_WIN32_ENABLE_SHARED_TRUE}" && test -z "${OS_WIN32_ENABLE_SHARED_FALSE}"; then
++  { { echo "$as_me:$LINENO: error: conditional \"OS_WIN32_ENABLE_SHARED\" was never defined.
++Usually this means the macro was only invoked conditionally." >&5
++echo "$as_me: error: conditional \"OS_WIN32_ENABLE_SHARED\" was never defined.
++Usually this means the macro was only invoked conditionally." >&2;}
++   { (exit 1); exit 1; }; }
++fi
+ if test -z "${MS_LIB_AVAILABLE_TRUE}" && test -z "${MS_LIB_AVAILABLE_FALSE}"; then
+   { { $as_echo "$as_me:$LINENO: error: conditional \"MS_LIB_AVAILABLE\" was never defined.
+ Usually this means the macro was only invoked conditionally." >&5
+--- fontconfig-2.8.0/configure.in      2009-11-18 15:49:23.000000000 -0800
++++ fontconfig-2.8.0/configure.in      2010-09-09 21:11:37.000000000 -0700
+@@ -76,6 +76,7 @@
+     os_win32=no
+ esac
+ AM_CONDITIONAL(OS_WIN32, test "$os_win32" = "yes")
++AM_CONDITIONAL(OS_WIN32_ENABLE_SHARED, test "$os_win32-$enable_shared" = "yes-yes")
+ if test "$os_win32" = "yes"; then
+   AC_CHECK_PROG(ms_librarian, lib.exe, yes, no)
+--- fontconfig-2.8.0/src/Makefile.am   2010-09-09 21:12:43.000000000 -0700
++++ fontconfig-2.8.0/src/Makefile.am   2010-09-09 21:13:07.000000000 -0700
+@@ -30,7 +30,9 @@
+ # gcc import library install/uninstall
+ install-libtool-import-lib: 
++if OS_WIN32_ENABLE_SHARED
+       $(INSTALL) .libs/libfontconfig.dll.a $(DESTDIR)$(libdir)
++endif
+       $(INSTALL) fontconfig.def $(DESTDIR)$(libdir)/fontconfig.def
+ uninstall-libtool-import-lib:
+--- fontconfig-2.8.0/src/Makefile.in   2009-11-18 15:49:39.000000000 -0800
++++ fontconfig-2.8.0/src/Makefile.in   2010-09-09 21:14:38.000000000 -0700
+@@ -688,7 +688,7 @@
+ # gcc import library install/uninstall
+ @OS_WIN32_TRUE@install-libtool-import-lib: 
+-@OS_WIN32_TRUE@       $(INSTALL) .libs/libfontconfig.dll.a $(DESTDIR)$(libdir)
++@OS_WIN32_ENABLE_SHARED_TRUE@@OS_WIN32_TRUE@  $(INSTALL) .libs/libfontconfig.dll.a $(DESTDIR)$(libdir)
+ @OS_WIN32_TRUE@       $(INSTALL) fontconfig.def $(DESTDIR)$(libdir)/fontconfig.def
+ @OS_WIN32_TRUE@uninstall-libtool-import-lib:
diff --git a/contrib/fontconfig/module.defs b/contrib/fontconfig/module.defs
new file mode 100644 (file)
index 0000000..ce96c82
--- /dev/null
@@ -0,0 +1,71 @@
+__deps__ := FREETYPE LIBXML2
+$(eval $(call import.MODULE.defs,FONTCONFIG,fontconfig,$(__deps__)))
+$(eval $(call import.CONTRIB.defs,FONTCONFIG))
+
+FONTCONFIG.FETCH.url = http://download.m0k.org/handbrake/contrib/fontconfig-2.8.0.tar.gz
+FONTCONFIG.EXTRACT.tarbase = fontconfig-2.8.0
+
+#
+# Under MinGW:
+# 
+# - A 'i386-ming32-gcc' $(FONTCONFIG.GCC.gcc) command will be available,
+#   and the '-arch <arch>' argument should be omitted, as it will confuse this compiler.
+# 
+# - The $(FONTCONFIG.GCC.archs) variable is not set.
+#   Therefore statically guess the target arch to be i386.
+# 
+ifeq ($(BUILD.system),mingw)
+    FONTCONFIG.cc_archoption      = 
+    FONTCONFIG.config_archoption  = --with-arch=i386
+else ifeq ($(BUILD.system),linux)
+    FONTCONFIG.cc_archoption      = 
+else
+    FONTCONFIG.cc_archoption      = -arch $(FONTCONFIG.GCC.archs)
+    FONTCONFIG.config_archoption  = --with-arch=$(FONTCONFIG.GCC.archs)
+endif
+
+#
+# Support cross-compiling:
+# 
+# - Add '-arch <arch>' to CC argument to avoid the need to put a <host_triplet>-gcc
+#   trampoline script in the PATH, since fontconfig's configure looks for this when
+#   in cross-compile mode. If such a trampoline were used, it would just call "gcc -arch <arch> $@".
+# 
+# - In the case of MinGW (on i386), a 'i386-ming32-gcc' command will be available,
+#   and the '-arch <arch>' argument should be omitted, as it will confuse the compiler.
+# 
+# The following line overrides the original line in /make/include/contrib.defs,
+# but has the -arch argument added (and '$(1)' presubstituted for 'FONTCONFIG').
+# 
+FONTCONFIG.CONFIGURE.env.CC       = CC="$(FONTCONFIG.GCC.gcc) $(FONTCONFIG.cc_archoption)"
+
+#
+# Support cross-compiling:
+# - Remove '-arch <arch>' from *FLAGS variables, since fontconfig's configure script
+#   needs to be given the freedom to insert that flag as necessary, since there are
+#   some trampoline executables that need to be built in the native build architecture
+#   (without the -arch flag).
+# 
+# The following lines override the original lines in /make/include/contrib.defs,
+# but have '*archs' removed (and '$(1)' presubstituted for 'FONTCONFIG').
+# 
+FONTCONFIG.CONFIGURE.env.CFLAGS   = CFLAGS="$(call fn.ARGS,FONTCONFIG.GCC,*sysroot *minver ?extra)"
+FONTCONFIG.CONFIGURE.env.CXXFLAGS = CXXFLAGS="$(call fn.ARGS,FONTCONFIG.GCC,*sysroot *minver ?extra)"
+FONTCONFIG.CONFIGURE.env.CPPFLAGS = CPPFLAGS="$(call fn.ARGS,FONTCONFIG.GCC,*sysroot *minver ?extra)"
+FONTCONFIG.CONFIGURE.env.LDFLAGS  = LDFLAGS="$(call fn.ARGS,FONTCONFIG.GCC,*sysroot *minver)"
+
+# 
+# Force use of libxml2 instead of expat with --enable-libxml2.
+# 
+# Tell configure where to find our (cross-compiled) versions of freetype and libxml2.
+# 
+# Support cross-compiling:
+# - Add --with-arch argument since fontconfig's configure isn't smart enough
+#   to infer it from the --host argument
+# 
+FONTCONFIG.CONFIGURE.extra = \
+    --enable-libxml2 \
+    --with-freetype-config=$(call fn.ABSOLUTE,$(CONTRIB.build/)bin/freetype-config) \
+    LIBXML2_LIBS="-L$(call fn.ABSOLUTE,$(CONTRIB.build/))lib -lxml2" \
+    LIBXML2_CFLAGS="-I$(call fn.ABSOLUTE,$(CONTRIB.build/))include/libxml2" \
+    $(FONTCONFIG.config_archoption)
diff --git a/contrib/fontconfig/module.rules b/contrib/fontconfig/module.rules
new file mode 100644 (file)
index 0000000..72ebbd9
--- /dev/null
@@ -0,0 +1,2 @@
+$(eval $(call import.MODULE.rules,FONTCONFIG))
+$(eval $(call import.CONTRIB.rules,FONTCONFIG))
diff --git a/contrib/freetype/module.defs b/contrib/freetype/module.defs
new file mode 100644 (file)
index 0000000..85437ba
--- /dev/null
@@ -0,0 +1,5 @@
+$(eval $(call import.MODULE.defs,FREETYPE,freetype))
+$(eval $(call import.CONTRIB.defs,FREETYPE))
+
+FREETYPE.FETCH.url = http://download.m0k.org/handbrake/contrib/freetype-2.3.9.tar.gz
+FREETYPE.EXTRACT.tarbase = freetype-2.3.9
diff --git a/contrib/freetype/module.rules b/contrib/freetype/module.rules
new file mode 100644 (file)
index 0000000..d4ebbda
--- /dev/null
@@ -0,0 +1,2 @@
+$(eval $(call import.MODULE.rules,FREETYPE))
+$(eval $(call import.CONTRIB.rules,FREETYPE))
diff --git a/contrib/libass/A00-configure.patch b/contrib/libass/A00-configure.patch
new file mode 100644 (file)
index 0000000..d26e0fb
--- /dev/null
@@ -0,0 +1,84 @@
+--- libass-0.9.9/configure     2010-02-28 20:38:16.000000000 -0800
++++ libass-0.9.9/configure     2010-08-19 23:24:11.000000000 -0700
+@@ -15728,10 +15728,10 @@
+ { echo "$as_me:$LINENO: checking for FREETYPE" >&5
+ echo $ECHO_N "checking for FREETYPE... $ECHO_C" >&6; }
+-if test -n "$PKG_CONFIG"; then
+     if test -n "$FREETYPE_CFLAGS"; then
+         pkg_cv_FREETYPE_CFLAGS="$FREETYPE_CFLAGS"
+     else
++if test -n "$PKG_CONFIG"; then
+         if test -n "$PKG_CONFIG" && \
+     { (echo "$as_me:$LINENO: \$PKG_CONFIG --exists --print-errors \"freetype2 >= 9.10.3\"") >&5
+   ($PKG_CONFIG --exists --print-errors "freetype2 >= 9.10.3") 2>&5
+@@ -15742,14 +15742,14 @@
+ else
+   pkg_failed=yes
+ fi
+-    fi
+ else
+       pkg_failed=untried
+ fi
+-if test -n "$PKG_CONFIG"; then
++    fi
+     if test -n "$FREETYPE_LIBS"; then
+         pkg_cv_FREETYPE_LIBS="$FREETYPE_LIBS"
+     else
++if test -n "$PKG_CONFIG"; then
+         if test -n "$PKG_CONFIG" && \
+     { (echo "$as_me:$LINENO: \$PKG_CONFIG --exists --print-errors \"freetype2 >= 9.10.3\"") >&5
+   ($PKG_CONFIG --exists --print-errors "freetype2 >= 9.10.3") 2>&5
+@@ -15760,10 +15760,10 @@
+ else
+   pkg_failed=yes
+ fi
+-    fi
+ else
+       pkg_failed=untried
+ fi
++    fi
+@@ -15849,10 +15849,10 @@
+ { echo "$as_me:$LINENO: checking for FONTCONFIG" >&5
+ echo $ECHO_N "checking for FONTCONFIG... $ECHO_C" >&6; }
+-if test -n "$PKG_CONFIG"; then
+     if test -n "$FONTCONFIG_CFLAGS"; then
+         pkg_cv_FONTCONFIG_CFLAGS="$FONTCONFIG_CFLAGS"
+     else
++if test -n "$PKG_CONFIG"; then
+         if test -n "$PKG_CONFIG" && \
+     { (echo "$as_me:$LINENO: \$PKG_CONFIG --exists --print-errors \"fontconfig >= 2.4.2\"") >&5
+   ($PKG_CONFIG --exists --print-errors "fontconfig >= 2.4.2") 2>&5
+@@ -15863,14 +15863,14 @@
+ else
+   pkg_failed=yes
+ fi
+-    fi
+ else
+       pkg_failed=untried
+ fi
+-if test -n "$PKG_CONFIG"; then
++    fi
+     if test -n "$FONTCONFIG_LIBS"; then
+         pkg_cv_FONTCONFIG_LIBS="$FONTCONFIG_LIBS"
+     else
++if test -n "$PKG_CONFIG"; then
+         if test -n "$PKG_CONFIG" && \
+     { (echo "$as_me:$LINENO: \$PKG_CONFIG --exists --print-errors \"fontconfig >= 2.4.2\"") >&5
+   ($PKG_CONFIG --exists --print-errors "fontconfig >= 2.4.2") 2>&5
+@@ -15881,10 +15881,10 @@
+ else
+   pkg_failed=yes
+ fi
+-    fi
+ else
+       pkg_failed=untried
+ fi
++    fi
diff --git a/contrib/libass/module.defs b/contrib/libass/module.defs
new file mode 100644 (file)
index 0000000..e5528fd
--- /dev/null
@@ -0,0 +1,15 @@
+__deps__ := FONTCONFIG FREETYPE
+$(eval $(call import.MODULE.defs,LIBASS,libass,$(__deps__)))
+$(eval $(call import.CONTRIB.defs,LIBASS))
+
+LIBASS.FETCH.url = http://download.m0k.org/handbrake/contrib/libass-0.9.9.tar.bz2
+LIBASS.EXTRACT.tarbase = libass-0.9.9
+
+# Disable as many external dependencies as I can get away with
+# and tell configure where to find our version of freetype
+LIBASS.CONFIGURE.extra = \
+    --disable-png --disable-enca \
+    FREETYPE_LIBS="-L$(call fn.ABSOLUTE,$(CONTRIB.build/))lib -lfreetype" \
+    FREETYPE_CFLAGS="-I$(call fn.ABSOLUTE,$(CONTRIB.build/))include/freetype2" \
+    FONTCONFIG_LIBS="-L$(call fn.ABSOLUTE,$(CONTRIB.build/))lib -lfontconfig" \
+    FONTCONFIG_CFLAGS="-I$(call fn.ABSOLUTE,$(CONTRIB.build/))include"
diff --git a/contrib/libass/module.rules b/contrib/libass/module.rules
new file mode 100644 (file)
index 0000000..67a5ab6
--- /dev/null
@@ -0,0 +1,2 @@
+$(eval $(call import.MODULE.rules,LIBASS))
+$(eval $(call import.CONTRIB.rules,LIBASS))
diff --git a/contrib/libxml2/module.defs b/contrib/libxml2/module.defs
new file mode 100644 (file)
index 0000000..519c608
--- /dev/null
@@ -0,0 +1,10 @@
+$(eval $(call import.MODULE.defs,LIBXML2,libxml2))
+$(eval $(call import.CONTRIB.defs,LIBXML2))
+
+LIBXML2.FETCH.url = http://download.m0k.org/handbrake/contrib/libxml2-2.7.7.tar.gz
+LIBXML2.EXTRACT.tarbase = libxml2-2.7.7
+
+# The Python components do not build on MinGW due to the lack of a select() call
+# in the MinGW environment.
+LIBXML2.CONFIGURE.extra = \
+    --without-python
\ No newline at end of file
diff --git a/contrib/libxml2/module.rules b/contrib/libxml2/module.rules
new file mode 100644 (file)
index 0000000..0715628
--- /dev/null
@@ -0,0 +1,2 @@
+$(eval $(call import.MODULE.rules,LIBXML2))
+$(eval $(call import.CONTRIB.rules,LIBXML2))
index c27f3470e41e87d52004cd3ee885f68052909dea..a69151df547c20b314cfef7ff0e1bf2ebb5f3a4b 100644 (file)
@@ -10,8 +10,5 @@ MP4V2.CONFIGURE.env.CXXFLAGS = CXXFLAGS="$(call fn.ARGS,MP4V2.GCC,*archs *sysroo
 ## save some build-time by disabling utils
 MP4V2.CONFIGURE.extra += --disable-util
 
-## make sure gch is disabled; we get build errors on linux with gcc-4.3.x and -g3
-## relatively safe to enable for darwin as it is unlikely to have that bugged version
-ifneq (darwin,$(BUILD.system))
-    MP4V2.CONFIGURE.extra += --disable-gch
-endif
+# gch causes build errors with -g3 on many gcc toolchains
+MP4V2.CONFIGURE.extra += --disable-gch
index aec38fcfe8c0b5f480f38339e2a578e3b9d6f846..b901baf80fee6bb431df0558b7a4426782fb97c4 100644 (file)
@@ -5,13 +5,13 @@ HB_LIBS= \
        -lhb -la52 -lmkv -lavformat -lavcodec -lavutil -lavcore -ldca -ldvdnav -ldvdread \
        -lfaac -lmp3lame -lmpeg2 -lvorbis -lvorbisenc -logg -lsamplerate \
        -lx264 -lmp4v2 -lswscale -ltheora -lfaad -lz \
-       -lbz2 -liberty -lpthreadGC2 -lbluray
+       -lbz2 -liberty -lpthreadGC2 -lbluray -lass -lfontconfig -lfreetype
 else
 HB_LIBS= \
        -lhb -la52 -lmkv -lavformat -lavcodec -lavutil -lavcore -ldca -ldvdnav -ldvdread \
        -lfaac -lmp3lame -lmpeg2 -lvorbis -lvorbisenc -logg -lsamplerate \
        -lx264 -lmp4v2 -lswscale -ltheora -lfaad -lz \
-       -lbz2 -lpthread -lbluray
+       -lbz2 -lpthread -lbluray -lass -lfontconfig -lfreetype
 endif
 
 icons =        \
index 8ebdd1d179052f491dfe29ea7ab42228fb234154..3683c23e54f83e37f0596ca66da2bcc29d2b6633 100644 (file)
@@ -2187,20 +2187,9 @@ subtitle_track_opts_set(GtkBuilder *builder, const gchar *name, gint titleindex)
                for (ii = 0; ii < count; ii++)
                {
                        subtitle = (hb_subtitle_t *)hb_list_item(title->list_subtitle, ii);
-                       // Skip subtitles that must be burned if there is already
-                       // a burned subtitle in the list
-#if 0
-                       if (subtitle->source == VOBSUB)
-                       {
-                               options[ii] = g_strdup_printf("%d - %s", ii+1, subtitle->lang);
-                       }
-                       else
-#endif
-                       {
-                               options[ii] = g_strdup_printf("%d - %s (%s)", ii+1, 
-                                       subtitle->lang, 
-                                       ghb_subtitle_source_name(subtitle->source));
-                       }
+                       options[ii] = g_strdup_printf("%d - %s (%s)", ii+1, 
+                               subtitle->lang, 
+                               ghb_subtitle_source_name(subtitle->source));
                        subtitle_opts.map[ii+1].option = options[ii];
                        subtitle_opts.map[ii+1].shortOpt = index_str[ii];
                        subtitle_opts.map[ii+1].ivalue = ii;
@@ -2575,6 +2564,18 @@ ghb_find_cc_track(gint titleindex)
        return -2;
 }
 
+static gboolean
+canForce(int source)
+{
+       return (source == VOBSUB);
+}
+
+static gboolean
+canBurn(int source)
+{
+       return (source == VOBSUB || source == SSASUB);
+}
+
 gint
 ghb_find_subtitle_track(
        gint          titleindex, 
@@ -2627,7 +2628,8 @@ ghb_find_subtitle_track(
                                continue;
 
                        subtitle = (hb_subtitle_t*)hb_list_item( title->list_subtitle, ii );
-                       if ((!(burn || force) || (subtitle->source == VOBSUB)) &&
+                       if (((!force || (force && canForce(subtitle->source))) &&
+                                (!burn  || (burn  &&  canBurn(subtitle->source)))) &&
                                ((strcmp(lang, subtitle->iso639_2) == 0) ||
                                 (strcmp(lang, "und") == 0)))
                        {
@@ -4878,15 +4880,16 @@ add_job(hb_handle_t *h, GValue *js, gint unique_id, gint titleindex)
                        if (subt != NULL)
                        {
                                sub_config = subt->config;
-                               if (!burned && subt->format == PICTURESUB)
+                               if (!burned)
                                {
                                        sub_config.dest = PASSTHRUSUB;
                                }
-                               else if ( burned && subt->format == PICTURESUB )
+                               else if ( burned && canBurn(subt->source) )
                                {
                                        // Only allow one subtitle to be burned into the video
                                        if (one_burned)
                                                continue;
+                                       sub_config.dest = RENDERSUB;
                                        one_burned = TRUE;
                                }
                                sub_config.force = force;
index a7f06712adae94662b1a4e7d8a521276235b8b3c..63b2f20b4df9562da4b820b12a0b2d20c015c0e9 100644 (file)
@@ -44,6 +44,18 @@ mustBurn(signal_user_data_t *ud, GValue *settings)
        return FALSE;
 }
 
+static gboolean
+canBurn(int source)
+{
+       return (source == VOBSUB || source == SSASUB);
+}
+
+static gboolean
+canForce(int source)
+{
+       return (source == VOBSUB);
+}
+
 gboolean
 ghb_soft_in_subtitle_list(GValue *subtitle_list)
 {
@@ -519,7 +531,7 @@ subtitle_forced_toggled_cb(
        settings = ghb_array_get_nth(subtitle_list, row);
 
        source = ghb_settings_get_int(settings, "SubtitleSource");
-       if (source != VOBSUB)
+       if (!canForce(source))
                return;
 
        ghb_settings_set_boolean(settings, "SubtitleForced", active);
@@ -567,7 +579,7 @@ subtitle_burned_toggled_cb(
 
        settings = ghb_array_get_nth(subtitle_list, row);
        source = ghb_settings_get_int(settings, "SubtitleSource");
-       if (source != VOBSUB)
+       if (!canBurn(source))
                return;
        if (!active && mustBurn(ud, settings))
                return;
@@ -654,7 +666,8 @@ subtitle_list_refresh_selected(signal_user_data_t *ud)
        gint row;
        GValue *settings = NULL;
        const GValue *subtitle_list;
-       gboolean allow_burn_force = FALSE;
+       gboolean allow_force = FALSE;
+       gboolean allow_burn = FALSE;
        
        g_debug("subtitle_list_refresh_selected ()");
        treeview = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "subtitle_list"));
@@ -681,14 +694,17 @@ subtitle_list_refresh_selected(signal_user_data_t *ud)
 
                gint i_source;
                i_source = ghb_settings_get_int(settings, "SubtitleSource");
-               if (i_source != VOBSUB)
+               if (!canBurn(i_source))
                {
-                       // Force and burn only apply to VOBSUBS
-                       forced = FALSE;
                        burned = FALSE;
-                       ghb_settings_set_boolean(settings, "SubtitleForced", forced);
                        ghb_settings_set_boolean(settings, "SubtitleBurned", burned);
                }
+               if (!canForce(i_source))
+               {
+                       // Force only apply to VOBSUBS
+                       forced = FALSE;
+                       ghb_settings_set_boolean(settings, "SubtitleForced", forced);
+               }
 
                if (i_source == SRTSUB)
                {
@@ -730,9 +746,10 @@ subtitle_list_refresh_selected(signal_user_data_t *ud)
                        burned = ghb_settings_get_boolean(settings, "SubtitleBurned");
                }
 
-               if (i_source == VOBSUB)
-                       allow_burn_force = TRUE;
-
+               if (canBurn(i_source))
+                       allow_burn = TRUE;
+               if (canForce(i_source))
+                       allow_force = TRUE;
 
                gtk_list_store_set(GTK_LIST_STORE(store), &iter, 
                        // These are displayed in list
@@ -744,8 +761,8 @@ subtitle_list_refresh_selected(signal_user_data_t *ud)
                        // These are used to set combo box values when a list item is selected
                        5, s_track,
                        6, i_source,
-                       7, allow_burn_force,
-                       8, allow_burn_force,
+                       7, allow_force,
+                       8, allow_burn,
                        -1);
                g_free(track);
                g_free(source);
@@ -892,7 +909,8 @@ add_to_subtitle_list(
        gboolean forced, burned, def;
        gchar *s_track;
        gint i_source;
-       gboolean allow_burn_force = FALSE;
+       gboolean allow_force = FALSE;
+       gboolean allow_burn = FALSE;
        
        g_debug("add_to_subtitle_list ()");
        treeview = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "subtitle_list"));
@@ -908,8 +926,10 @@ add_to_subtitle_list(
        i_source = ghb_settings_get_int(settings, "SubtitleSource");
        source = ghb_subtitle_source_name(i_source);
 
-       if (i_source == VOBSUB)
-               allow_burn_force = TRUE;
+       if (canBurn(i_source))
+               allow_burn = TRUE;
+       if (canForce(i_source))
+               allow_force = TRUE;
 
        gtk_list_store_append(store, &iter);
        gtk_list_store_set(store, &iter, 
@@ -921,8 +941,8 @@ add_to_subtitle_list(
                // These are used to set combo box values when a list item is selected
                5, s_track,
                6, i_source,
-               7, allow_burn_force,
-               8, allow_burn_force,
+               7, allow_force,
+               8, allow_burn,
                9, FALSE,
                -1);
        gtk_tree_selection_select_iter(selection, &iter);
index f7b9ee384ab277f4e0e2ba972c87bc54833044a7..35417cb6c65805f1d955f3660aad4c06e47d1c9a 100644 (file)
@@ -730,6 +730,7 @@ hb_title_t * hb_title_init( char * path, int index )
     t->list_audio    = hb_list_init();
     t->list_chapter  = hb_list_init();
     t->list_subtitle = hb_list_init();
+    t->list_attachment = hb_list_init();
     strcat( t->path, path );
     // default to decoding mpeg2
     t->video_id      = 0xE0;
@@ -749,6 +750,7 @@ void hb_title_close( hb_title_t ** _t )
     hb_audio_t * audio;
     hb_chapter_t * chapter;
     hb_subtitle_t * subtitle;
+    hb_attachment_t * attachment;
 
     while( ( audio = hb_list_item( t->list_audio, 0 ) ) )
     {
@@ -767,9 +769,31 @@ void hb_title_close( hb_title_t ** _t )
     while( ( subtitle = hb_list_item( t->list_subtitle, 0 ) ) )
     {
         hb_list_rem( t->list_subtitle, subtitle );
+        if ( subtitle->extradata )
+        {
+            free( subtitle->extradata );
+            subtitle->extradata = NULL;
+        }
         free( subtitle );
     }
     hb_list_close( &t->list_subtitle );
+    
+    while( ( attachment = hb_list_item( t->list_attachment, 0 ) ) )
+    {
+        hb_list_rem( t->list_attachment, attachment );
+        if ( attachment->name )
+        {
+            free( attachment->name );
+            attachment->name = NULL;
+        }
+        if ( attachment->data )
+        {
+            free( attachment->data );
+            attachment->data = NULL;
+        }
+        free( attachment );
+    }
+    hb_list_close( &t->list_attachment );
 
     if( t->metadata )
     {
@@ -924,6 +948,11 @@ hb_subtitle_t *hb_subtitle_copy(const hb_subtitle_t *src)
     {
         subtitle = calloc(1, sizeof(*subtitle));
         memcpy(subtitle, src, sizeof(*subtitle));
+        if ( src->extradata )
+        {
+            subtitle->extradata = malloc( src->extradata_size );
+            memcpy( subtitle->extradata, src->extradata, src->extradata_size );
+        }
     }
     return subtitle;
 }
@@ -1021,6 +1050,32 @@ char * hb_strdup_printf( char * fmt, ... )
     }
 }
 
+/**********************************************************************
+ * hb_attachment_copy
+ **********************************************************************
+ *
+ *********************************************************************/
+hb_attachment_t *hb_attachment_copy(const hb_attachment_t *src)
+{
+    hb_attachment_t *attachment = NULL;
+
+    if( src )
+    {
+        attachment = calloc(1, sizeof(*attachment));
+        memcpy(attachment, src, sizeof(*attachment));
+        if ( src->name )
+        {
+            attachment->name = strdup( src->name );
+        }
+        if ( src->data )
+        {
+            attachment->data = malloc( src->size );
+            memcpy( attachment->data, src->data, src->size );
+        }
+    }
+    return attachment;
+}
+
 /**********************************************************************
  * hb_yuv2rgb
  **********************************************************************
@@ -1089,3 +1144,26 @@ int hb_rgb2yuv(int rgb)
     return (y << 16) | (Cb << 8) | Cr;
 }
 
+const char * hb_subsource_name( int source )
+{
+    switch (source)
+    {
+        case VOBSUB:
+            return "VOBSUB";
+        case SRTSUB:
+            return "SRT";
+        case CC608SUB:
+            return "CC";
+        case CC708SUB:
+            return "CC";
+        case UTF8SUB:
+            return "UTF-8";
+        case TX3GSUB:
+            return "TX3G";
+        case SSASUB:
+            return "SSA";
+        default:
+            return "Unknown";
+    }
+}
+
index b59cba5154aefb897306f5273da28a4044ab7ece..bba48350c83bf6f74f472c7638a8fd0e533dbcbd 100644 (file)
@@ -63,6 +63,7 @@ typedef struct hb_audio_s hb_audio_t;
 typedef struct hb_audio_config_s hb_audio_config_t;
 typedef struct hb_subtitle_s hb_subtitle_t;
 typedef struct hb_subtitle_config_s hb_subtitle_config_t;
+typedef struct hb_attachment_s hb_attachment_t;
 typedef struct hb_metadata_s hb_metadata_t;
 typedef struct hb_state_s hb_state_t;
 typedef union  hb_esconfig_u     hb_esconfig_t;
@@ -102,10 +103,12 @@ void hb_audio_config_init(hb_audio_config_t * audiocfg);
 int hb_audio_add(const hb_job_t * job, const hb_audio_config_t * audiocfg);
 hb_audio_config_t * hb_list_audio_config_item(hb_list_t * list, int i);
 
+hb_subtitle_t *hb_subtitle_copy(const hb_subtitle_t *src);
 int hb_subtitle_add(const hb_job_t * job, const hb_subtitle_config_t * subtitlecfg, int track);
 int hb_srt_add(const hb_job_t * job, const hb_subtitle_config_t * subtitlecfg, 
                const char *lang);
 
+hb_attachment_t *hb_attachment_copy(const hb_attachment_t *src);
 
 struct hb_rate_s
 {
@@ -194,8 +197,8 @@ struct hb_job_s
         int             itu_par;
         int             par_width;
         int             par_height;
-        int             dar_width;
-        int             dar_height;
+        int             dar_width;  // 0 if normal
+        int             dar_height; // 0 if normal
         int             keep_display_aspect;
     } anamorphic;
 
@@ -237,8 +240,7 @@ struct hb_job_s
     /* List of audio settings. */
     hb_list_t     * list_audio;
 
-    /* Subtitles
-     */
+    /* Subtitles */
     hb_list_t     * list_subtitle;
 
     /* Muxer settings
@@ -488,9 +490,8 @@ struct hb_chapter_s
  * > config.dest
  *     - whether to render the subtitle on the video track (RENDERSUB) or 
  *       to pass it through its own subtitle track in the output container (PASSTHRUSUB)
- *     - for legacy compatibility, all newly created VOBSUB tracks should default to RENDERSUB
- *     - since only VOBSUBs are renderable (as of 2010-04-25), all other newly created
- *       subtitle track types should default to PASSTHRUSUB
+ *     - all newly created non-VOBSUB tracks should default to PASSTHRUSUB
+ *     - all newly created VOBSUB tracks should default to RENDERSUB, for legacy compatibility
  * > lang
  *     - user-readable description of the subtitle track
  *     - may correspond to the language of the track (see the 'iso639_2' field)
@@ -516,6 +517,10 @@ struct hb_subtitle_s
     uint32_t    palette[16];
     int         width;
     int         height;
+    
+    // Codec private data for subtitles originating from FFMPEG sources
+    uint8_t *   extradata;
+    int         extradata_size;
 
     int hits;     /* How many hits/occurrences of this subtitle */
     int forced_hits; /* How many forced hits in this subtitle */
@@ -530,6 +535,19 @@ struct hb_subtitle_s
 #endif
 };
 
+/*
+ * An attachment.
+ * 
+ * These are usually used for attaching embedded fonts to movies containing SSA subtitles.
+ */
+struct hb_attachment_s
+{
+    enum attachtype { FONT_TTF_ATTACH } type;
+    char *  name;
+    char *  data;
+    int     size;
+};
+
 struct hb_metadata_s 
 {
     char  name[255];
@@ -593,6 +611,7 @@ struct hb_title_s
     hb_list_t * list_chapter;
     hb_list_t * list_audio;
     hb_list_t * list_subtitle;
+    hb_list_t * list_attachment;
 
     /* Job template for this title */
     hb_job_t  * job;
@@ -800,4 +819,6 @@ char * hb_strdup_printf( char * fmt, ... );
 int hb_yuv2rgb(int yuv);
 int hb_rgb2yuv(int rgb);
 
+const char * hb_subsource_name( int source );
+
 #endif
index 2b350dc476190a76d8bfd0f7583ec7b1eb9248f6..99e4259a0470be8dc1035bec950a4d2a1406d8e2 100644 (file)
@@ -4,13 +4,19 @@
    It may be used under the terms of the GNU General Public License. */
 
 /*
- * Converts SSA subtitles to UTF-8 subtitles with limited HTML-style markup (<b>, <i>, <u>).
+ * Converts SSA subtitles to either:
+ * (1) TEXTSUB format: UTF-8 subtitles with limited HTML-style markup (<b>, <i>, <u>), or
+ * (2) PICTURESUB format, using libass.
  * 
  * SSA format references:
  *   http://www.matroska.org/technical/specs/subtitles/ssa.html
  *   http://moodub.free.fr/video/ass-specs.doc
  *   vlc-1.0.4/modules/codec/subtitles/subsass.c:ParseSSAString
  * 
+ * libass references:
+ *   libass-0.9.9/ass.h
+ *   vlc-1.0.4/modules/codec/libass.c
+ * 
  * @author David Foster (davidfstr)
  */
 
 #include <stdio.h>
 #include "hb.h"
 
+#include <ass/ass.h>
+
+struct hb_work_private_s
+{
+    // If decoding to PICTURESUB format:
+    ASS_Library *ssa;
+    ASS_Renderer *renderer;
+    ASS_Track *ssaTrack;
+    int readOrder;
+};
+
 typedef enum {
     BOLD        = 0x01,
     ITALIC      = 0x02,
@@ -92,14 +109,17 @@ static void ssa_append_html_tags_for_style_change(
     #undef APPEND
 }
 
-static hb_buffer_t *ssa_decode_to_utf8_line( uint8_t *in_data, int in_size );
+static hb_buffer_t *ssa_decode_line_to_utf8( uint8_t *in_data, int in_size, int in_sequence );
+static hb_buffer_t *ssa_decode_line_to_picture( hb_work_object_t * w, uint8_t *in_data, int in_size, int in_sequence );
 
 /*
+ * Decodes a single SSA packet to one or more TEXTSUB or PICTURESUB subtitle packets.
+ * 
  * SSA packet format:
  * ( Dialogue: Marked,Start,End,Style,Name,MarginL,MarginR,MarginV,Effect,Text CR LF ) +
  *             1      2     3   4     5    6       7       8       9      10
  */
-static hb_buffer_t *ssa_decode_to_utf8( hb_buffer_t *in )
+static hb_buffer_t *ssa_decode_packet( hb_work_object_t * w, hb_buffer_t *in )
 {
     // Store NULL after the end of the buffer to make using string processing safe
     hb_buffer_realloc( in, in->size + 1 );
@@ -119,22 +139,31 @@ static hb_buffer_t *ssa_decode_to_utf8( hb_buffer_t *in )
             continue;
         
         // Decode an individual SSA line
-        hb_buffer_t *out = ssa_decode_to_utf8_line( (uint8_t*)curLine, strlen( curLine ) );
-        
-        // We shouldn't be storing the extra NULL character,
-        // but the MP4 muxer expects this, unfortunately.
-        if ( out->size > 0 && out->data[out->size - 1] != '\0' ) {
-            // NOTE: out->size remains unchanged
-            hb_buffer_realloc( out, out->size + 1 );
-            out->data[out->size] = '\0';
-        }
-        
-        // If the input packet was non-empty, do not pass through
-        // an empty output packet (even if the subtitle was empty),
-        // as this would be interpreted as an end-of-stream
-        if ( in->size > 0 && out->size == 0 ) {
-            hb_buffer_close(&out);
-            continue;
+        hb_buffer_t *out;
+        if ( w->subtitle->config.dest == PASSTHRUSUB ) {
+            out = ssa_decode_line_to_utf8( (uint8_t *) curLine, strlen( curLine ), in->sequence );
+            if ( out == NULL )
+                continue;
+            
+            // We shouldn't be storing the extra NULL character,
+            // but the MP4 muxer expects this, unfortunately.
+            if ( out->size > 0 && out->data[out->size - 1] != '\0' ) {
+                // NOTE: out->size remains unchanged
+                hb_buffer_realloc( out, out->size + 1 );
+                out->data[out->size] = '\0';
+            }
+            
+            // If the input packet was non-empty, do not pass through
+            // an empty output packet (even if the subtitle was empty),
+            // as this would be interpreted as an end-of-stream
+            if ( in->size > 0 && out->size == 0 ) {
+                hb_buffer_close(&out);
+                continue;
+            }
+        } else if ( w->subtitle->config.dest == RENDERSUB ) {
+            out = ssa_decode_line_to_picture( w, (uint8_t *) curLine, strlen( curLine ), in->sequence );
+            if ( out == NULL )
+                continue;
         }
         
         // Append 'out' to 'out_list'
@@ -146,50 +175,68 @@ static hb_buffer_t *ssa_decode_to_utf8( hb_buffer_t *in )
 }
 
 /*
- * SSA line format:
- *   Dialogue: Marked,Start,End,Style,Name,MarginL,MarginR,MarginV,Effect,Text '\0'
- *             1      2     3   4     5    6       7       8       9      10
+ * Parses the start and stop time from the specified SSA packet.
+ * 
+ * Returns true if parsing failed; false otherwise.
  */
-static hb_buffer_t *ssa_decode_to_utf8_line( uint8_t *in_data, int in_size )
+static int parse_timing_from_ssa_packet( char *in_data, int64_t *in_start, int64_t *in_stop )
 {
-    uint8_t *pos = in_data;
-    uint8_t *end = in_data + in_size;
-    
     /*
      * Parse Start and End fields for timing information
      */
     int start_hr, start_min, start_sec, start_centi;
     int   end_hr,   end_min,   end_sec,   end_centi;
-    int numPartsRead = sscanf( (char *) in_data, "%*128[^,],"
+    int numPartsRead = sscanf( (char *) in_data, "Dialogue: %*128[^,],"
         "%d:%d:%d.%d,"  // Start
         "%d:%d:%d.%d,", // End
         &start_hr, &start_min, &start_sec, &start_centi,
           &end_hr,   &end_min,   &end_sec,   &end_centi );
     if ( numPartsRead != 8 )
-        goto fail;
+        return 1;
     
-    int64_t in_start = SSA_2_HB_TIME(start_hr, start_min, start_sec, start_centi);
-    int64_t in_stop  = SSA_2_HB_TIME(  end_hr,   end_min,   end_sec,   end_centi);
+    *in_start = SSA_2_HB_TIME(start_hr, start_min, start_sec, start_centi);
+    *in_stop  = SSA_2_HB_TIME(  end_hr,   end_min,   end_sec,   end_centi);
     
-    /*
-     * Advance 'pos' to the beginning of the Text field
-     */
+    return 0;
+}
+
+static uint8_t *find_field( uint8_t *pos, uint8_t *end, int fieldNum )
+{
     int curFieldID = 1;
     while (pos < end)
     {
         if ( *pos++ == ',' )
         {
             curFieldID++;
-            if ( curFieldID == 10 ) // Text
-                break;
+            if ( curFieldID == fieldNum )
+                return pos;
         }
     }
-    if ( curFieldID != 10 )
+    return NULL;
+}
+
+/*
+ * SSA line format:
+ *   Dialogue: Marked,Start,End,Style,Name,MarginL,MarginR,MarginV,Effect,Text '\0'
+ *             1      2     3   4     5    6       7       8       9      10
+ */
+static hb_buffer_t *ssa_decode_line_to_utf8( uint8_t *in_data, int in_size, int in_sequence )
+{
+    uint8_t *pos = in_data;
+    uint8_t *end = in_data + in_size;
+    
+    // Parse values for in->start and in->stop
+    int64_t in_start, in_stop;
+    if ( parse_timing_from_ssa_packet( (char *) in_data, &in_start, &in_stop ) )
+        goto fail;
+    
+    uint8_t *textFieldPos = find_field( pos, end, 10 );
+    if ( textFieldPos == NULL )
         goto fail;
-    uint8_t *textFieldPos = pos;
     
     // Count the number of style overrides in the Text field
     int numStyleOverrides = 0;
+    pos = textFieldPos;
     while ( pos < end )
     {
         if (*pos++ == '{')
@@ -207,7 +254,7 @@ static hb_buffer_t *ssa_decode_to_utf8_line( uint8_t *in_data, int in_size )
      * The Text field contains plain text marked up with:
      * (1) '\n' -> space
      * (2) '\N' -> newline
-     * (3) curly-brace control codes like '{\k44}' -> empty (strip them)
+     * (3) curly-brace control codes like '{\k44}' -> HTML tags / strip
      * 
      * Perform the above conversions and copy it to the output packet
      */
@@ -253,6 +300,7 @@ static hb_buffer_t *ssa_decode_to_utf8_line( uint8_t *in_data, int in_size )
     // Copy metadata from the input packet to the output packet
     out->start = in_start;
     out->stop = in_stop;
+    out->sequence = in_sequence;
     
     return out;
     
@@ -261,8 +309,252 @@ fail:
     return NULL;
 }
 
+/*
+ * SSA line format:
+ *   Dialogue: Marked,Start,End,Style,Name,MarginL,MarginR,MarginV,Effect,Text '\0'
+ *             1      2     3   4     5    6       7       8       9      10
+ * 
+ * MKV-SSA packet format:
+ *   ReadOrder,Marked,          Style,Name,MarginL,MarginR,MarginV,Effect,Text '\0'
+ *   1         2                3     4    5       6       7       8      9
+ */
+static hb_buffer_t *ssa_decode_line_to_picture( hb_work_object_t * w, uint8_t *in_data, int in_size, int in_sequence )
+{
+    hb_work_private_t * pv = w->private_data;
+    
+    // Parse values for in->start and in->stop
+    int64_t in_start, in_stop;
+    if ( parse_timing_from_ssa_packet( (char *) in_data, &in_start, &in_stop ) )
+        goto fail;
+    
+    // Convert the SSA packet to MKV-SSA format, which is what libass expects
+    char *mkvIn;
+    int mkvInSize;
+    {
+        char *layerField = malloc( in_size );
+        int numPartsRead = sscanf( (char *) in_data, "Dialogue: %128[^,],", layerField );
+        if ( numPartsRead != 1 )
+            goto fail;
+        
+        char *styleToTextFields = (char *) find_field( in_data, in_data + in_size, 4 );
+        if ( styleToTextFields == NULL ) {
+            free( layerField );
+            goto fail;
+        }
+        
+        mkvIn = malloc( in_size + 1 );
+        mkvIn[0] = '\0';
+        sprintf(mkvIn, "%d", pv->readOrder++);    // ReadOrder: make this up
+        strcat( mkvIn, "," );
+        strcat( mkvIn, layerField );
+        strcat( mkvIn, "," );
+        strcat( mkvIn, (char *) styleToTextFields );
+        
+        mkvInSize = strlen(mkvIn);
+        
+        free( layerField );
+    }
+    
+    // Parse MKV-SSA packet
+    ass_process_chunk( pv->ssaTrack, mkvIn, mkvInSize, in_start / 90, (in_stop - in_start) / 90 );
+    
+    free( mkvIn );
+    
+    // TODO: To support things like karaoke, it won't be sufficient to only generate
+    //       new subtitle pictures when there are subtitle packets. Rather, pictures will
+    //       need to be generated potentially continuously. 
+    //       
+    //       Until "karaoke support" is implemented, make an educated guess about the
+    //       timepoint within the subtitle that should be rendered. I guess the midpoint.
+    int64_t renderTime = ( in_start + in_stop ) / 2; 
+    
+    int changed;
+    ASS_Image *frameList = ass_render_frame( pv->renderer, pv->ssaTrack, renderTime / 90, &changed );
+    if ( !changed && !frameList )
+        return NULL;
+    
+    int numFrames = 0;
+    ASS_Image *curFrame;
+    for (curFrame = frameList; curFrame; curFrame = curFrame->next)
+        numFrames++;
+    
+    hb_buffer_t *outSubpictureList = NULL;
+    hb_buffer_t **outSubpictureListTailPtr = &outSubpictureList;
+    
+    // Generate a PICTURESUB packet from the frames
+    ASS_Image *frame;
+    for (frame = frameList; frame; frame = frame->next) {
+        // Allocate pixmap where drawing will be done
+        uint8_t *rgba = calloc(frame->w * frame->h * 4, 1);
+        
+        unsigned r = (frame->color >> 24) & 0xff;
+        unsigned g = (frame->color >> 16) & 0xff;
+        unsigned b = (frame->color >>  8) & 0xff;
+        unsigned a = (frame->color      ) & 0xff;
+        
+        int x, y;
+        for (y = 0; y < frame->h; y++) {
+            for (x = 0; x < frame->w; x++) {
+                unsigned srcAlphaPrenormalized = frame->bitmap[y*frame->stride + x];
+                unsigned srcAlpha = (255 - a) * srcAlphaPrenormalized / 255;
+                
+                uint8_t *dst = &rgba[(y*frame->w + x) * 4];
+                unsigned oldDstAlpha = dst[3];
+                
+                if (oldDstAlpha == 0) {
+                    // Optimized version
+                    dst[0] = r;
+                    dst[1] = g;
+                    dst[2] = b;
+                    dst[3] = srcAlpha;
+                } else {
+                    dst[3] = 255 - ( 255 - dst[3] ) * ( 255 - srcAlpha ) / 255;
+                    if (dst[3] != 0) {
+                        dst[0] = ( dst[0] * oldDstAlpha * (255-srcAlpha) / 255 + r * srcAlpha ) / dst[3];
+                        dst[1] = ( dst[1] * oldDstAlpha * (255-srcAlpha) / 255 + g * srcAlpha ) / dst[3];
+                        dst[2] = ( dst[2] * oldDstAlpha * (255-srcAlpha) / 255 + b * srcAlpha ) / dst[3];
+                    }
+                }
+            }
+        }
+        
+        // Generate output subpicture (in PICTURESUB format)
+        hb_buffer_t *out = hb_buffer_init(frame->w * frame->h * 4);
+        out->x = frame->dst_x;
+        out->y = frame->dst_y;
+        out->width = frame->w;
+        out->height = frame->h;
+        
+        int i;
+        int numPixels = frame->w * frame->h;
+        for (i = 0; i < numPixels; i++) {
+            uint8_t *srcRgba = &rgba[i * 4];
+            
+            uint8_t *dstY = &out->data[(numPixels * 0) + i];
+            uint8_t *dstA = &out->data[(numPixels * 1) + i];
+            uint8_t *dstU = &out->data[(numPixels * 2) + i];
+            uint8_t *dstV = &out->data[(numPixels * 3) + i];
+            
+            int srcYuv = hb_rgb2yuv((srcRgba[0] << 16) | (srcRgba[1] << 8) | (srcRgba[2] << 0));
+            int srcA = srcRgba[3];
+            
+            *dstY = (srcYuv >> 16) & 0xff;
+            *dstU = (srcYuv >> 8 ) & 0xff;
+            *dstV = (srcYuv >> 0 ) & 0xff;
+            *dstA = srcA / 16;  // HB's max alpha value is 16
+        }
+        
+        free(rgba);
+        
+        *outSubpictureListTailPtr = out;
+        outSubpictureListTailPtr = &out->next_subpicture;
+    }
+    
+    // NOTE: The subpicture list is actually considered a single packet by most other code
+    hb_buffer_t *out = outSubpictureList;
+    
+    // Copy metadata from the input packet to the output packet
+    out->start = in_start;
+    out->stop = in_stop;
+    out->sequence = in_sequence;
+
+    return out;
+    
+fail:
+    hb_log( "decssasub: malformed SSA subtitle packet: %.*s\n", in_size, in_data );
+    return NULL;
+}
+
+static void ssa_log(int level, const char *fmt, va_list args, void *data)
+{
+    if ( level < 5 )      // same as default verbosity when no callback is set
+    {
+        char *msg;
+        if ( vasprintf( &msg, fmt, args ) < 0 )
+        {
+            hb_log( "decssasub: could not report libass message\n" );
+            return;
+        }
+        hb_log( "[ass] %s", msg );  // no need for extra '\n' because libass sends it
+        
+        free( msg );
+    }
+}
+
 static int decssaInit( hb_work_object_t * w, hb_job_t * job )
 {
+    hb_work_private_t * pv;
+
+    pv              = calloc( 1, sizeof( hb_work_private_t ) );
+    w->private_data = pv;
+    
+    if ( w->subtitle->config.dest == RENDERSUB ) {
+        pv->ssa = ass_library_init();
+        if ( !pv->ssa ) {
+            hb_log( "decssasub: libass initialization failed\n" );
+            return 1;
+        }
+        
+        // Redirect libass output to hb_log
+        ass_set_message_cb( pv->ssa, ssa_log, NULL );
+        
+        // Load embedded fonts
+        hb_list_t * list_attachment = job->title->list_attachment;
+        int i;
+        for ( i = 0; i < hb_list_count(list_attachment); i++ )
+        {
+            hb_attachment_t * attachment = hb_list_item( list_attachment, i );
+            
+            if ( attachment->type == FONT_TTF_ATTACH )
+            {
+                ass_add_font(
+                    pv->ssa,
+                    attachment->name,
+                    attachment->data,
+                    attachment->size );
+            }
+        }
+        
+        ass_set_extract_fonts( pv->ssa, 1 );
+        ass_set_style_overrides( pv->ssa, NULL );
+        
+        pv->renderer = ass_renderer_init( pv->ssa );
+        if ( !pv->renderer ) {
+            hb_log( "decssasub: renderer initialization failed\n" );
+            return 1;
+        }
+        
+        ass_set_use_margins( pv->renderer, 0 );
+        ass_set_hinting( pv->renderer, ASS_HINTING_LIGHT );     // VLC 1.0.4 uses this
+        ass_set_font_scale( pv->renderer, 1.0 );
+        ass_set_line_spacing( pv->renderer, 1.0 );
+        
+        // Setup default font family
+        // 
+        // SSA v4.00 requires that "Arial" be the default font
+        const char *font = NULL;
+        const char *family = "Arial";
+        // NOTE: This can sometimes block for several *seconds*.
+        //       It seems that process_fontdata() for some embedded fonts is slow.
+        ass_set_fonts( pv->renderer, font, family, /*haveFontConfig=*/1, NULL, 1 );
+        
+        // Setup track state
+        pv->ssaTrack = ass_new_track( pv->ssa );
+        if ( !pv->ssaTrack ) {
+            hb_log( "decssasub: ssa track initialization failed\n" );
+            return 1;
+        }
+        
+        // NOTE: The codec extradata is expected to be in MKV format
+        ass_process_codec_private( pv->ssaTrack,
+            (char *) w->subtitle->extradata, w->subtitle->extradata_size );
+        
+        int originalWidth = job->title->width;
+        int originalHeight = job->title->height;
+        ass_set_frame_size( pv->renderer, originalWidth, originalHeight);
+        ass_set_aspect_ratio( pv->renderer, /*dar=*/1.0, /*sar=*/1.0 );
+    }
+    
     return 0;
 }
 
@@ -273,7 +565,7 @@ static int decssaWork( hb_work_object_t * w, hb_buffer_t ** buf_in,
     hb_buffer_t * out_list = NULL;
     
     if ( in->size > 0 ) {
-        out_list = ssa_decode_to_utf8(in);
+        out_list = ssa_decode_packet(w, in);
     } else {
         out_list = hb_buffer_init( 0 );
     }
@@ -288,7 +580,16 @@ static int decssaWork( hb_work_object_t * w, hb_buffer_t ** buf_in,
 
 static void decssaClose( hb_work_object_t * w )
 {
-    // nothing
+    hb_work_private_t * pv = w->private_data;
+
+    if ( pv->ssaTrack )
+        ass_free_track( pv->ssaTrack );
+    if ( pv->renderer )
+        ass_renderer_done( pv->renderer );
+    if ( pv->ssa )
+        ass_library_done( pv->ssa );
+    
+    free( w->private_data );
 }
 
 hb_work_object_t hb_decssasub =
index 3b5177ca381fc08a953fd4eabaeab91cf82f71fa..fc4a9e24f238cd9205cce7b4671d46d9887b9d0f 100644 (file)
  *
  * Output format of this decoder is PICTURESUB, which is:
  *   struct PictureSubPacket {
- *       uint8_t lum[pixelCount];
- *       uint8_t alpha[pixelCount];
- *       uint8_t chromaU[pixelCount];
- *       uint8_t chromaV[pixelCount];
+ *       uint8_t lum[pixelCount];       // Y
+ *       uint8_t alpha[pixelCount];     // alpha (max = 16)
+ *       uint8_t chromaU[pixelCount];   // Cb
+ *       uint8_t chromaV[pixelCount];   // Cr
  *   }
  */
 
index 22eb286d524158c8e300c04d8f5143f623e7bfaa..5ae5a392944092be41d5ee23f838b239b0be0fbc 100644 (file)
@@ -235,13 +235,22 @@ int encavcodecWork( hb_work_object_t * w, hb_buffer_t ** buf_in,
     // doesn't do the trick.  It must be set in the AVFrame.
     frame->quality = pv->context->global_quality;
 
-    /* Should be way too large */
-    buf = hb_video_buffer_init( job->width, job->height );
-    buf->size = avcodec_encode_video( pv->context, buf->data, buf->alloc,
-                                      frame );
-    buf->start = in->start;
-    buf->stop  = in->stop;
-    buf->frametype   = pv->context->coded_frame->key_frame ? HB_FRAME_KEY : HB_FRAME_REF;
+    if ( pv->context->codec )
+    {
+        /* Should be way too large */
+        buf = hb_video_buffer_init( job->width, job->height );
+        buf->size = avcodec_encode_video( pv->context, buf->data, buf->alloc,
+                                          frame );
+        buf->start = in->start;
+        buf->stop  = in->stop;
+        buf->frametype   = pv->context->coded_frame->key_frame ? HB_FRAME_KEY : HB_FRAME_REF;
+    }
+    else
+    {
+        buf = NULL;
+        
+        hb_error( "encavcodec: codec context has uninitialized codec; skipping frame" );
+    }
 
     av_free( frame );
 
index 11b80357e26c9ff777c6fabdc818c2b150b83c3f..36fcd75c93be67cf52ea2441a94d65728f62e358 100644 (file)
@@ -1225,6 +1225,7 @@ void hb_add( hb_handle_t * h, hb_job_t * job )
     hb_chapter_t  * chapter,  * chapter_copy;
     hb_audio_t    * audio;
     hb_subtitle_t * subtitle, * subtitle_copy;
+    hb_attachment_t * attachment;
     int             i;
     char            audio_lang[4];
 
@@ -1272,7 +1273,6 @@ void hb_add( hb_handle_t * h, hb_job_t * job )
 
     /* Copy the audio track(s) we want */
     title_copy->list_audio = hb_list_init();
-
     for( i = 0; i < hb_list_count(job->list_audio); i++ )
     {
         if( ( audio = hb_list_item( job->list_audio, i ) ) )
@@ -1281,7 +1281,18 @@ void hb_add( hb_handle_t * h, hb_job_t * job )
         }
     }
 
+    /* Initialize subtitle list - filled out further below */
     title_copy->list_subtitle = hb_list_init();
+    
+    /* Copy all the attachments */
+    title_copy->list_attachment = hb_list_init();
+    for( i = 0; i < hb_list_count(title->list_attachment); i++ )
+    {
+        if( ( attachment = hb_list_item( title->list_attachment, i ) ) )
+        {
+            hb_list_add( title_copy->list_attachment, hb_attachment_copy(attachment) );
+        }
+    }
 
     /*
      * The following code is confusing, there are two ways in which
index fe1cdca260793454255935907b0958e57d139330..30bf022d5c6c562be490fbb7e6b851fd3a74f199 100644 (file)
@@ -85,15 +85,16 @@ struct hb_buffer_s
     /* Holds the output PTS from x264, for use by b-frame offsets in muxmp4.c */
     int64_t     renderOffset;
 
-    // VOB subtitle packets:
+    // PICTURESUB subtitle packets:
     //   Location and size of the subpicture.
     int           x;
     int           y;
     int           width;
     int           height;
+    hb_buffer_t * next_subpicture;
 
     // Video packets (after processing by the hb_sync_video work-object):
-    //   A (copy of a) VOB subtitle packet that needs to be burned into this video packet by the hb_render work-object.
+    //   A (copy of a) PICTURESUB subtitle packet that needs to be burned into this video packet by the hb_render work-object.
     //   Subtitles that are simply passed thru are NOT attached to the associated video packets.
     hb_buffer_t * sub;
 
index c6fb9dceb1c29776d2e524b77e608350b4d364f4..4759a921af6081fc21ecdb167c6d2b58d4be2605 100644 (file)
@@ -1,5 +1,5 @@
-__deps__ := A52DEC BZIP2 FAAC FAAD2 FFMPEG LAME LIBDCA \
-    LIBDVDREAD LIBDVDNAV LIBICONV LIBMKV LIBOGG LIBSAMPLERATE LIBTHEORA LIBVORBIS \
+__deps__ := A52DEC BZIP2 FAAC FAAD2 FFMPEG FONTCONFIG FREETYPE LAME LIBASS LIBDCA \
+    LIBDVDREAD LIBDVDNAV LIBICONV LIBMKV LIBOGG LIBSAMPLERATE LIBTHEORA LIBVORBIS LIBXML2 \
     MP4V2 MPEG2DEC PTHREADW32 X264 ZLIB LIBBLURAY
 
 $(eval $(call import.MODULE.defs,LIBHB,libhb,$(__deps__)))
@@ -89,8 +89,8 @@ LIBHB.dll = $(LIBHB.build/)hb.dll
 LIBHB.lib = $(LIBHB.build/)hb.lib
 
 LIBHB.dll.libs = $(foreach n, \
-        a52 avcore avcodec avformat avutil dca dvdnav dvdread faac faad mkv mpeg2 mp3lame mp4v2 \
-        ogg samplerate swscale theora vorbis vorbisenc x264 bluray, \
+        a52 ass avcore avcodec avformat avutil dca dvdnav dvdread faac faad fontconfig freetype mkv mpeg2 mp3lame mp4v2 \
+        ogg samplerate swscale theora vorbis vorbisenc x264 xml2 bluray, \
         $(CONTRIB.build/)lib/lib$(n).a )
 
 ifneq ($(HAS.iconv),1)
index 6888a1e0a75bc5b7afb6b6b1e82d7cd4778fdbcc..98bc7fea3cabc72c49eb366d36e9963c226dc2d0 100644 (file)
@@ -472,8 +472,14 @@ int renderWork( hb_work_object_t * w, hb_buffer_t ** buf_in,
                 pv->dropped_frames++;
 
                 /* Pop the frame's subtitle and dispose of it. */
-                hb_buffer_t * subtitles = hb_fifo_get( pv->subtitle_queue );
-                hb_buffer_close( &subtitles );
+                hb_buffer_t * subpicture_list = hb_fifo_get( pv->subtitle_queue );
+                hb_buffer_t * subpicture;
+                hb_buffer_t * subpicture_next;
+                for ( subpicture = subpicture_list; subpicture; subpicture = subpicture_next )
+                {
+                    subpicture_next = subpicture->next_subpicture;
+                    hb_buffer_close( &subpicture );
+                }
                 buf_tmp_in = NULL;
                 break;
             }
@@ -500,10 +506,13 @@ int renderWork( hb_work_object_t * w, hb_buffer_t ** buf_in,
     /* Apply subtitles */
     if( buf_tmp_in )
     {
-        hb_buffer_t * subtitles = hb_fifo_get( pv->subtitle_queue );
-        if( subtitles )
+        hb_buffer_t * subpicture_list = hb_fifo_get( pv->subtitle_queue );
+        hb_buffer_t * subpicture;
+        hb_buffer_t * subpicture_next;
+        for ( subpicture = subpicture_list; subpicture; subpicture = subpicture_next )
         {
-            ApplySub( job, buf_tmp_in, &subtitles );
+            subpicture_next = subpicture->next_subpicture;
+            ApplySub( job, buf_tmp_in, &subpicture );
         }
     }
 
index 58b2506f06d79a080ce650e14653661a2f49857f..85a891c7b6cf676ba9483328d7fe228a2295d65c 100644 (file)
@@ -3181,9 +3181,55 @@ static void add_ffmpeg_subtitle( hb_title_t *title, hb_stream_t *stream, int id
     strcpy( subtitle->lang, language->eng_name );
     strncpy( subtitle->iso639_2, language->iso639_2, 4 );
     
+    // Copy the extradata for the subtitle track
+    subtitle->extradata = malloc( codec->extradata_size );
+    memcpy( subtitle->extradata, codec->extradata, codec->extradata_size );
+    subtitle->extradata_size = codec->extradata_size;
+    
     hb_list_add(title->list_subtitle, subtitle);
 }
 
+static char *get_ffmpeg_metadata_value( AVMetadata *m, char *key )
+{
+    AVMetadataTag *tag = NULL;
+    while ( tag = av_metadata_get(m, "", tag, AV_METADATA_IGNORE_SUFFIX) )
+    {
+        if ( !strcmp( key, tag->key ) )
+        {
+            return tag->value;
+        }
+    }
+    return NULL;
+}
+
+static void add_ffmpeg_attachment( hb_title_t *title, hb_stream_t *stream, int id )
+{
+    AVStream *st = stream->ffmpeg_ic->streams[id];
+    AVCodecContext *codec = st->codec;
+    
+    enum attachtype type;
+    switch ( codec->codec_id )
+    {
+        case CODEC_ID_TTF:
+            type = FONT_TTF_ATTACH;
+            break;
+        default:
+            // Ignore unrecognized attachment type
+            return;
+    }
+    
+    hb_attachment_t *attachment = calloc( 1, sizeof(*attachment) );
+    
+    // Copy the attachment name and data
+    attachment->type = type;
+    attachment->name = strdup( get_ffmpeg_metadata_value( st->metadata, "filename" ) );
+    attachment->data = malloc( codec->extradata_size );
+    memcpy( attachment->data, codec->extradata, codec->extradata_size );
+    attachment->size = codec->extradata_size;
+    
+    hb_list_add(title->list_attachment, attachment);
+}
+
 static hb_title_t *ffmpeg_title_scan( hb_stream_t *stream )
 {
     AVFormatContext *ic = stream->ffmpeg_ic;
@@ -3244,6 +3290,10 @@ static hb_title_t *ffmpeg_title_scan( hb_stream_t *stream )
         {
             add_ffmpeg_subtitle( title, stream, i );
         }
+        else if ( ic->streams[i]->codec->codec_type == CODEC_TYPE_ATTACHMENT )
+        {
+            add_ffmpeg_attachment( title, stream, i );
+        }
     }
 
     title->container_name = strdup( ic->iformat->name );
index 53b3193a3ebed8d3cbc52314ddc5a7108cc91519..58628f316866c15b28c90f7c795747fe46941413 100644 (file)
@@ -247,6 +247,8 @@ void syncVideoClose( hb_work_object_t * w )
  ***********************************************************************
  *
  **********************************************************************/
+static hb_buffer_t * copy_subtitle( hb_buffer_t * src );
+
 int syncVideoWork( hb_work_object_t * w, hb_buffer_t ** buf_in,
               hb_buffer_t ** buf_out )
 {
@@ -562,12 +564,10 @@ int syncVideoWork( hb_work_object_t * w, hb_buffer_t ** buf_in,
         /*
          * Rewrite timestamps on subtitles that need it (on raw queue).
          */
-        if( subtitle->source == CC608SUB ||
-            subtitle->source == CC708SUB ||
-            subtitle->source == SRTSUB ||
-            subtitle->source == UTF8SUB ||
-            subtitle->source == TX3GSUB ||
-            subtitle->source == SSASUB)
+        // NOTE: It's probably fine to use this logic for passthru VOBSUBs as well,
+        //       but I am currently preserving backwards compatibility with the old
+        //       VOBSUB behavior, which uses the more complex logic following this if-statement.
+        if( subtitle->config.dest == PASSTHRUSUB && subtitle->source != VOBSUB )
         {
             /*
              * Rewrite timestamps on subtitles that came from Closed Captions
@@ -611,9 +611,13 @@ int syncVideoWork( hb_work_object_t * w, hb_buffer_t ** buf_in,
                     }
                 }
             }
+            
+            continue;
         }
 
-        if( subtitle->source == VOBSUB ) 
+        // For rendered subtitles (and, for backward compatibility, passthru VOBSUBs),
+        // delay pushing subtitle packets through the pipeline until the video catches up
+        if( subtitle->config.dest == RENDERSUB || subtitle->source == VOBSUB ) 
         {
             hb_buffer_t * sub2;
             while( ( sub = hb_fifo_see( subtitle->fifo_raw ) ) )
@@ -681,7 +685,7 @@ int syncVideoWork( hb_work_object_t * w, hb_buffer_t ** buf_in,
                                  * Subtitle is on for less than three 
                                  * seconds, extend the time that it is 
                                  * displayed to make it easier to read. 
-                                 * Make it 3 seconds or until the next
+                                 * Make it 2 seconds or until the next
                                  * subtitle is displayed.
                                  *
                                  * This is in response to Indochine which 
@@ -760,24 +764,23 @@ int syncVideoWork( hb_work_object_t * w, hb_buffer_t ** buf_in,
             }
             
             /* If we have a subtitle for this picture, copy it */
-            /* FIXME: we should avoid this memcpy */
             if( sub )
             {
                 if( sub->size > 0 )
                 {
                     if( subtitle->config.dest == RENDERSUB )
                     {
+                        // Only allow one subtitle to be showing at once; ignore others
                         if ( cur->sub == NULL )
                         {
                             /*
                              * Tack onto the video buffer for rendering
                              */
-                            cur->sub         = hb_buffer_init( sub->size );
-                            cur->sub->x      = sub->x;
-                            cur->sub->y      = sub->y;
-                            cur->sub->width  = sub->width;
-                            cur->sub->height = sub->height;
-                            memcpy( cur->sub->data, sub->data, sub->size ); 
+                            /* FIXME: we should avoid this memcpy */
+                            cur->sub = copy_subtitle( sub );
+                            
+                            // Leave the subtitle on the raw queue
+                            // (until it no longer needs to be displayed)
                         }
                     } else {
                         /*
@@ -846,6 +849,29 @@ int syncVideoWork( hb_work_object_t * w, hb_buffer_t ** buf_in,
     return HB_WORK_OK;
 }
 
+static hb_buffer_t * copy_subtitle( hb_buffer_t * src_list )
+{
+    hb_buffer_t * dst_list = NULL;
+    
+    hb_buffer_t * src;
+    hb_buffer_t * dst;
+    hb_buffer_t ** dst_ptr = &dst_list;
+    for ( src = src_list, dst_ptr = &dst_list;
+          src;
+          src = src->next_subpicture, dst_ptr = &dst->next_subpicture )
+    {
+        (*dst_ptr)  = hb_buffer_init( src->size );
+        dst         = (*dst_ptr); 
+        dst->x      = src->x;
+        dst->y      = src->y;
+        dst->width  = src->width;
+        dst->height = src->height;
+        memcpy( dst->data, src->data, src->size );
+    }
+    
+    return dst_list;
+}
+
 // sync*Init does nothing because sync has a special initializer
 // that takes care of initializing video and all audio tracks
 int syncVideoInit( hb_work_object_t * w, hb_job_t * job)
index 68bb6fe2f364cd65907eb5bf9be5ab27cf334623..3c3346d19ff0150a9b901d0047dd6312be87e16f 100644 (file)
@@ -317,11 +317,7 @@ void hb_display_job_info( hb_job_t * job )
             {
                 hb_log( " * subtitle track %i, %s (id %x) %s [%s] -> %s%s%s", subtitle->track, subtitle->lang, subtitle->id,
                         subtitle->format == PICTURESUB ? "Picture" : "Text",
-                        subtitle->source == VOBSUB ? "VOBSUB" : 
-                        subtitle->source == CC608SUB || subtitle->source == CC708SUB ? "CC" : 
-                        subtitle->source == UTF8SUB ? "UTF-8" : 
-                        subtitle->source == TX3GSUB ? "TX3G" : 
-                        subtitle->source == SSASUB ? "SSA" : "Unknown",
+                        hb_subsource_name( subtitle->source ),
                         job->indepth_scan ? "Foreign Audio Search" :
                         subtitle->config.dest == RENDERSUB ? "Render/Burn in" : "Pass-Through",
                         subtitle->config.force ? ", Forced Only" : "",
@@ -422,6 +418,7 @@ static void do_job( hb_job_t * job, int cpu_count )
 
     hb_audio_t   * audio;
     hb_subtitle_t * subtitle;
+    hb_attachment_t * attachment;
     unsigned int subtitle_highest = 0;
     unsigned int subtitle_highest_id = 0;
     unsigned int subtitle_lowest = -1;
@@ -819,6 +816,7 @@ static void do_job( hb_job_t * job, int cpu_count )
                 w = hb_get_work( WORK_DECSSASUB );
                 w->fifo_in  = subtitle->fifo_in;
                 w->fifo_out = subtitle->fifo_raw;
+                w->subtitle = subtitle;
                 hb_list_add( job->list_work, w );
             }
 
index 7fbd5f28022a1f4fa5e967cc730015ca583ed22a..9c7f1999a17c9b1e308f972677ef40f7bfca1edb 100644 (file)
@@ -3183,6 +3183,13 @@ bool one_burned = FALSE;
                             continue;
                         one_burned = TRUE;
                     }
+                    
+                    /* Besides VOBSUBS we can also burn in SSA text subs */
+                    if (subt->source == SSASUB && burned)
+                    {
+                        sub_config.dest = RENDERSUB;
+                    }
+                    
                     sub_config.force = force;
                     sub_config.default_track = def;
                     hb_subtitle_add( job, &sub_config, subtitle );
@@ -3672,13 +3679,20 @@ bool one_burned = FALSE;
                     {
                         sub_config.dest = PASSTHRUSUB;
                     }
-                    else if ( burned && subt->format == PICTURESUB )
+                    else if ( burned  )
                     {
                         // Only allow one subtitle to be burned into the video
                         if (one_burned)
                             continue;
                         one_burned = TRUE;
                     }
+                    
+                    /* Besides VOBSUBS we can also burn in SSA text subs */
+                    if (subt->source == SSASUB && burned)
+                    {
+                        sub_config.dest = RENDERSUB;
+                    }
+
                     sub_config.force = force;
                     sub_config.default_track = def;
                     hb_subtitle_add( job, &sub_config, subtitle );
index aca6c023b7df9c4dd3934c4a1335050113bc38b1..b084de52570c6ef1e17757de44ea451fe3cd8218 100644 (file)
             {
                 NSString * trackTypeString = @"";
                 int isPictureSub = 0;
+                int canBeBurnedIn = 0;
                 subtitle = (hb_subtitle_t *) hb_list_item( fTitle->list_subtitle, i );
                 sub_config = subtitle->config;
                 
                 {
                     trackTypeString = @"- (Bitmap)";
                     isPictureSub = 1;
+                    canBeBurnedIn = 1;
                 }
                 else
                 {
                     trackTypeString = @"- (Text)";
+                    if(subtitle->source == SSASUB)
+                    {
+                       canBeBurnedIn = 1;
+                    }
                 }
-                
                 /* create a dictionary of source subtitle information to store in our array */
                 NSString *popupName = [NSString stringWithFormat:@"%d - %@ %@",i,[NSString stringWithUTF8String:subtitle->lang],trackTypeString];
                 NSMutableDictionary *newSubtitleSourceTrack = [[NSMutableDictionary alloc] init];
                 [newSubtitleSourceTrack setObject:@"Source" forKey:@"sourceTrackType"];
                 /* Subtitle Source track popup isPictureSub */ 
                 [newSubtitleSourceTrack setObject:[NSNumber numberWithInt:isPictureSub] forKey:@"sourceTrackisPictureSub"];
+                /* Subtitle Source track popup canBeBurnedIn */ 
+                [newSubtitleSourceTrack setObject:[NSNumber numberWithInt:canBeBurnedIn] forKey:@"sourceTrackcanBeBurnedIn"];
                 
                 [subtitleSourceArray addObject:newSubtitleSourceTrack];
                 [newSubtitleSourceTrack autorelease];
     [newSubtitleTrack setObject:@"None" forKey:@"subtitleSourceTrackName"];
     /* Subtitle Source track popup isPictureSub */
     [newSubtitleTrack setObject:[NSNumber numberWithInt:0] forKey:@"subtitleSourceTrackisPictureSub"];
+    /* Subtitle Source track popup canBeBurnedIn */
+    [newSubtitleTrack setObject:[NSNumber numberWithInt:0] forKey:@"subtitleSourceTrackcanBeBurnedIn"];
     /* Subtitle track forced state */
     [newSubtitleTrack setObject:[NSNumber numberWithInt:0] forKey:@"subtitleTrackForced"];
     /* Subtitle track burned state */
     [newSubtitleSourceTrack setObject:@"SRT" forKey:@"subtitleSourceTrackType"];
     /* Subtitle Source track type */
     [newSubtitleSourceTrack setObject:filePath forKey:@"sourceSrtFilePath"];
-    /* Subtitle Source track popup isPictureSub */ 
+    /* Subtitle Source track popup isPictureSub */
     [newSubtitleSourceTrack setObject:[NSNumber numberWithInt:0] forKey:@"sourceTrackisPictureSub"];
+    /* Subtitle Source track popup canBeBurnedIn */ 
+    [newSubtitleSourceTrack setObject:[NSNumber numberWithInt:0] forKey:@"sourceTrackcanBeBurnedIn"];
     
     [subtitleSourceArray addObject:newSubtitleSourceTrack];
     [newSubtitleSourceTrack autorelease];
     [newSubtitleSrtTrack setObject:displayname forKey:@"subtitleSourceTrackName"];
     /* Subtitle Source track popup isPictureSub */
     [newSubtitleSrtTrack setObject:[NSNumber numberWithInt:0] forKey:@"subtitleSourceTrackisPictureSub"];
+    /* Subtitle Source track popup canBeBurnedIn */
+    [newSubtitleSrtTrack setObject:[NSNumber numberWithInt:0] forKey:@"subtitleSourceTrackcanBeBurnedIn"];
     /* Subtitle track forced state */
     [newSubtitleSrtTrack setObject:[NSNumber numberWithInt:0] forKey:@"subtitleTrackForced"];
     /* Subtitle track burned state */
             [newSubtitleSourceTrack setObject:filePath forKey:@"sourceSrtFilePath"];
             /* Subtitle Source track popup isPictureSub */ 
             [newSubtitleSourceTrack setObject:[NSNumber numberWithInt:0] forKey:@"sourceTrackisPictureSub"];
+            /* Subtitle Source track popup canBeBurnedIn */ 
+            [newSubtitleSourceTrack setObject:[NSNumber numberWithInt:0] forKey:@"sourceTrackcanBeBurnedIn"];
             
             [subtitleSourceArray addObject:newSubtitleSourceTrack];
             [newSubtitleSourceTrack autorelease];
         {
             int sourceSubtitleIndex;
             bool isPictureSub = FALSE;
+            bool canBeBurnedIn = FALSE;
             
             if (rowIndex == 0)
             {
             if (rowIndex == 0 && [anObject intValue] == 1)// we are Foreign Launguage Search, which is inherently bitmap
             {
                 isPictureSub = TRUE;
+                canBeBurnedIn = TRUE;
             }
             else
             {
                 {
                     isPictureSub = TRUE;
                 }
+                if ([[[subtitleSourceArray objectAtIndex:sourceSubtitleIndex] objectForKey:@"sourceTrackcanBeBurnedIn"] intValue] ==1)
+                {
+                    canBeBurnedIn = TRUE;
+                }
             }
             if (isPictureSub == TRUE)
             {
             else
             {
                 [[subtitleArray objectAtIndex:rowIndex] setObject:[NSNumber numberWithInt:0] forKey:@"subtitleSourceTrackisPictureSub"];
-                /* if we are not picture sub, then we must be a text sub, handbrake does not support burning in text subs */
+            }
+            if (canBeBurnedIn == TRUE)
+            {
+                [[subtitleArray objectAtIndex:rowIndex] setObject:[NSNumber numberWithInt:1] forKey:@"subtitleSourceTrackcanBeBurnedIn"];
+            }
+            else
+            {
+                [[subtitleArray objectAtIndex:rowIndex] setObject:[NSNumber numberWithInt:0] forKey:@"subtitleSourceTrackcanBeBurnedIn"];
+                /* the source track cannot be burned in, so uncheck the widget */
                 [[subtitleArray objectAtIndex:rowIndex] setObject:[NSNumber numberWithInt:0] forKey:@"subtitleTrackBurned"];
             }
             
         else if ([[aTableColumn identifier] isEqualToString:@"burned"])
         {
             [aCell setState:[[[subtitleArray objectAtIndex:rowIndex] objectForKey:@"subtitleTrackBurned"] intValue]];
-            /* Disable the "Burned-In" checkbox if a) the track is "None" or b) the subtitle track is text (we do not support burning in
-             * text subs) */
+            /* Disable the "Burned-In" checkbox if a) the track is "None" or b) the subtitle track is text but not ssa (we do not support burning in
+             * non-ssa text subs) */
             if ([[[subtitleArray objectAtIndex:rowIndex] objectForKey:@"subtitleSourceTrackNum"] intValue] == 0 ||
-                [[[subtitleArray objectAtIndex:rowIndex] objectForKey:@"subtitleSourceTrackisPictureSub"] intValue] == 0)
+                [[[subtitleArray objectAtIndex:rowIndex] objectForKey:@"subtitleSourceTrackcanBeBurnedIn"] intValue] == 0)
             {
                 [aCell setEnabled:NO];
             }
index c851352335fcb0ef2ed935a730fdaa81b3106104..660787ae10108a3e4c52a73206413d2c930e16bb 100644 (file)
                                OTHER_LDFLAGS = (
                                        "$(EXTERNAL_BUILD)/contrib/lib/libbluray.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/liba52.a",
+                                       "$(EXTERNAL_BUILD)/contrib/lib/libass.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libavcodec.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libavformat.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libavutil.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libdvdread.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libfaac.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libfaad.a",
+                                       "$(EXTERNAL_BUILD)/contrib/lib/libfontconfig.a",
+                                       "$(EXTERNAL_BUILD)/contrib/lib/libfreetype.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libmkv.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libmp3lame.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libmp4v2.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libvorbis.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libvorbisenc.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libx264.a",
+                                       "$(EXTERNAL_BUILD)/contrib/lib/libxml2.a",
                                );
                                PRODUCT_NAME = HandBrakeCLI;
                        };
                                OTHER_LDFLAGS = (
                                        "$(EXTERNAL_BUILD)/contrib/lib/libbluray.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/liba52.a",
+                                       "$(EXTERNAL_BUILD)/contrib/lib/libass.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libavcodec.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libavformat.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libavutil.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libdvdread.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libfaac.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libfaad.a",
+                                       "$(EXTERNAL_BUILD)/contrib/lib/libfontconfig.a",
+                                       "$(EXTERNAL_BUILD)/contrib/lib/libfreetype.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libmkv.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libmp3lame.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libmp4v2.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libvorbis.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libvorbisenc.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libx264.a",
+                                       "$(EXTERNAL_BUILD)/contrib/lib/libxml2.a",
                                );
                                PRODUCT_NAME = HandBrakeCLI;
                        };
                                CONFIGURATION_BUILD_DIR = "$(EXTERNAL_BUILD)";
                                CONFIGURATION_TEMP_DIR = "$(SYMROOT)";
                                EXTERNAL_BUILD = "$(EXTERNAL_SRC)/build.$(CONFIGURATION)";
-                               EXTERNAL_JOBS = 2;
+                               EXTERNAL_JOBS = 1;
                                EXTERNAL_METHOD = xcode;
                                EXTERNAL_SRC = ..;
                                FRAMEWORK_SEARCH_PATHS = "$(EXTERNAL_SRC)/macosx";
                                OTHER_LDFLAGS = (
                                        "$(EXTERNAL_BUILD)/contrib/lib/libbluray.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/liba52.a",
+                                       "$(EXTERNAL_BUILD)/contrib/lib/libass.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libavcodec.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libavformat.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libavutil.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libdvdread.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libfaac.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libfaad.a",
+                                       "$(EXTERNAL_BUILD)/contrib/lib/libfontconfig.a",
+                                       "$(EXTERNAL_BUILD)/contrib/lib/libfreetype.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libmkv.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libmp3lame.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libmp4v2.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libvorbis.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libvorbisenc.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libx264.a",
+                                       "$(EXTERNAL_BUILD)/contrib/lib/libxml2.a",
                                );
                                PRODUCT_NAME = HandBrake;
                                WARNING_CFLAGS = (
                                OTHER_LDFLAGS = (
                                        "$(EXTERNAL_BUILD)/contrib/lib/libbluray.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/liba52.a",
+                                       "$(EXTERNAL_BUILD)/contrib/lib/libass.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libavcodec.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libavformat.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libavutil.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libdvdread.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libfaac.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libfaad.a",
+                                       "$(EXTERNAL_BUILD)/contrib/lib/libfontconfig.a",
+                                       "$(EXTERNAL_BUILD)/contrib/lib/libfreetype.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libmkv.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libmp3lame.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libmp4v2.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libvorbis.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libvorbisenc.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libx264.a",
+                                       "$(EXTERNAL_BUILD)/contrib/lib/libxml2.a",
                                );
                                PRODUCT_NAME = HandBrakeCLI;
                        };
                                CONFIGURATION_BUILD_DIR = "$(EXTERNAL_BUILD)";
                                CONFIGURATION_TEMP_DIR = "$(SYMROOT)";
                                EXTERNAL_BUILD = "$(EXTERNAL_SRC)/build.$(CONFIGURATION)";
-                               EXTERNAL_JOBS = 2;
+                               EXTERNAL_JOBS = 1;
                                EXTERNAL_METHOD = xcode;
                                EXTERNAL_SRC = ..;
                                FRAMEWORK_SEARCH_PATHS = "$(EXTERNAL_SRC)/macosx";
                                OTHER_LDFLAGS = (
                                        "$(EXTERNAL_BUILD)/contrib/lib/libbluray.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/liba52.a",
+                                       "$(EXTERNAL_BUILD)/contrib/lib/libass.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libavcodec.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libavformat.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libavutil.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libdvdread.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libfaac.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libfaad.a",
+                                       "$(EXTERNAL_BUILD)/contrib/lib/libfontconfig.a",
+                                       "$(EXTERNAL_BUILD)/contrib/lib/libfreetype.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libmkv.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libmp3lame.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libmp4v2.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libvorbis.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libvorbisenc.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libx264.a",
+                                       "$(EXTERNAL_BUILD)/contrib/lib/libxml2.a",
                                );
                                PRODUCT_NAME = HandBrake;
                                WARNING_CFLAGS = (
                                OTHER_LDFLAGS = (
                                        "$(EXTERNAL_BUILD)/contrib/lib/libbluray.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/liba52.a",
+                                       "$(EXTERNAL_BUILD)/contrib/lib/libass.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libavcodec.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libavformat.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libavutil.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libdvdread.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libfaac.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libfaad.a",
+                                       "$(EXTERNAL_BUILD)/contrib/lib/libfontconfig.a",
+                                       "$(EXTERNAL_BUILD)/contrib/lib/libfreetype.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libmkv.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libmp3lame.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libmp4v2.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libvorbis.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libvorbisenc.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libx264.a",
+                                       "$(EXTERNAL_BUILD)/contrib/lib/libxml2.a",
                                );
                                PRODUCT_NAME = HandBrakeCLI;
                        };
                                CONFIGURATION_BUILD_DIR = "$(EXTERNAL_BUILD)";
                                CONFIGURATION_TEMP_DIR = "$(SYMROOT)";
                                EXTERNAL_BUILD = "$(EXTERNAL_SRC)/build.$(CONFIGURATION)";
-                               EXTERNAL_JOBS = 2;
+                               EXTERNAL_JOBS = 1;
                                EXTERNAL_METHOD = xcode;
                                EXTERNAL_SRC = ..;
                                FRAMEWORK_SEARCH_PATHS = "$(EXTERNAL_SRC)/macosx";
                                OTHER_LDFLAGS = (
                                        "$(EXTERNAL_BUILD)/contrib/lib/libbluray.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/liba52.a",
+                                       "$(EXTERNAL_BUILD)/contrib/lib/libass.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libavcodec.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libavformat.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libavutil.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libdvdread.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libfaac.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libfaad.a",
+                                       "$(EXTERNAL_BUILD)/contrib/lib/libfontconfig.a",
+                                       "$(EXTERNAL_BUILD)/contrib/lib/libfreetype.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libmkv.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libmp3lame.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libmp4v2.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libvorbis.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libvorbisenc.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libx264.a",
+                                       "$(EXTERNAL_BUILD)/contrib/lib/libxml2.a",
                                );
                                PRODUCT_NAME = HandBrake;
                                WARNING_CFLAGS = (
                                OTHER_LDFLAGS = (
                                        "$(EXTERNAL_BUILD)/contrib/lib/libbluray.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/liba52.a",
+                                       "$(EXTERNAL_BUILD)/contrib/lib/libass.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libavcodec.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libavformat.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libavutil.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libdvdread.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libfaac.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libfaad.a",
+                                       "$(EXTERNAL_BUILD)/contrib/lib/libfontconfig.a",
+                                       "$(EXTERNAL_BUILD)/contrib/lib/libfreetype.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libmkv.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libmp3lame.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libmp4v2.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libvorbis.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libvorbisenc.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libx264.a",
+                                       "$(EXTERNAL_BUILD)/contrib/lib/libxml2.a",
                                );
                                PRODUCT_NAME = HandBrakeCLI;
                        };
                                CONFIGURATION_BUILD_DIR = "$(EXTERNAL_BUILD)";
                                CONFIGURATION_TEMP_DIR = "$(SYMROOT)";
                                EXTERNAL_BUILD = "$(EXTERNAL_SRC)/build.$(CONFIGURATION)";
-                               EXTERNAL_JOBS = 2;
+                               EXTERNAL_JOBS = 1;
                                EXTERNAL_METHOD = xcode;
                                EXTERNAL_SRC = ..;
                                FRAMEWORK_SEARCH_PATHS = "$(EXTERNAL_SRC)/macosx";
                                OTHER_LDFLAGS = (
                                        "$(EXTERNAL_BUILD)/contrib/lib/libbluray.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/liba52.a",
+                                       "$(EXTERNAL_BUILD)/contrib/lib/libass.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libavcodec.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libavformat.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libavutil.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libdvdread.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libfaac.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libfaad.a",
+                                       "$(EXTERNAL_BUILD)/contrib/lib/libfontconfig.a",
+                                       "$(EXTERNAL_BUILD)/contrib/lib/libfreetype.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libmkv.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libmp3lame.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libmp4v2.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libvorbis.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libvorbisenc.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libx264.a",
+                                       "$(EXTERNAL_BUILD)/contrib/lib/libxml2.a",
                                );
                                PRODUCT_NAME = HandBrake;
                                WARNING_CFLAGS = (
                                OTHER_LDFLAGS = (
                                        "$(EXTERNAL_BUILD)/contrib/lib/libbluray.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/liba52.a",
+                                       "$(EXTERNAL_BUILD)/contrib/lib/libass.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libavcodec.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libavformat.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libavutil.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libdvdread.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libfaac.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libfaad.a",
+                                       "$(EXTERNAL_BUILD)/contrib/lib/libfontconfig.a",
+                                       "$(EXTERNAL_BUILD)/contrib/lib/libfreetype.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libmkv.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libmp3lame.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libmp4v2.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libvorbis.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libvorbisenc.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libx264.a",
+                                       "$(EXTERNAL_BUILD)/contrib/lib/libxml2.a",
                                );
                                PRODUCT_NAME = HandBrakeCLI;
                        };
                                COPY_PHASE_STRIP = NO;
                                DEBUG_INFORMATION_FORMAT = dwarf;
                                EXTERNAL_BUILD = "$(EXTERNAL_SRC)/build.$(CONFIGURATION)";
-                               EXTERNAL_JOBS = 2;
+                               EXTERNAL_JOBS = 1;
                                EXTERNAL_METHOD = xcode;
                                EXTERNAL_SRC = ..;
                                FRAMEWORK_SEARCH_PATHS = "$(EXTERNAL_SRC)/macosx";
                                OTHER_LDFLAGS = (
                                        "$(EXTERNAL_BUILD)/contrib/lib/libbluray.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/liba52.a",
+                                       "$(EXTERNAL_BUILD)/contrib/lib/libass.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libavcodec.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libavformat.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libavutil.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libdvdread.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libfaac.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libfaad.a",
+                                       "$(EXTERNAL_BUILD)/contrib/lib/libfontconfig.a",
+                                       "$(EXTERNAL_BUILD)/contrib/lib/libfreetype.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libmkv.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libmp3lame.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libmp4v2.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libvorbis.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libvorbisenc.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libx264.a",
+                                       "$(EXTERNAL_BUILD)/contrib/lib/libxml2.a",
                                );
                                PRODUCT_NAME = HandBrake;
                                WARNING_CFLAGS = (
                                OTHER_LDFLAGS = (
                                        "$(EXTERNAL_BUILD)/contrib/lib/libbluray.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/liba52.a",
+                                       "$(EXTERNAL_BUILD)/contrib/lib/libass.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libavcodec.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libavformat.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libavutil.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libdvdread.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libfaac.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libfaad.a",
+                                       "$(EXTERNAL_BUILD)/contrib/lib/libfontconfig.a",
+                                       "$(EXTERNAL_BUILD)/contrib/lib/libfreetype.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libmkv.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libmp3lame.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libmp4v2.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libvorbis.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libvorbisenc.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libx264.a",
+                                       "$(EXTERNAL_BUILD)/contrib/lib/libxml2.a",
                                );
                                PRODUCT_NAME = HandBrakeCLI;
                        };
                                COPY_PHASE_STRIP = NO;
                                DEBUG_INFORMATION_FORMAT = dwarf;
                                EXTERNAL_BUILD = "$(EXTERNAL_SRC)/build.$(CONFIGURATION)";
-                               EXTERNAL_JOBS = 2;
+                               EXTERNAL_JOBS = 1;
                                EXTERNAL_METHOD = xcode;
                                EXTERNAL_SRC = ..;
                                FRAMEWORK_SEARCH_PATHS = "$(EXTERNAL_SRC)/macosx";
                                OTHER_LDFLAGS = (
                                        "$(EXTERNAL_BUILD)/contrib/lib/libbluray.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/liba52.a",
+                                       "$(EXTERNAL_BUILD)/contrib/lib/libass.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libavcodec.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libavformat.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libavutil.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libdvdread.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libfaac.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libfaad.a",
+                                       "$(EXTERNAL_BUILD)/contrib/lib/libfontconfig.a",
+                                       "$(EXTERNAL_BUILD)/contrib/lib/libfreetype.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libmkv.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libmp3lame.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libmp4v2.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libvorbis.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libvorbisenc.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libx264.a",
+                                       "$(EXTERNAL_BUILD)/contrib/lib/libxml2.a",
                                );
                                PRODUCT_NAME = HandBrake;
                                WARNING_CFLAGS = (
                                OTHER_LDFLAGS = (
                                        "$(EXTERNAL_BUILD)/contrib/lib/libbluray.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/liba52.a",
+                                       "$(EXTERNAL_BUILD)/contrib/lib/libass.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libavcodec.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libavformat.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libavutil.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libdvdread.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libfaac.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libfaad.a",
+                                       "$(EXTERNAL_BUILD)/contrib/lib/libfontconfig.a",
+                                       "$(EXTERNAL_BUILD)/contrib/lib/libfreetype.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libmkv.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libmp3lame.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libmp4v2.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libvorbis.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libvorbisenc.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libx264.a",
+                                       "$(EXTERNAL_BUILD)/contrib/lib/libxml2.a",
                                );
                                PRODUCT_NAME = HandBrakeCLI;
                        };
                                COPY_PHASE_STRIP = NO;
                                DEBUG_INFORMATION_FORMAT = dwarf;
                                EXTERNAL_BUILD = "$(EXTERNAL_SRC)/build.$(CONFIGURATION)";
-                               EXTERNAL_JOBS = 2;
+                               EXTERNAL_JOBS = 1;
                                EXTERNAL_METHOD = xcode;
                                EXTERNAL_SRC = ..;
                                FRAMEWORK_SEARCH_PATHS = "$(EXTERNAL_SRC)/macosx";
                                OTHER_LDFLAGS = (
                                        "$(EXTERNAL_BUILD)/contrib/lib/libbluray.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/liba52.a",
+                                       "$(EXTERNAL_BUILD)/contrib/lib/libass.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libavcodec.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libavformat.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libavutil.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libdvdread.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libfaac.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libfaad.a",
+                                       "$(EXTERNAL_BUILD)/contrib/lib/libfontconfig.a",
+                                       "$(EXTERNAL_BUILD)/contrib/lib/libfreetype.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libmkv.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libmp3lame.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libmp4v2.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libvorbis.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libvorbisenc.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libx264.a",
+                                       "$(EXTERNAL_BUILD)/contrib/lib/libxml2.a",
                                );
                                PRODUCT_NAME = HandBrake;
                                WARNING_CFLAGS = (
                                OTHER_LDFLAGS = (
                                        "$(EXTERNAL_BUILD)/contrib/lib/libbluray.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/liba52.a",
+                                       "$(EXTERNAL_BUILD)/contrib/lib/libass.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libavcodec.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libavformat.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libavutil.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libdvdread.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libfaac.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libfaad.a",
+                                       "$(EXTERNAL_BUILD)/contrib/lib/libfontconfig.a",
+                                       "$(EXTERNAL_BUILD)/contrib/lib/libfreetype.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libmkv.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libmp3lame.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libmp4v2.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libvorbis.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libvorbisenc.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libx264.a",
+                                       "$(EXTERNAL_BUILD)/contrib/lib/libxml2.a",
                                );
                                PRODUCT_NAME = HandBrakeCLI;
                        };
                                COPY_PHASE_STRIP = NO;
                                DEBUG_INFORMATION_FORMAT = dwarf;
                                EXTERNAL_BUILD = "$(EXTERNAL_SRC)/build.$(CONFIGURATION)";
-                               EXTERNAL_JOBS = 2;
+                               EXTERNAL_JOBS = 1;
                                EXTERNAL_METHOD = xcode;
                                EXTERNAL_SRC = ..;
                                FRAMEWORK_SEARCH_PATHS = "$(EXTERNAL_SRC)/macosx";
                                OTHER_LDFLAGS = (
                                        "$(EXTERNAL_BUILD)/contrib/lib/libbluray.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/liba52.a",
+                                       "$(EXTERNAL_BUILD)/contrib/lib/libass.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libavcodec.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libavformat.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libavutil.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libdvdread.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libfaac.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libfaad.a",
+                                       "$(EXTERNAL_BUILD)/contrib/lib/libfontconfig.a",
+                                       "$(EXTERNAL_BUILD)/contrib/lib/libfreetype.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libmkv.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libmp3lame.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libmp4v2.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libvorbis.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libvorbisenc.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libx264.a",
+                                       "$(EXTERNAL_BUILD)/contrib/lib/libxml2.a",
                                );
                                PRODUCT_NAME = HandBrake;
                                WARNING_CFLAGS = (
                                OTHER_LDFLAGS = (
                                        "$(EXTERNAL_BUILD)/contrib/lib/libbluray.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/liba52.a",
+                                       "$(EXTERNAL_BUILD)/contrib/lib/libass.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libavcodec.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libavformat.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libavutil.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libdvdread.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libfaac.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libfaad.a",
+                                       "$(EXTERNAL_BUILD)/contrib/lib/libfontconfig.a",
+                                       "$(EXTERNAL_BUILD)/contrib/lib/libfreetype.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libmkv.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libmp3lame.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libmp4v2.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libvorbis.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libvorbisenc.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libx264.a",
+                                       "$(EXTERNAL_BUILD)/contrib/lib/libxml2.a",
                                );
                                PRODUCT_NAME = HandBrakeCLI;
                        };
                                OTHER_LDFLAGS = (
                                        "$(EXTERNAL_BUILD)/contrib/lib/libbluray.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/liba52.a",
+                                       "$(EXTERNAL_BUILD)/contrib/lib/libass.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libavcodec.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libavformat.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libavutil.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libdvdread.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libfaac.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libfaad.a",
+                                       "$(EXTERNAL_BUILD)/contrib/lib/libfontconfig.a",
+                                       "$(EXTERNAL_BUILD)/contrib/lib/libfreetype.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libmkv.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libmp3lame.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libmp4v2.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libvorbis.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libvorbisenc.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libx264.a",
+                                       "$(EXTERNAL_BUILD)/contrib/lib/libxml2.a",
                                );
                                PRODUCT_NAME = HandBrake;
                                WARNING_CFLAGS = (
                                OTHER_LDFLAGS = (
                                        "$(EXTERNAL_BUILD)/contrib/lib/libbluray.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/liba52.a",
+                                       "$(EXTERNAL_BUILD)/contrib/lib/libass.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libavcodec.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libavformat.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libavutil.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libdvdread.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libfaac.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libfaad.a",
+                                       "$(EXTERNAL_BUILD)/contrib/lib/libfontconfig.a",
+                                       "$(EXTERNAL_BUILD)/contrib/lib/libfreetype.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libmkv.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libmp3lame.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libmp4v2.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libvorbis.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libvorbisenc.a",
                                        "$(EXTERNAL_BUILD)/contrib/lib/libx264.a",
+                                       "$(EXTERNAL_BUILD)/contrib/lib/libxml2.a",
                                );
                                PRODUCT_NAME = HandBrake;
                                WARNING_CFLAGS = (
                                COPY_PHASE_STRIP = NO;
                                DEBUG_INFORMATION_FORMAT = dwarf;
                                EXTERNAL_BUILD = "$(EXTERNAL_SRC)/build.$(CONFIGURATION)";
-                               EXTERNAL_JOBS = 2;
+                               EXTERNAL_JOBS = 1;
                                EXTERNAL_METHOD = xcode;
                                EXTERNAL_SRC = ..;
                                FRAMEWORK_SEARCH_PATHS = "$(EXTERNAL_SRC)/macosx";
                                CONFIGURATION_BUILD_DIR = "$(EXTERNAL_BUILD)";
                                CONFIGURATION_TEMP_DIR = "$(SYMROOT)";
                                EXTERNAL_BUILD = "$(EXTERNAL_SRC)/build.$(CONFIGURATION)";
-                               EXTERNAL_JOBS = 2;
+                               EXTERNAL_JOBS = 1;
                                EXTERNAL_METHOD = xcode;
                                EXTERNAL_SRC = ..;
                                FRAMEWORK_SEARCH_PATHS = "$(EXTERNAL_SRC)/macosx";
index a8ac0999d21cf35c7d2dc6e0f3b940554e77fe35..4742f0f3e869ab10326987d61ba51f33935062ce 100644 (file)
@@ -19,7 +19,10 @@ endif
 MODULES += contrib/faac
 MODULES += contrib/faad2
 MODULES += contrib/ffmpeg
+MODULES += contrib/fontconfig
+MODULES += contrib/freetype
 MODULES += contrib/lame
+MODULES += contrib/libass
 MODULES += contrib/libdca
 MODULES += contrib/libdvdread
 MODULES += contrib/libdvdnav
@@ -29,6 +32,7 @@ MODULES += contrib/libogg
 MODULES += contrib/libsamplerate
 MODULES += contrib/libtheora
 MODULES += contrib/libvorbis
+MODULES += contrib/libxml2
 MODULES += contrib/mp4v2
 MODULES += contrib/mpeg2dec
 
index 7dd323556d376bd3996e683a13405b5d76f09125..33d34d43e6be1974235d9ce00a6a22efe8c2b5ad 100644 (file)
@@ -10,8 +10,8 @@ TEST.c.o = $(patsubst $(SRC/)%.c,$(BUILD/)%.o,$(TEST.c))
 TEST.exe = $(BUILD/)$(call TARGET.exe,$(HB.name)CLI)
 
 TEST.libs = $(LIBHB.a) $(foreach n, \
-        a52 avcore avcodec avformat avutil dca dvdnav dvdread faac faad mkv mpeg2 mp3lame mp4v2 \
-        ogg samplerate swscale theora vorbis vorbisenc x264 bluray, \
+        a52 ass avcore avcodec avformat avutil dca dvdnav dvdread faac faad fontconfig freetype mkv mpeg2 mp3lame mp4v2 \
+        ogg samplerate swscale theora vorbis vorbisenc x264 xml2 bluray, \
         $(CONTRIB.build/)lib/lib$(n).a )
 
 TEST.install.exe = $(DESTDIR)$(PREFIX/)bin/$(notdir $(TEST.exe))
index cff30ef4b76ac25e28dd411a363e1a83676bec31..f5fb9ec57d58aaec044023ccf9f883440f967231 100644 (file)
@@ -440,10 +440,11 @@ static void PrintTitleInfo( hb_title_t * title )
     for( i = 0; i < hb_list_count( title->list_subtitle ); i++ )
     {
         subtitle = hb_list_item( title->list_subtitle, i );
-        fprintf( stderr, "    + %d, %s (iso639-2: %s) (%s)\n", 
+        fprintf( stderr, "    + %d, %s (iso639-2: %s) (%s)(%s)\n", 
                  i + 1, subtitle->lang,
                  subtitle->iso639_2,
-                 (subtitle->format == TEXTSUB) ? "Text" : "Bitmap");
+                 (subtitle->format == TEXTSUB) ? "Text" : "Bitmap",
+                 hb_subsource_name(subtitle->source));
     }
 
     if(title->detected_interlacing)
@@ -1857,12 +1858,12 @@ static int HandleEvents( hb_handle_t * h )
                         }
 
                         force = test_sub_list(subforce, token, pos);
-
-                        if ( !burn && subtitle->format == PICTURESUB)
-                        {
-                            sub_config.dest = PASSTHRUSUB;
-                        }
-                        else if ( burn && subtitle->format == PICTURESUB )
+                        
+                        int supports_burn =
+                            ( subtitle->source == VOBSUB ) ||
+                            ( subtitle->source == SSASUB );
+                        
+                        if ( burn && supports_burn )
                         {
                             // Only allow one subtitle to be burned into video
                             if ( sub_burned )
@@ -1871,6 +1872,13 @@ static int HandleEvents( hb_handle_t * h )
                                 continue;
                             }
                             sub_burned = 1;
+                            
+                            // Mark as burn-in
+                            sub_config.dest = RENDERSUB;
+                        }
+                        else
+                        {
+                            sub_config.dest = PASSTHRUSUB;
                         }
                         sub_config.force = force;
                         sub_config.default_track = def;