summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjstebbins <[email protected]>2014-10-02 21:05:08 +0000
committerjstebbins <[email protected]>2014-10-02 21:05:08 +0000
commit7265c862c042e81f0b86e7df8b58ee69d9cb9e83 (patch)
tree9289bb66d25218890c73331c55f91dedb57688a0
parent9254fa47939e055f39f1cd5f8db52268d498558d (diff)
libhb: improve preview generateion when there are no IDRs
Puts the decoder into a mode that returns *all* frames. I.e. it won't just scan to the end of the file looking for an IDR. Then we decode multiple frames (up to 100) searching for an I frame. This way, the reconstructed frame we use for a preview is more likely to be complete. git-svn-id: svn://svn.handbrake.fr/HandBrake/trunk@6430 b64f7644-9d1e-0410-96f1-a4d463321fa5
-rw-r--r--libhb/bd.c1
-rw-r--r--libhb/decavcodec.c25
-rw-r--r--libhb/scan.c17
-rw-r--r--libhb/stream.c4
4 files changed, 42 insertions, 5 deletions
diff --git a/libhb/bd.c b/libhb/bd.c
index 6cef95609..06d4feaef 100644
--- a/libhb/bd.c
+++ b/libhb/bd.c
@@ -350,7 +350,6 @@ hb_title_t * hb_bd_title_scan( hb_bd_t * d, int tt, uint64_t min_duration )
case BLURAY_STREAM_TYPE_VIDEO_H264:
title->video_codec = WORK_DECAVCODECV;
title->video_codec_param = AV_CODEC_ID_H264;
- title->flags |= HBTF_NO_IDR;
break;
default:
diff --git a/libhb/decavcodec.c b/libhb/decavcodec.c
index e235111d8..4eb9f6947 100644
--- a/libhb/decavcodec.c
+++ b/libhb/decavcodec.c
@@ -1149,6 +1149,20 @@ static hb_buffer_t * cc_fill_buffer(hb_work_private_t *pv, uint8_t *cc, int size
return buf;
}
+static int get_frame_type(int type)
+{
+ switch(type)
+ {
+ case AV_PICTURE_TYPE_I:
+ return HB_FRAME_I;
+ case AV_PICTURE_TYPE_B:
+ return HB_FRAME_B;
+ case AV_PICTURE_TYPE_P:
+ return HB_FRAME_P;
+ }
+ return 0;
+}
+
/*
* Decodes a video frame from the specified raw packet data
* ('data', 'size', 'sequence').
@@ -1315,6 +1329,7 @@ static int decodeFrame( hb_work_object_t *w, uint8_t *data, int size, int sequen
{
flags |= PIC_FLAG_REPEAT_FRAME;
}
+ int frametype = get_frame_type(pv->frame->pict_type);
// Check for CC data
AVFrameSideData *sd;
@@ -1385,6 +1400,7 @@ static int decodeFrame( hb_work_object_t *w, uint8_t *data, int size, int sequen
buf->sequence = sequence;
buf->s.flags = flags;
+ buf->s.frametype = frametype;
if ( pv->new_chap && buf->s.start >= pv->chap_time )
{
@@ -1451,6 +1467,7 @@ static int decodeFrame( hb_work_object_t *w, uint8_t *data, int size, int sequen
buf->sequence = sequence;
/* Store picture flags for later use by filters */
buf->s.flags = flags;
+ buf->s.frametype = frametype;
pv->delayq[slot] = buf;
heap_push( &pv->pts_heap, pts );
@@ -1654,6 +1671,10 @@ static int decavcodecvInit( hb_work_object_t * w, hb_job_t * job )
// Set encoder opts...
AVDictionary * av_opts = NULL;
av_dict_set( &av_opts, "refcounted_frames", "1", 0 );
+ if (pv->title->flags & HBTF_NO_IDR)
+ {
+ av_dict_set( &av_opts, "flags", "output_corrupt", 0 );
+ }
if ( hb_avcodec_open( pv->context, codec, &av_opts, pv->threads ) )
{
@@ -1818,6 +1839,10 @@ static int decavcodecvWork( hb_work_object_t * w, hb_buffer_t ** buf_in,
AVDictionary * av_opts = NULL;
av_dict_set( &av_opts, "refcounted_frames", "1", 0 );
+ if (pv->title->flags & HBTF_NO_IDR)
+ {
+ av_dict_set( &av_opts, "flags", "output_corrupt", 0 );
+ }
// disable threaded decoding for scan, can cause crashes
if ( hb_avcodec_open( pv->context, codec, &av_opts, pv->threads ) )
diff --git a/libhb/scan.c b/libhb/scan.c
index 5726e8a5d..08b8e9e24 100644
--- a/libhb/scan.c
+++ b/libhb/scan.c
@@ -493,6 +493,7 @@ static int DecodePreviews( hb_scan_t * data, hb_title_t * title, int flush )
int pulldown_count = 0;
int doubled_frame_count = 0;
int interlaced_preview_count = 0;
+ int frame_wait = 0;
hb_stream_t * stream = NULL;
info_list_t * info_list = calloc( data->preview_count+1, sizeof(*info_list) );
crop_record_t *crops = crop_record_init( data->preview_count );
@@ -590,6 +591,10 @@ static int DecodePreviews( hb_scan_t * data, hb_title_t * title, int flush )
if (flush && vid_decoder->flush)
vid_decoder->flush( vid_decoder );
+ if (title->flags & HBTF_NO_IDR)
+ {
+ frame_wait = 100;
+ }
hb_buffer_t * vid_buf = NULL;
@@ -660,6 +665,18 @@ static int DecodePreviews( hb_scan_t * data, hb_title_t * title, int flush )
if( buf_es->s.id == title->video_id && vid_buf == NULL )
{
vid_decoder->work( vid_decoder, &buf_es, &vid_buf );
+ if (vid_buf != NULL && frame_wait)
+ {
+ if (vid_buf->s.frametype != HB_FRAME_I)
+ {
+ hb_buffer_close(&vid_buf);
+ frame_wait--;
+ }
+ else
+ {
+ frame_wait = 0;
+ }
+ }
}
else if( ! AllAudioOK( title ) )
{
diff --git a/libhb/stream.c b/libhb/stream.c
index 5b59c44db..0d1bec226 100644
--- a/libhb/stream.c
+++ b/libhb/stream.c
@@ -1098,7 +1098,6 @@ hb_title_t * hb_stream_title_scan(hb_stream_t *stream, hb_title_t * title)
chapter->seconds = title->seconds;
hb_list_add( title->list_chapter, chapter );
-
if ( stream->has_IDRs < 1 )
{
hb_log( "stream doesn't seem to have video IDR frames" );
@@ -5440,9 +5439,6 @@ static hb_title_t *ffmpeg_title_scan( hb_stream_t *stream, hb_title_t *title )
title->pixel_aspect_height = ic->streams[i]->sample_aspect_ratio.den;
}
- if ( context->codec_id == AV_CODEC_ID_H264 )
- title->flags |= HBTF_NO_IDR;
-
title->video_codec = WORK_DECAVCODECV;
title->video_codec_param = context->codec_id;
}