diff options
author | jstebbins <[email protected]> | 2011-09-24 01:16:28 +0000 |
---|---|---|
committer | jstebbins <[email protected]> | 2011-09-24 01:16:28 +0000 |
commit | 3d237202e20af694df84ad73ae2f92145777c692 (patch) | |
tree | 90f63e58462878bbacec1fa3975db3c9411f3901 /libhb | |
parent | 442f8efade3df7a34c52441c982c93aeb66b29e5 (diff) |
fix framerate detection for AVCHD-Lite
The AVCHD-Lite specification only supports 50 or 60 fps. So to get
25 or 30 fps, they double every frame using repeat flags. Detect
this and adjust the framerate accordingly.
git-svn-id: svn://svn.handbrake.fr/HandBrake/trunk@4242 b64f7644-9d1e-0410-96f1-a4d463321fa5
Diffstat (limited to 'libhb')
-rw-r--r-- | libhb/decavcodec.c | 6 | ||||
-rw-r--r-- | libhb/internal.h | 2 | ||||
-rw-r--r-- | libhb/scan.c | 24 |
3 files changed, 27 insertions, 5 deletions
diff --git a/libhb/decavcodec.c b/libhb/decavcodec.c index 09ad0ce80..ce459d6e5 100644 --- a/libhb/decavcodec.c +++ b/libhb/decavcodec.c @@ -796,10 +796,14 @@ static int decodeFrame( hb_work_object_t *w, uint8_t *data, int size, int sequen { flags |= PIC_FLAG_PROGRESSIVE_FRAME; } - if ( frame.repeat_pict ) + if ( frame.repeat_pict == 1 ) { flags |= PIC_FLAG_REPEAT_FIRST_FIELD; } + if ( frame.repeat_pict == 2 ) + { + flags |= PIC_FLAG_REPEAT_FRAME; + } hb_buffer_t *buf; diff --git a/libhb/internal.h b/libhb/internal.h index 6f6420a56..77ead967c 100644 --- a/libhb/internal.h +++ b/libhb/internal.h @@ -384,6 +384,8 @@ enum #define PIC_FLAG_PROGRESSIVE_FRAME 16 #endif +#define PIC_FLAG_REPEAT_FRAME 512 + extern hb_work_object_t * hb_objects; #define HB_WORK_IDLE 0 diff --git a/libhb/scan.c b/libhb/scan.c index 73b39e376..8cf324678 100644 --- a/libhb/scan.c +++ b/libhb/scan.c @@ -489,6 +489,7 @@ static int DecodePreviews( hb_scan_t * data, hb_title_t * title ) hb_list_t * list_es; int progressive_count = 0; int pulldown_count = 0; + int doubled_frame_count = 0; int interlaced_preview_count = 0; info_list_t * info_list = calloc( data->preview_count+1, sizeof(*info_list) ); crop_record_t *crops = calloc( 1, sizeof(*crops) ); @@ -670,6 +671,14 @@ static int DecodePreviews( hb_scan_t * data, hb_title_t * title ) pulldown_count++; } + if( vid_buf->s.flags & PIC_FLAG_REPEAT_FRAME ) + { + // AVCHD-Lite specifies that all streams are + // 50 or 60 fps. To produce 25 or 30 fps, camera + // makers are repeating all frames. + doubled_frame_count++; + } + if( is_close_to( vid_info.rate_base, 1126125, 100 ) ) { // Frame FPS is 23.976 (meaning it's progressive), so start keeping @@ -818,23 +827,30 @@ skip_preview: title->height = vid_info.height; if ( vid_info.rate && vid_info.rate_base ) { + title->rate = vid_info.rate; + title->rate_base = vid_info.rate_base; if( is_close_to( vid_info.rate_base, 900900, 100 ) ) { if( pulldown_count >= npreviews / 3 ) { - vid_info.rate_base = 1126125; + title->rate_base = 1126125; hb_deep_log( 2, "Pulldown detected, setting fps to 23.976" ); } if( progressive_count >= npreviews / 2 ) { // We've already deduced that the frame rate is 23.976, // so set it back again. - vid_info.rate_base = 1126125; + title->rate_base = 1126125; hb_deep_log( 2, "Title's mostly NTSC Film, setting fps to 23.976" ); } } - title->rate = vid_info.rate; - title->rate_base = vid_info.rate_base; + if( doubled_frame_count >= 3 * npreviews / 4 ) + { + // We've detected that a significant number of the frames + // have been doubled in duration by repeat flags. + title->rate_base = 2 * vid_info.rate_base; + hb_deep_log( 2, "Repeat frames detected, setting fps to %.3f", (float)title->rate / title->rate_base ); + } } title->video_bitrate = vid_info.bitrate; |