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"),
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"),
{
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);
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++;
}
// 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;
}
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
( 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 &&
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)
{
stream->ts_stream_type[esindx] = 0x81;
break;
+ case 0x7a: // DVB EAC-3 descriptor
+ stream->ts_stream_type[esindx] = 0x87;
+ break;
+
default:
break;
}
{
return 0;
}
- if ( av_find_stream_info( ic ) < 0 )
+ if ( hb_av_find_stream_info( ic ) < 0 )
goto fail;
stream->ffmpeg_ic = ic;
// 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
{
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
{
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;
}
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 );
}
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;
{
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 );
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;
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,
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.