summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorvan <[email protected]>2008-09-15 06:51:18 +0000
committervan <[email protected]>2008-09-15 06:51:18 +0000
commit357a1d943389cb3c76bf3a2c412b6e86bf646cf7 (patch)
treef36fe44de1355c998bd9a37bdb9d827479a81fe9
parenta5b76eee9e6637f26e4a60201e3d4bb77ab8ad72 (diff)
If we always sort timestamps we can't detect & correct misordering caused by an SCR discontinuity. So only sort timestamps on streams that could have been broken by Microsoft (ffmpeg avi, wmv, mkv & mp4) and leave mpeg PS, TS & M2TS steams alone.
git-svn-id: svn://svn.handbrake.fr/HandBrake/trunk@1699 b64f7644-9d1e-0410-96f1-a4d463321fa5
-rw-r--r--libhb/decavcodec.c42
1 files changed, 26 insertions, 16 deletions
diff --git a/libhb/decavcodec.c b/libhb/decavcodec.c
index f6bffc089..63ed879ac 100644
--- a/libhb/decavcodec.c
+++ b/libhb/decavcodec.c
@@ -92,21 +92,22 @@ typedef struct {
struct hb_work_private_s
{
- hb_job_t *job;
- AVCodecContext *context;
+ hb_job_t *job;
+ AVCodecContext *context;
AVCodecParserContext *parser;
- hb_list_t *list;
- double duration; // frame duration (for video)
- double pts_next; // next pts we expect to generate
- int64_t pts; // (video) pts passing from parser to decoder
- int64_t chap_time; // time of next chap mark (if new_chap != 0)
- int new_chap;
- uint32_t nframes;
- uint32_t ndrops;
- uint32_t decode_errors;
- hb_buffer_t* delayq[HEAP_SIZE];
- pts_heap_t pts_heap;
- void* buffer;
+ hb_list_t *list;
+ double duration; // frame duration (for video)
+ double pts_next; // next pts we expect to generate
+ int64_t pts; // (video) pts passing from parser to decoder
+ int64_t chap_time; // time of next chap mark (if new_chap != 0)
+ int new_chap; // output chapter mark pending
+ uint32_t nframes;
+ uint32_t ndrops;
+ uint32_t decode_errors;
+ int brokenByMicrosoft; // video stream may contain packed b-frames
+ hb_buffer_t* delayq[HEAP_SIZE];
+ pts_heap_t pts_heap;
+ void* buffer;
};
static int64_t heap_pop( pts_heap_t *heap )
@@ -498,8 +499,9 @@ static int decodeFrame( hb_work_private_t *pv, uint8_t *data, int size )
hb_buffer_t *buf;
- // if we're doing a scan we don't worry about timestamp reordering
- if ( ! pv->job )
+ // if we're doing a scan or this content couldn't have been broken
+ // by Microsoft we don't worry about timestamp reordering
+ if ( ! pv->job || ! pv->brokenByMicrosoft )
{
buf = copy_frame( pv->context, &frame );
buf->start = pts;
@@ -806,6 +808,14 @@ static void init_ffmpeg_context( hb_work_object_t *w )
// we have to wrap ffmpeg's get_buffer to be able to set the pts (?!)
pv->context->opaque = pv;
pv->context->get_buffer = get_frame_buf;
+
+ // avi, mkv and possibly mp4 containers can contain the M$ VFW packed
+ // b-frames abortion that messes up frame ordering and timestamps.
+ // XXX ffmpeg knows which streams are broken but doesn't expose the
+ // info externally. We should patch ffmpeg to add a flag to the
+ // codec context for this but until then we mark all ffmpeg streams
+ // as suspicious.
+ pv->brokenByMicrosoft = 1;
}
static void prepare_ffmpeg_buffer( hb_buffer_t * in )