summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libhb/common.h1
-rw-r--r--libhb/decavcodec.c69
-rw-r--r--libhb/fifo.c17
-rw-r--r--libhb/internal.h1
-rw-r--r--libhb/scan.c48
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;
}
/*