static int h264_parse(AVCodecParserContext *s, AVCodecContext *avctx, const uint8_t **poutbuf, int *poutbuf_size, const uint8_t *buf, int buf_size) { H264ParseContext *p = s->priv_data; ParseContext *pc = &p->pc; int next; if (!p->got_first) { p->got_first = 1; if (avctx->extradata_size) { ff_h264_decode_extradata(avctx->extradata, avctx->extradata_size, &p->ps, &p->is_avc, &p->nal_length_size, avctx->err_recognition, avctx); } } if (s->flags & PARSER_FLAG_COMPLETE_FRAMES) { next = buf_size; } else { next = h264_find_frame_end(p, buf, buf_size, avctx); if (ff_combine_frame(pc, next, &buf, &buf_size) < 0) { *poutbuf = NULL; *poutbuf_size = 0; return buf_size; } if (next < 0 && next != END_NOT_FOUND) { av_assert1(pc->last_index + next >= 0); h264_find_frame_end(p, &pc->buffer[pc->last_index + next], -next, avctx); // update state } } parse_nal_units(s, avctx, buf, buf_size); if (avctx->framerate.num) avctx->time_base = av_inv_q(av_mul_q(avctx->framerate, (AVRational){avctx->ticks_per_frame, 1})); if (p->sei.picture_timing.cpb_removal_delay >= 0) { s->dts_sync_point = p->sei.buffering_period.present; s->dts_ref_dts_delta = p->sei.picture_timing.cpb_removal_delay; s->pts_dts_delta = p->sei.picture_timing.dpb_output_delay; } else { s->dts_sync_point = INT_MIN; s->dts_ref_dts_delta = INT_MIN; s->pts_dts_delta = INT_MIN; } if (s->flags & PARSER_FLAG_ONCE) { 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; }