diff options
-rw-r--r-- | libhb/common.h | 1 | ||||
-rw-r--r-- | libhb/decavcodec.c | 69 | ||||
-rw-r--r-- | libhb/fifo.c | 17 | ||||
-rw-r--r-- | libhb/internal.h | 1 | ||||
-rw-r--r-- | libhb/scan.c | 48 |
5 files changed, 99 insertions, 37 deletions
diff --git a/libhb/common.h b/libhb/common.h index cf1dc02d8..69c6ddea0 100644 --- a/libhb/common.h +++ b/libhb/common.h @@ -436,6 +436,7 @@ struct hb_audio_s hb_esconfig_t config; hb_mux_data_t * mux_data; + hb_fifo_t * scan_cache; } priv; }; #endif diff --git a/libhb/decavcodec.c b/libhb/decavcodec.c index e083d517e..9f3196a85 100644 --- a/libhb/decavcodec.c +++ b/libhb/decavcodec.c @@ -389,44 +389,53 @@ static int decavcodecBSInfo( hb_work_object_t *w, const hb_buffer_t *buf, uint8_t *buffer = av_malloc( AVCODEC_MAX_AUDIO_FRAME_SIZE ); int out_size = AVCODEC_MAX_AUDIO_FRAME_SIZE; unsigned char *pbuffer; - int pos = 0, pbuffer_size; + int pos, pbuffer_size; - while ( pos < buf->size ) + while ( buf && !ret ) { - int len; - - if (parser != NULL ) - { - len = av_parser_parse2( parser, context, &pbuffer, &pbuffer_size, - buf->data + pos, buf->size - pos, - buf->start, buf->start, AV_NOPTS_VALUE ); - } - else + pos = 0; + while ( pos < buf->size ) { - pbuffer = buf->data; - len = pbuffer_size = buf->size; - } - pos += len; - if ( pbuffer_size > 0 ) - { - AVPacket avp; - av_init_packet( &avp ); - avp.data = pbuffer; - avp.size = pbuffer_size; + int len; - len = avcodec_decode_audio3( context, (int16_t*)buffer, &out_size, &avp ); - if ( len > 0 && context->sample_rate > 0 ) + if (parser != NULL ) { - info->bitrate = context->bit_rate; - info->rate = context->sample_rate; - info->rate_base = 1; - info->channel_layout = - hb_ff_layout_xlat(context->channel_layout, context->channels); - ret = 1; - break; + len = av_parser_parse2( parser, context, &pbuffer, + &pbuffer_size, buf->data + pos, + buf->size - pos, buf->start, + buf->start, AV_NOPTS_VALUE ); + } + else + { + pbuffer = buf->data; + len = pbuffer_size = buf->size; + } + pos += len; + if ( pbuffer_size > 0 ) + { + AVPacket avp; + av_init_packet( &avp ); + avp.data = pbuffer; + avp.size = pbuffer_size; + + len = avcodec_decode_audio3( context, (int16_t*)buffer, + &out_size, &avp ); + if ( len > 0 && context->sample_rate > 0 ) + { + info->bitrate = context->bit_rate; + info->rate = context->sample_rate; + info->rate_base = 1; + info->channel_layout = + hb_ff_layout_xlat(context->channel_layout, + context->channels); + ret = 1; + break; + } } } + buf = buf->next; } + av_free( buffer ); if ( parser != NULL ) av_parser_close( parser ); diff --git a/libhb/fifo.c b/libhb/fifo.c index c72b4e10b..3aeeea273 100644 --- a/libhb/fifo.c +++ b/libhb/fifo.c @@ -235,6 +235,23 @@ hb_fifo_t * hb_fifo_init( int capacity, int thresh ) return f; } +int hb_fifo_size_bytes( hb_fifo_t * f ) +{ + int ret = 0; + hb_buffer_t * link; + + hb_lock( f->lock ); + link = f->first; + while ( link ) + { + ret += link->size; + link = link->next; + } + hb_unlock( f->lock ); + + return ret; +} + int hb_fifo_size( hb_fifo_t * f ) { int ret; diff --git a/libhb/internal.h b/libhb/internal.h index 59753022e..7672c7311 100644 --- a/libhb/internal.h +++ b/libhb/internal.h @@ -87,6 +87,7 @@ void hb_buffer_copy_settings( hb_buffer_t * dst, hb_fifo_t * hb_fifo_init( int capacity, int thresh ); int hb_fifo_size( hb_fifo_t * ); +int hb_fifo_size_bytes( hb_fifo_t * ); int hb_fifo_is_full( hb_fifo_t * ); float hb_fifo_percent_full( hb_fifo_t * f ); hb_buffer_t * hb_fifo_get( hb_fifo_t * ); diff --git a/libhb/scan.c b/libhb/scan.c index e14e6712b..1ae5de007 100644 --- a/libhb/scan.c +++ b/libhb/scan.c @@ -30,7 +30,7 @@ typedef struct static void ScanFunc( void * ); static int DecodePreviews( hb_scan_t *, hb_title_t * title ); -static void LookForAudio( hb_title_t * title, hb_buffer_t * b ); +static int LookForAudio( hb_title_t * title, hb_buffer_t * b ); static int AllAudioOK( hb_title_t * title ); static const char *aspect_to_string( double aspect ) @@ -163,6 +163,11 @@ static void ScanFunc( void * _data ) free( audio ); continue; } + if ( audio->priv.scan_cache ) + { + hb_fifo_flush( audio->priv.scan_cache ); + hb_fifo_close( &audio->priv.scan_cache ); + } j++; } @@ -513,9 +518,11 @@ static int DecodePreviews( hb_scan_t * data, hb_title_t * title ) vid_buf = NULL; } } - else if( ! AllAudioOK( title ) ) + else { - LookForAudio( title, buf_es ); + if( ! AllAudioOK( title ) ) + if ( !LookForAudio( title, buf_es ) ) + buf_es = NULL; } if ( buf_es ) hb_buffer_close( &buf_es ); @@ -698,6 +705,15 @@ static int DecodePreviews( hb_scan_t * data, hb_title_t * title ) ++npreviews; skip_preview: + /* Make sure we found audio rates and bitrates */ + for( j = 0; j < hb_list_count( title->list_audio ); j++ ) + { + hb_audio_t * audio = hb_list_item( title->list_audio, j ); + if ( audio->priv.scan_cache ) + { + hb_fifo_flush( audio->priv.scan_cache ); + } + } if ( vid_buf ) hb_buffer_close( &vid_buf ); } @@ -809,7 +825,7 @@ skip_preview: * aren't (e.g., some European DVD Teletext streams use the same IDs as US ATSC * AC-3 audio). */ -static void LookForAudio( hb_title_t * title, hb_buffer_t * b ) +static int LookForAudio( hb_title_t * title, hb_buffer_t * b ) { int i; @@ -830,9 +846,20 @@ static void LookForAudio( hb_title_t * title, hb_buffer_t * b ) if( !audio || audio->config.in.bitrate != 0 ) { /* not found or already done */ - return; + return 1; } + if ( audio->priv.scan_cache == NULL ) + audio->priv.scan_cache = hb_fifo_init( 16, 16 ); + + if ( hb_fifo_size_bytes( audio->priv.scan_cache ) >= 4096 ) + { + hb_buffer_t * tmp; + tmp = hb_fifo_get( audio->priv.scan_cache ); + hb_buffer_close( &tmp ); + } + hb_fifo_push( audio->priv.scan_cache, b ); + hb_work_object_t *w = hb_codec_decoder( audio->config.in.codec ); if ( w == NULL || w->bsinfo == NULL ) @@ -845,6 +872,7 @@ static void LookForAudio( hb_title_t * title, hb_buffer_t * b ) hb_work_info_t info; w->audio = audio; w->codec_param = audio->config.in.codec_param; + b = hb_fifo_see( audio->priv.scan_cache ); int ret = w->bsinfo( w, b, &info ); if ( ret < 0 ) { @@ -856,8 +884,11 @@ static void LookForAudio( hb_title_t * title, hb_buffer_t * b ) if ( !info.bitrate ) { /* didn't find any info */ - return; + return 0; } + hb_fifo_flush( audio->priv.scan_cache ); + hb_fifo_close( &audio->priv.scan_cache ); + audio->config.in.samplerate = info.rate; audio->config.in.bitrate = info.bitrate; audio->config.in.channel_layout = info.channel_layout; @@ -886,7 +917,7 @@ static void LookForAudio( hb_title_t * title, hb_buffer_t * b ) audio->config.lang.description ); free( w ); - return; + return 1; // We get here if there's no hope of finding info on an audio bitstream, // either because we don't have a decoder (or a decoder with a bitstream @@ -898,7 +929,10 @@ static void LookForAudio( hb_title_t * title, hb_buffer_t * b ) if ( w ) free( w ); + hb_fifo_flush( audio->priv.scan_cache ); + hb_fifo_close( &audio->priv.scan_cache ); hb_list_rem( title->list_audio, audio ); + return -1; } /* |