OSDN Git Service

CLI: remove 'L' from short opts so that getopt_long properly flags it as an invalid...
[handbrake-jp/handbrake-jp-git.git] / libhb / stream.c
index 95bf719..24093e6 100644 (file)
@@ -2832,9 +2832,6 @@ static void add_ffmpeg_audio( hb_title_t *title, hb_stream_t *stream, int id )
 }
 
 /*
- * Parses the 'subtitle->palette' information from the specific VOB subtitle track's private data.
- * Returns 0 if successful or 1 if parsing failed or was incomplete.
- * 
  * Format:
  *   MkvVobSubtitlePrivateData = ( Line )*
  *   Line = FieldName ':' ' ' FieldValue '\n'
@@ -2847,11 +2844,8 @@ static void add_ffmpeg_audio( hb_title_t *title, hb_stream_t *stream, int id )
  * More information on the format at:
  *   http://www.matroska.org/technical/specs/subtitles/images.html
  */
-static int ffmpeg_parse_vobsub_extradata( AVCodecContext *codec, hb_subtitle_t *subtitle )
+static int ffmpeg_parse_vobsub_extradata_mkv( AVCodecContext *codec, hb_subtitle_t *subtitle )
 {
-    if ( codec->extradata_size <= 0 )
-        return 1;
-    
     // lines = (string) codec->extradata;
     char *lines = malloc( codec->extradata_size + 1 );
     if ( lines == NULL )
@@ -2861,26 +2855,46 @@ static int ffmpeg_parse_vobsub_extradata( AVCodecContext *codec, hb_subtitle_t *
     
     uint32_t rgb[16];
     int gotPalette = 0;
+    int gotDimensions = 0;
     
     char *curLine, *curLine_parserData;
     for ( curLine = strtok_r( lines, "\n", &curLine_parserData );
           curLine;
           curLine = strtok_r( NULL, "\n", &curLine_parserData ) )
     {
-        int numElementsRead = sscanf(curLine, "palette: "
-            "%06x, %06x, %06x, %06x, "
-            "%06x, %06x, %06x, %06x, "
-            "%06x, %06x, %06x, %06x, "
-            "%06x, %06x, %06x, %06x",
-            &rgb[0],  &rgb[1],  &rgb[2],  &rgb[3],
-            &rgb[4],  &rgb[5],  &rgb[6],  &rgb[7],
-            &rgb[8],  &rgb[9],  &rgb[10], &rgb[11],
-            &rgb[12], &rgb[13], &rgb[14], &rgb[15]);
-        
-        if (numElementsRead == 16) {
-            gotPalette = 1;
-            break;
+        if (!gotPalette)
+        {
+            int numElementsRead = sscanf(curLine, "palette: "
+                "%06x, %06x, %06x, %06x, "
+                "%06x, %06x, %06x, %06x, "
+                "%06x, %06x, %06x, %06x, "
+                "%06x, %06x, %06x, %06x",
+                &rgb[0],  &rgb[1],  &rgb[2],  &rgb[3],
+                &rgb[4],  &rgb[5],  &rgb[6],  &rgb[7],
+                &rgb[8],  &rgb[9],  &rgb[10], &rgb[11],
+                &rgb[12], &rgb[13], &rgb[14], &rgb[15]);
+
+            if (numElementsRead == 16) {
+                gotPalette = 1;
+            }
         }
+        if (!gotDimensions)
+        {
+            int numElementsRead = sscanf(curLine, "size: %dx%d",
+                &subtitle->width, &subtitle->height);
+
+            if (numElementsRead == 2) {
+                gotDimensions = 1;
+            }
+        }
+        if (gotPalette && gotDimensions)
+            break;
+    }
+
+    if (subtitle->width == 0 || subtitle->height == 0)
+    {
+        subtitle->width = 720;
+        subtitle->height = 480;
     }
     
     free( lines );
@@ -2898,6 +2912,47 @@ static int ffmpeg_parse_vobsub_extradata( AVCodecContext *codec, hb_subtitle_t *
     }
 }
 
+/*
+ * Format: 8-bit {0,Y,Cb,Cr} x 16
+ */
+static int ffmpeg_parse_vobsub_extradata_mp4( AVCodecContext *codec, hb_subtitle_t *subtitle )
+{
+    if ( codec->extradata_size != 4*16 )
+        return 1;
+    
+    int i, j;
+    for ( i=0, j=0; i<16; i++, j+=4 )
+    {
+        subtitle->palette[i] = 
+            codec->extradata[j+1] << 16 |   // Y
+            codec->extradata[j+2] << 8  |   // Cb
+            codec->extradata[j+3] << 0;     // Cr
+    }
+    if (codec->width <= 0 || codec->height <= 0)
+    {
+        subtitle->width = 720;
+        subtitle->height = 480;
+    }
+    else
+    {
+        subtitle->width = codec->width;
+        subtitle->height = codec->height;
+    }
+    return 0;
+}
+
+/*
+ * Parses the 'subtitle->palette' information from the specific VOB subtitle track's private data.
+ * Returns 0 if successful or 1 if parsing failed or was incomplete.
+ */
+static int ffmpeg_parse_vobsub_extradata( AVCodecContext *codec, hb_subtitle_t *subtitle )
+{
+    // XXX: Better if we actually chose the correct parser based on the input container
+    return
+        ffmpeg_parse_vobsub_extradata_mkv( codec, subtitle ) &&
+        ffmpeg_parse_vobsub_extradata_mp4( codec, subtitle );
+}
+
 static void add_ffmpeg_subtitle( hb_title_t *title, hb_stream_t *stream, int id )
 {
     AVStream *st = stream->ffmpeg_ic->streams[id];
@@ -2927,14 +2982,11 @@ static void add_ffmpeg_subtitle( hb_title_t *title, hb_stream_t *stream, int id
             subtitle->source = TX3GSUB;
             subtitle->config.dest = PASSTHRUSUB;
             break;
-        // TODO(davidfstr): implement SSA subtitle support
-        /*
         case CODEC_ID_SSA:
             subtitle->format = TEXTSUB;
             subtitle->source = SSASUB;
             subtitle->config.dest = PASSTHRUSUB;
             break;
-        */
         default:
             hb_log( "add_ffmpeg_subtitle: unknown subtitle stream type: 0x%x", (int) codec->codec_id );
             free(subtitle);
@@ -3207,6 +3259,10 @@ static int ffmpeg_read( hb_stream_t *stream, hb_buffer_t *buf )
      * VOB subtitles (CODEC_ID_DVD_SUBTITLE) do not have their duration stored in
      * either field. This is not a problem because the VOB decoder can extract this
      * information from the packet payload itself.
+     * 
+     * SSA subtitles (CODEC_ID_SSA) do not have their duration stored in
+     * either field. This is not a problem because the SSA decoder can extract this
+     * information from the packet payload itself.
      */
     enum CodecID ffmpeg_pkt_codec = stream->ffmpeg_ic->streams[stream->ffmpeg_pkt->stream_index]->codec->codec_id;
     if ( ffmpeg_pkt_codec == CODEC_ID_TEXT ) {