uint8_t parse_history[6];
int parse_history_count;
int parse_last_mb;
+ int64_t reference_dts;
+ int last_frame_num, last_picture_structure;
} H264ParseContext;
return 0;
}
-static inline int get_avc_nalsize(H264ParseContext *p, const uint8_t *buf,
- int buf_size, int *buf_index, void *logctx)
-{
- int i, nalsize = 0;
-
- if (*buf_index >= buf_size - p->nal_length_size) {
- // the end of the buffer is reached, refill it
- return AVERROR(EAGAIN);
- }
-
- for (i = 0; i < p->nal_length_size; i++)
- nalsize = ((unsigned)nalsize << 8) | buf[(*buf_index)++];
- if (nalsize <= 0 || nalsize > buf_size - *buf_index) {
- av_log(logctx, AV_LOG_ERROR,
- "AVC: nal size %d\n", nalsize);
- return AVERROR_INVALIDDATA;
- }
- return nalsize;
-}
-
/**
* Parse NAL units of found picture and decode some basic information.
*
int src_length, consumed, nalsize = 0;
if (buf_index >= next_avc) {
- nalsize = get_avc_nalsize(p, buf, buf_size, &buf_index, avctx);
+ nalsize = get_nalsize(p->nal_length_size, buf, buf_size, &buf_index, avctx);
if (nalsize < 0)
break;
next_avc = buf_index + nalsize;
}
break;
}
- consumed = ff_h2645_extract_rbsp(buf + buf_index, src_length, &nal);
+ consumed = ff_h2645_extract_rbsp(buf + buf_index, src_length, &nal, 1);
if (consumed < 0)
break;
s->picture_structure = AV_PICTURE_STRUCTURE_TOP_FIELD;
else
s->picture_structure = AV_PICTURE_STRUCTURE_BOTTOM_FIELD;
- s->field_order = AV_FIELD_UNKNOWN;
+ if (p->poc.frame_num == p->last_frame_num &&
+ p->last_picture_structure != AV_PICTURE_STRUCTURE_UNKNOWN &&
+ p->last_picture_structure != AV_PICTURE_STRUCTURE_FRAME &&
+ p->last_picture_structure != s->picture_structure) {
+ if (p->last_picture_structure == AV_PICTURE_STRUCTURE_TOP_FIELD)
+ s->field_order = AV_FIELD_TT;
+ else
+ s->field_order = AV_FIELD_BB;
+ } else {
+ s->field_order = AV_FIELD_UNKNOWN;
+ }
+ p->last_picture_structure = s->picture_structure;
+ p->last_frame_num = p->poc.frame_num;
}
av_freep(&nal.rbsp_buffer);
s->flags &= PARSER_FLAG_COMPLETE_FRAMES;
}
+ if (s->dts_sync_point >= 0) {
+ int64_t den = avctx->time_base.den * (int64_t)avctx->pkt_timebase.num;
+ if (den > 0) {
+ int64_t num = avctx->time_base.num * (int64_t)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;
{
H264ParseContext *p = s->priv_data;
+ p->reference_dts = AV_NOPTS_VALUE;
+ p->last_frame_num = INT_MAX;
ff_h264dsp_init(&p->h264dsp, 8, 1);
return 0;
}