OSDN Git Service

bump ffmpeg from git-185a155 to git-0b32da9
[handbrake-jp/handbrake-jp-git.git] / libhb / stream.c
index 58b2506..4c11841 100644 (file)
@@ -58,11 +58,7 @@ static const stream2codec_t st2codec[256] = {
     st(0x0e, N, 0,                 0,              "ISO 13818-1 auxiliary"),
     st(0x0f, A, HB_ACODEC_MPGA,    CODEC_ID_AAC,   "ISO 13818-7 AAC Audio"),
     st(0x10, V, WORK_DECAVCODECV,  CODEC_ID_MPEG4, "MPEG4"),
-#if defined(OLD_LATM_PATCH)
     st(0x11, A, HB_ACODEC_MPGA,    CODEC_ID_AAC_LATM, "MPEG4 LATM AAC"),
-#else
-    st(0x11, N, 0,                 0,              "MPEG4 LATM AAC"),
-#endif
     st(0x12, U, 0,                 0,              "MPEG4 generic"),
 
     st(0x14, N, 0,                 0,              "ISO 13818-6 DSM-CC download"),
@@ -72,11 +68,11 @@ static const stream2codec_t st2codec[256] = {
     st(0x80, N, HB_ACODEC_MPGA,    CODEC_ID_PCM_BLURAY, "DigiCipher II Video"),
     st(0x81, A, HB_ACODEC_AC3,     0,              "AC-3"),
     st(0x82, A, HB_ACODEC_DCA,     0,              "HDMV DTS"),
-    st(0x83, A, HB_ACODEC_LPCM,    0,              "LPCM"),
-    st(0x84, A, 0,                 0,              "SDDS"),
+    st(0x83, A, HB_ACODEC_LPCM,    0,              "LPCM/TrueHD"),
+    st(0x84, A, 0,                 0,              "SDDS/EAC3"),
     st(0x85, U, 0,                 0,              "ATSC Program ID"),
     st(0x86, A, HB_ACODEC_DCA,     0,              "DTS-HD"),
-    st(0x87, A, 0,                 0,              "E-AC-3"),
+    st(0x87, A, HB_ACODEC_MPGA,    CODEC_ID_EAC3,  "EAC3"),
 
     st(0x8a, A, HB_ACODEC_DCA,     0,              "DTS"),
 
@@ -390,7 +386,7 @@ static int hb_stream_check_for_ps(hb_stream_t *stream)
 {
     uint8_t buf[2048*4];
     uint8_t sc_buf[4];
-    int pos;
+    int pos = 0;
     int hits = 0;
 
     fseek(stream->file_handle, 0, SEEK_SET);
@@ -699,6 +695,14 @@ hb_stream_t * hb_bd_stream_open( hb_title_t *title )
             d->ts_multiplexed[d->ts_number_pids] = 0x71;
             d->ts_stream_type[d->ts_number_pids] = 0x82;
         }
+        if ( d->ts_stream_type[d->ts_number_pids] == 0x84 &&
+             title->reg_desc == STR4_TO_UINT32("HDMV") )
+        {
+            // EAC3 audio in bluray has an stype of 0x84
+            // which conflicts with SDDS
+            // To distinguish, Bluray streams have a reg_desc of HDMV
+            d->ts_stream_type[d->ts_number_pids] = 0x87;
+        }
 
         d->ts_number_pids++;
     }
@@ -1457,7 +1461,7 @@ int hb_stream_seek_chapter( hb_stream_t * stream, int chapter_num )
         // that causes the problem. since hb_stream_seek_chapter
         // is called before we start reading, make sure
         // we do a seek here.
-        av_seek_frame( stream->ffmpeg_ic, -1, ffmpeg_initial_timestamp( stream ), AVSEEK_FLAG_BACKWARD );
+        av_seek_frame( stream->ffmpeg_ic, -1, ffmpeg_initial_timestamp( stream ), AVSEEK_FLAG_BACKWARD | AVSEEK_FLAG_ANY );
     }
     return 1;
 }
@@ -1536,21 +1540,6 @@ int hb_stream_seek_ts( hb_stream_t * stream, int64_t ts )
     return -1;
 }
 
-static const char* make_upper( const char* s )
-{
-    static char name[8];
-    char *cp = name;
-    char *ep = cp + sizeof(name)-1;
-
-    while ( *s && cp < ep )
-    {
-        *cp++ = islower(*s)? toupper(*s) : *s;
-        ++s;
-    }
-    *cp = 0;
-    return name;
-}
-
 static void set_audio_description( hb_audio_t *audio, iso639_lang_t *lang )
 {
     /* XXX
@@ -1566,10 +1555,18 @@ static void set_audio_description( hb_audio_t *audio, iso639_lang_t *lang )
          ( cc = hb_ffmpeg_context( audio->config.in.codec_param ) ) &&
          avcodec_find_decoder( cc->codec_id ) )
     {
-        codec_name = make_upper( avcodec_find_decoder( cc->codec_id )->name );
-        if ( !strcmp( codec_name, "LIBFAAD" ) )
+        AVCodec *codec = avcodec_find_decoder( cc->codec_id );
+        codec_name = codec->name;
+        if ( !strcmp( codec_name, "DCA" ) )
+        {
+            codec_name = "DTS";
+        }
+
+        char *profile_name;
+        profile_name = av_get_profile_name( codec, cc->profile );
+        if ( profile_name )
         {
-            codec_name = "AAC";
+            codec_name = profile_name;
         }
     }
     else if ( audio->config.in.codec == HB_ACODEC_MPGA &&
@@ -1684,6 +1681,16 @@ static hb_audio_t *hb_ts_stream_set_audio_id_and_codec(hb_stream_t *stream,
                 stream->ts_stream_type[idx] = 0x82;
                 kind = A;
             }
+            if ( stype == 0x84 && 
+                 stream->pmt_info.reg_desc == STR4_TO_UINT32("HDMV") )
+            {
+                // EAC3 audio in bluray has an stype of 0x84
+                // which conflicts with SDDS
+                // To distinguish, Bluray streams have a reg_desc of HDMV
+                stype = 0x87;
+                stream->ts_stream_type[idx] = 0x87;
+                kind = A;
+            }
         }
         else if ((buf[3] & 0xe0) == 0xc0)
         {
@@ -1980,6 +1987,10 @@ static void decode_element_descriptors(hb_stream_t* stream, int esindx,
                 stream->ts_stream_type[esindx] = 0x81;
                 break;
 
+            case 0x7a:  // DVB EAC-3 descriptor
+                stream->ts_stream_type[esindx] = 0x87;
+                break;
+
             default:
                 break;
         }
@@ -2909,7 +2920,7 @@ static int ffmpeg_open( hb_stream_t *stream, hb_title_t *title )
     {
         return 0;
     }
-    if ( av_find_stream_info( ic ) < 0 )
+    if ( hb_av_find_stream_info( ic ) < 0 )
         goto fail;
 
     stream->ffmpeg_ic = ic;
@@ -2931,7 +2942,7 @@ static int ffmpeg_open( hb_stream_t *stream, hb_title_t *title )
         // we're opening for scan. let ffmpeg put some info into the
         // log about what we've got.
         av_log_set_level( AV_LOG_INFO );
-        dump_format( ic, 0, stream->path, 0 );
+        av_dump_format( ic, 0, stream->path, 0 );
         av_log_set_level( AV_LOG_ERROR );
 
         // accept this file if it has at least one video stream we can decode
@@ -2975,6 +2986,7 @@ static void add_ffmpeg_audio( hb_title_t *title, hb_stream_t *stream, int id )
 {
     AVStream *st = stream->ffmpeg_ic->streams[id];
     AVCodecContext *codec = st->codec;
+    AVMetadataTag *tag;
     int layout;
 
     // scan will ignore any audio without a bitrate. Since we've already
@@ -2995,7 +3007,10 @@ static void add_ffmpeg_audio( hb_title_t *title, hb_stream_t *stream, int id )
         {
             audio->config.in.codec = HB_ACODEC_AC3;
         }
-        else if ( codec->codec_id == CODEC_ID_DTS )
+        else if ( codec->codec_id == CODEC_ID_DTS &&
+                ( codec->profile == FF_PROFILE_DTS ||
+                  codec->profile == FF_PROFILE_DTS_ES ||
+                  codec->profile == FF_PROFILE_DTS_96_24 ) )
         {
             audio->config.in.codec = HB_ACODEC_DCA;
         }
@@ -3009,7 +3024,9 @@ static void add_ffmpeg_audio( hb_title_t *title, hb_stream_t *stream, int id )
             audio->config.in.channel_layout = layout;
         }
 
-        set_audio_description( audio, lang_for_code2( st->language ) );
+        tag = av_metadata_get( st->metadata, "language", NULL, 0 );
+        set_audio_description( audio, 
+            lang_for_code2( tag ? tag->value : "und" ) );
 
         hb_list_add( title->list_audio, audio );
     }
@@ -3177,13 +3194,63 @@ static void add_ffmpeg_subtitle( hb_title_t *title, hb_stream_t *stream, int id
             return;
     }
     
-    iso639_lang_t *language = lang_for_code2( st->language );
+    AVMetadataTag *tag;
+    iso639_lang_t *language;
+
+    tag = av_metadata_get( st->metadata, "language", NULL, 0 );
+    language = lang_for_code2( tag ? tag->value : "und" );
     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 +3311,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 );
@@ -3258,6 +3329,7 @@ static hb_title_t *ffmpeg_title_scan( hb_stream_t *stream )
         for( i = 0; i < ic->nb_chapters; i++ )
             if( ( m = ic->chapters[i] ) != NULL )
             {
+                AVMetadataTag *tag;
                 hb_chapter_t * chapter;
                 chapter = calloc( sizeof( hb_chapter_t ), 1 );
                 chapter->index    = i+1;
@@ -3266,7 +3338,8 @@ static hb_title_t *ffmpeg_title_scan( hb_stream_t *stream )
                 chapter->hours    = chapter->duration / 90000 / 3600;
                 chapter->minutes  = ( ( chapter->duration / 90000 ) % 3600 ) / 60;
                 chapter->seconds  = ( chapter->duration / 90000 ) % 60;
-                strcpy( chapter->title, m->title );
+                tag = av_metadata_get( m->metadata, "title", NULL, 0 );
+                strcpy( chapter->title, tag ? tag->value : "" );
                 hb_deep_log( 2, "Added chapter %i, name='%s', dur=%"PRIu64", (%02i:%02i:%02i)",
                             chapter->index, chapter->title,
                             chapter->duration, chapter->hours,
@@ -3355,6 +3428,12 @@ static int ffmpeg_read( hb_stream_t *stream, hb_buffer_t *buf )
   again:
     if ( ( err = av_read_frame( stream->ffmpeg_ic, stream->ffmpeg_pkt )) < 0 )
     {
+        // av_read_frame can return EAGAIN.  In this case, it expects
+        // to be called again to get more data.
+        if ( err == AVERROR(EAGAIN) )
+        {
+            goto again;
+        }
         // XXX the following conditional is to handle avi files that
         // use M$ 'packed b-frames' and occasionally have negative
         // sizes for the null frames these require.