OSDN Git Service

CLI: SubRip Subtitle import
authoreddyg <eddyg@b64f7644-9d1e-0410-96f1-a4d463321fa5>
Tue, 23 Jun 2009 00:32:36 +0000 (00:32 +0000)
committereddyg <eddyg@b64f7644-9d1e-0410-96f1-a4d463321fa5>
Tue, 23 Jun 2009 00:32:36 +0000 (00:32 +0000)
git-svn-id: svn://localhost/HandBrake/trunk@2602 b64f7644-9d1e-0410-96f1-a4d463321fa5

libhb/common.c
libhb/common.h
libhb/hb.c
libhb/internal.h
libhb/module.defs
libhb/sync.c
libhb/work.c
macosx/HandBrake.xcodeproj/project.pbxproj
make/include/main.defs
test/module.defs
test/test.c

index cea4a50..8249963 100644 (file)
@@ -9,6 +9,7 @@
 #include <sys/time.h>
 
 #include "common.h"
+#include "lang.h"
 #include "hb.h"
 
 /**********************************************************************
@@ -864,8 +865,37 @@ int hb_subtitle_add(const hb_job_t * job, const hb_subtitle_config_t * subtitlec
         /* We fail! */
         return 0;
     }
-       subtitle->config = *subtitlecfg;
+    subtitle->config = *subtitlecfg;
     hb_list_add(job->list_subtitle, subtitle);
     return 1;
 }
 
+int hb_srt_add( const hb_job_t * job, 
+                const hb_subtitle_config_t * subtitlecfg, 
+                const char *lang )
+{
+    hb_subtitle_t *subtitle;
+    iso639_lang_t *language = NULL;
+    int retval = 0;
+
+    subtitle = calloc( 1, sizeof( *subtitle ) );
+    
+    subtitle->format = TEXTSUB;
+    subtitle->source = SRTSUB;
+
+    language = lang_for_code2( lang );
+
+    if( language )
+    {
+
+        strcpy( subtitle->lang, language->eng_name );
+        strncpy( subtitle->iso639_2, lang, 4 );
+        
+        subtitle->config = *subtitlecfg;
+        subtitle->config.dest = PASSTHRUSUB;
+
+        hb_list_add(job->list_subtitle, subtitle);
+        retval = 1;
+    }
+    return retval;
+}
index 488004f..808714e 100644 (file)
@@ -96,6 +96,9 @@ 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);
 
 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);
+
 
 struct hb_rate_s
 {
@@ -115,7 +118,10 @@ struct hb_subtitle_config_s
 {
     enum subdest { RENDERSUB, PASSTHRUSUB } dest;
     int  force;
-    int  default_track;
+    int  default_track; 
+    char src_filename[128];
+    char src_codeset[40];
+    int64_t offset;
 };
 
 #define HB_VIDEO_RATE_BASE   27000000
@@ -671,6 +677,7 @@ extern hb_work_object_t hb_decmpeg2;
 extern hb_work_object_t hb_decvobsub;
 extern hb_work_object_t hb_encvobsub;
 extern hb_work_object_t hb_deccc608;
+extern hb_work_object_t hb_decsrtsub;
 extern hb_work_object_t hb_render;
 extern hb_work_object_t hb_encavcodec;
 extern hb_work_object_t hb_encx264;
index df04aea..898650a 100644 (file)
@@ -162,6 +162,7 @@ hb_handle_t * hb_init( int verbose, int update_check )
        hb_register( &hb_decvobsub );
     hb_register( &hb_encvobsub );
     hb_register( &hb_deccc608 );
+    hb_register( &hb_decsrtsub );
        hb_register( &hb_render );
        hb_register( &hb_encavcodec );
        hb_register( &hb_encx264 );
@@ -258,6 +259,7 @@ hb_handle_t * hb_init_dl( int verbose, int update_check )
        hb_register( &hb_decvobsub );
     hb_register( &hb_encvobsub );
     hb_register( &hb_deccc608 );
+    hb_register( &hb_decsrtsub );
        hb_register( &hb_render );
        hb_register( &hb_encavcodec );
        hb_register( &hb_encx264 );
index 397883d..a00142b 100644 (file)
@@ -256,6 +256,7 @@ enum
     WORK_DECMPEG2,
     WORK_DECCC608,
     WORK_DECVOBSUB,
+    WORK_DECSRTSUB,
     WORK_ENCVOBSUB,
     WORK_RENDER,
     WORK_ENCAVCODEC,
index c79e70b..f3da3c0 100644 (file)
@@ -1,5 +1,5 @@
 __deps__ := A52DEC BZIP2 FAAC FAAD2 FFMPEG LAME LIBDCA \
-    LIBDVDREAD LIBDVDNAV LIBMKV LIBOGG LIBSAMPLERATE LIBTHEORA LIBVORBIS \
+    LIBDVDREAD LIBDVDNAV LIBICONV LIBMKV LIBOGG LIBSAMPLERATE LIBTHEORA LIBVORBIS \
     MP4V2 MPEG2DEC PTHREADW32 X264 ZLIB
 
 $(eval $(call import.MODULE.defs,LIBHB,libhb,$(__deps__)))
@@ -88,7 +88,7 @@ LIBHB.dll = $(LIBHB.build/)hb.dll
 LIBHB.lib = $(LIBHB.build/)hb.lib
 
 LIBHB.dll.libs = $(foreach n, \
-        a52 bz2 avcodec avformat avutil dca dvdnav dvdread faac faad mkv mpeg2 mp3lame mp4v2 \
+        a52 bz2 avcodec avformat avutil dca dvdnav dvdread faac faad iconv mkv mpeg2 mp3lame mp4v2 \
         ogg pthreadGC2 samplerate swscale theora vorbis vorbisenc x264 z, \
         $(CONTRIB.build/)lib/lib$(n).a )
 
index 2043b9d..14e5048 100644 (file)
@@ -446,7 +446,8 @@ static void SyncVideo( hb_work_object_t * w )
              * Rewrite timestamps on subtitles that need it (on raw queue).
              */
             if( subtitle->source == CC608SUB ||
-                subtitle->source == CC708SUB )
+                subtitle->source == CC708SUB ||
+                subtitle->source == SRTSUB )
             {
                 /*
                  * Rewrite timestamps on subtitles that came from Closed Captions
index 486b8a3..d0afb50 100644 (file)
@@ -589,6 +589,15 @@ static void do_job( hb_job_t * job, int cpu_count )
                 hb_list_add( job->list_work, w );
             }
 
+            if( !job->indepth_scan && subtitle->source == SRTSUB )
+            {
+                w = hb_get_work( WORK_DECSRTSUB );
+                w->fifo_in  = subtitle->fifo_in;
+                w->fifo_out = subtitle->fifo_raw;
+                w->subtitle = subtitle;
+                hb_list_add( job->list_work, w );
+            }
+
             if( !job->indepth_scan && 
                 subtitle->format == PICTURESUB
                 && subtitle->config.dest == PASSTHRUSUB )
index 892ab58..ce2d260 100644 (file)
@@ -18,6 +18,8 @@
                2713E6300F676510002E0A01 /* libhb.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 2713E50C0F675F32002E0A01 /* libhb.a */; };
                2713E6420F676526002E0A01 /* libhb.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 2713E50C0F675F32002E0A01 /* libhb.a */; };
                2728D25B0FE8419900758EC9 /* HandBrake-64.icns in Resources */ = {isa = PBXBuildFile; fileRef = 2728D25A0FE8419900758EC9 /* HandBrake-64.icns */; };
+               274DD1E40FEF109900881E69 /* libiconv.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 274DD1E30FEF109900881E69 /* libiconv.dylib */; };
+               274DD20B0FEF10FD00881E69 /* libiconv.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 274DD1E30FEF109900881E69 /* libiconv.dylib */; };
                2774BE900F66F47100B65FC6 /* libbz2.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 2774BE8F0F66F47100B65FC6 /* libbz2.dylib */; };
                2774BE920F66F48200B65FC6 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 2774BE910F66F48200B65FC6 /* libz.dylib */; };
                2774BEC70F66F61A00B65FC6 /* libbz2.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 2774BE8F0F66F47100B65FC6 /* libbz2.dylib */; };
                25DE1FB50C169A0C00F01FC8 /* HBPreferencesController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HBPreferencesController.m; sourceTree = "<group>"; };
                2713E50C0F675F32002E0A01 /* libhb.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libhb.a; path = libhb/libhb.a; sourceTree = BUILT_PRODUCTS_DIR; };
                2728D25A0FE8419900758EC9 /* HandBrake-64.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = "HandBrake-64.icns"; sourceTree = "<group>"; };
+               274DD1E30FEF109900881E69 /* libiconv.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libiconv.dylib; path = /usr/lib/libiconv.dylib; sourceTree = "<absolute>"; };
                2774BE8F0F66F47100B65FC6 /* libbz2.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libbz2.dylib; path = usr/lib/libbz2.dylib; sourceTree = SDKROOT; };
                2774BE910F66F48200B65FC6 /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.dylib; path = usr/lib/libz.dylib; sourceTree = SDKROOT; };
                27AC71840F5A0AF600053B83 /* fakexcode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = fakexcode.cpp; path = ../test/fakexcode.cpp; sourceTree = SOURCE_ROOT; };
                        buildActionMask = 2147483647;
                        files = (
                                D289A9F30DBBE7AC00CE614B /* CoreServices.framework in Frameworks */,
+                               A906A0520F7A7B210007A827 /* AudioToolbox.framework in Frameworks */,
                                D289AAC40DBBF3F100CE614B /* IOKit.framework in Frameworks */,
                                2713E6300F676510002E0A01 /* libhb.a in Frameworks */,
+                               274DD1E40FEF109900881E69 /* libiconv.dylib in Frameworks */,
                                2774BE900F66F47100B65FC6 /* libbz2.dylib in Frameworks */,
                                2774BE920F66F48200B65FC6 /* libz.dylib in Frameworks */,
-                               A906A0520F7A7B210007A827 /* AudioToolbox.framework in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                A25962E10F15077500B3BF4E /* Quartz.framework in Frameworks */,
                                A20F47010EBB5EC2005B861B /* QTKit.framework in Frameworks */,
                                4DD93FA4082036E8008E1322 /* OpenGL.framework in Frameworks */,
+                               A906A0510F7A7B210007A827 /* AudioToolbox.framework in Frameworks */,
                                4DD93FA3082036E8008E1322 /* IOKit.framework in Frameworks */,
                                A29E05800BE1283E000533F5 /* Growl.framework in Frameworks */,
                                A2D0A0AB0D3E5929002D57CB /* Sparkle.framework in Frameworks */,
                                2713E6420F676526002E0A01 /* libhb.a in Frameworks */,
+                               274DD20B0FEF10FD00881E69 /* libiconv.dylib in Frameworks */,
                                2774BEC70F66F61A00B65FC6 /* libbz2.dylib in Frameworks */,
                                2774BEC80F66F61A00B65FC6 /* libz.dylib in Frameworks */,
-                               A906A0510F7A7B210007A827 /* AudioToolbox.framework in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                089C165CFE840E0CC02AAC07 /* InfoPlist.strings */,
                                29B97323FDCFA39411CA2CEA /* Frameworks */,
                                19C28FACFE9D520D11CA2CBB /* Products */,
+                               274DD1E30FEF109900881E69 /* libiconv.dylib */,
                        );
                        name = HandBrake;
                        sourceTree = "<group>";
index 1c2a22e..9089166 100644 (file)
@@ -36,6 +36,7 @@ endif
 MODULES += contrib/x264
 
 ifneq (,$(filter $(BUILD.system),cygwin mingw))
+    MODULES += contrib/libiconv
     MODULES += contrib/zlib
 endif
 
index c803fcb..48f0c57 100644 (file)
@@ -16,6 +16,9 @@ TEST.libs = $(LIBHB.a) $(foreach n, \
 
 TEST.install.exe = $(PREFIX/)bin/$(notdir $(TEST.exe))
 
+ifeq (1,$(LIBICONV.enabled))
+    TEST.libs += $(CONTRIB.build/)lib/libiconv.a
+endif
 ifeq (1,$(BZIP2.enabled))
     TEST.libs += $(CONTRIB.build/)lib/libbz2.a
 endif
@@ -37,7 +40,7 @@ TEST.GCC.I += $(LIBHB.GCC.I)
 
 ifeq ($(BUILD.system),darwin)
     TEST.GCC.f += IOKit CoreServices AudioToolbox
-    TEST.GCC.l += bz2 z
+    TEST.GCC.l += iconv bz2 z
 else ifeq ($(BUILD.system),linux)
     TEST.GCC.l += bz2 z pthread dl m
 else ifeq (1-mingw,$(BUILD.cross)-$(BUILD.system))
index 54b1a7a..5e15c83 100644 (file)
@@ -72,6 +72,10 @@ static char ** subtracks   = NULL;
 static char ** subforce    = NULL;
 static char * subburn     = NULL;
 static char * subdefault  = NULL;
+static char ** srtfile     = NULL;
+static char ** srtcodeset  = NULL;
+static char ** srtoffset   = NULL;
+static char ** srtlang     = NULL;
 static int    subtitle_scan = 0;
 static int    width       = 0;
 static int    height      = 0;
@@ -1790,6 +1794,43 @@ static int HandleEvents( hb_handle_t * h )
                 }
             }
 
+            if( srtfile )
+            {
+                char * token;
+                int i, pos;
+                hb_subtitle_config_t sub_config;
+
+                pos = 0;
+                for( i=0; srtfile[i] != NULL; i++ )
+                {
+                    char *codeset = "L1";
+                    int64_t offset = 0;
+                    char *lang = "und";
+
+                    pos++;
+                    token = srtfile[i];
+                    if( srtcodeset && srtcodeset[i] )
+                    {
+                        codeset = srtcodeset[i];
+                    }
+                    if( srtoffset && srtoffset[i] )
+                    {
+                        offset = strtoll( srtoffset[i], &srtoffset[i], 0 );
+                    }
+                    if ( srtlang && srtlang[i] )
+                    {
+                        lang = srtlang[i];
+                    }
+                    sub_config.force = 0;
+                    sub_config.default_track = 0;
+                    strncpy( sub_config.src_filename, srtfile[i], 128);
+                    strncpy( sub_config.src_codeset, codeset, 40);
+                    sub_config.offset = offset;
+
+                    hb_srt_add( job, &sub_config, lang);
+                }
+            }
+
             if( native_language )
             {
                 char audio_lang[4];
@@ -2319,7 +2360,17 @@ static void ShowHelp()
     "                            that matches the --native-language. If there are no\n"
     "                            matching audio tracks then the first matching\n"
     "                            subtitle track is used instead.\n"
-
+    "        --srt-file <string> SubRip SRT filename(s), separated by commas.\n"
+    "        --srt-codeset       Character codeset(s) that the SRT file(s) are\n"
+    "          <string>          encoded in, separted by commas.\n"
+    "                            Use 'iconv -l' for a list of valid\n"
+    "                            codesets. If not specified latin1 is assumed\n"
+    "        --srt-offset        Offset in milli-seconds to apply to the SRT file(s)\n"
+    "          <string>          separted by commas. If not specified zero is assumed.\n"
+    "                            Offsets may be negative.\n"
+    "        --srt-lang <string> Language as an iso639-2 code fra, eng, spa et cetera)\n"
+    "                            for the SRT file(s) separated by commas. If not specified\n"
+    "                            then 'und' is used.\n"
     "\n"
 
 
@@ -2421,6 +2472,10 @@ static int ParseOptions( int argc, char ** argv )
     #define SUB_BURNED          266
     #define SUB_DEFAULT         267
     #define NATIVE_DUB          268
+    #define SRT_FILE            269
+    #define SRT_CODESET         270
+    #define SRT_OFFSET          271
+    #define SRT_LANG            272
     
     for( ;; )
     {
@@ -2451,9 +2506,12 @@ static int ParseOptions( int argc, char ** argv )
             { "subtitle-forced", optional_argument,   NULL,    'F' },
             { "subtitle-burned", optional_argument,   NULL,    SUB_BURNED },
             { "subtitle-default", optional_argument,   NULL,    SUB_DEFAULT },
+            { "srt-file",    required_argument, NULL, SRT_FILE },
+            { "srt-codeset", required_argument, NULL, SRT_CODESET },
+            { "srt-offset",  required_argument, NULL, SRT_OFFSET },
+            { "srt-lang",    required_argument, NULL, SRT_LANG },
             { "native-language", required_argument, NULL,'N' },
             { "native-dub",  no_argument,       NULL,    NATIVE_DUB },
-
             { "encoder",     required_argument, NULL,    'e' },
             { "aencoder",    required_argument, NULL,    'E' },
             { "two-pass",    no_argument,       NULL,    '2' },
@@ -2671,6 +2729,18 @@ static int ParseOptions( int argc, char ** argv )
             case NATIVE_DUB:
                 native_dub = 1;
                 break;
+            case SRT_FILE:
+                srtfile = str_split( optarg, "," );
+                break;
+            case SRT_CODESET:
+                srtcodeset = str_split( optarg, "," );
+                break;
+            case SRT_OFFSET:
+                srtoffset = str_split( optarg, "," );
+                break;
+            case SRT_LANG:
+                srtlang = str_split( optarg, "," );
+                break;
             case '2':
                 twoPass = 1;
                 break;