avcodec/h264_parser: set missing pts for top/bottom field frames
authorPaul B Mahol <onemda@gmail.com>
Wed, 14 Sep 2016 14:35:48 +0000 (16:35 +0200)
committerPaul B Mahol <onemda@gmail.com>
Wed, 14 Sep 2016 18:32:24 +0000 (20:32 +0200)
Adopted from 4eb49fdde8f84d54a763cfb5d355527b525ee2bf revert.

Signed-off-by: Paul B Mahol <onemda@gmail.com>
libavcodec/h264_parser.c

index 615884f..4dacb22 100644 (file)
@@ -60,6 +60,7 @@ typedef struct H264ParseContext {
     uint8_t parse_history[6];
     int parse_history_count;
     int parse_last_mb;
+    int64_t reference_dts;
 } H264ParseContext;
 
 
@@ -598,6 +599,26 @@ static int h264_parse(AVCodecParserContext *s,
         s->flags &= PARSER_FLAG_COMPLETE_FRAMES;
     }
 
+    if (s->dts_sync_point >= 0) {
+        int64_t den = avctx->time_base.den * avctx->pkt_timebase.num;
+        if (den > 0) {
+            int64_t num = avctx->time_base.num * avctx->pkt_timebase.den;
+            if (s->dts != AV_NOPTS_VALUE) {
+                // got DTS from the stream, update reference timestamp
+                p->reference_dts = s->dts - av_rescale(s->dts_ref_dts_delta, num, den);
+            } else if (p->reference_dts != AV_NOPTS_VALUE) {
+                // compute DTS based on reference timestamp
+                s->dts = p->reference_dts + av_rescale(s->dts_ref_dts_delta, num, den);
+            }
+
+            if (p->reference_dts != AV_NOPTS_VALUE && s->pts == AV_NOPTS_VALUE)
+                s->pts = s->dts + av_rescale(s->pts_dts_delta, num, den);
+
+            if (s->dts_sync_point > 0)
+                p->reference_dts = s->dts; // new reference
+        }
+    }
+
     *poutbuf      = buf;
     *poutbuf_size = buf_size;
     return next;
@@ -655,6 +676,7 @@ static av_cold int init(AVCodecParserContext *s)
 {
     H264ParseContext *p = s->priv_data;
 
+    p->reference_dts = AV_NOPTS_VALUE;
     ff_h264dsp_init(&p->h264dsp, 8, 1);
     return 0;
 }