[FFmpeg-devel] [PATCH 5/6] lavc/utils: bind SKIP_SAMPLES to the frame.
Nicolas George
george at nsup.org
Fri Feb 21 20:50:17 CET 2014
From: Nicolas George <nicolas.george at normalesup.org>
If several packets have the SKIP_SAMPLES side data and the
decoded frame does not correspond to the input packet (which
can happen with codec delay of frame multithreading), then a
later SKIP_SAMPLES value will be applied to an earlier frame.
To fix that, copy the SKIP_SAMPLES side data from the packet
to the frame in ff_init_buffer_info() along with the rest of
the useful packet metadata, and use the side data from the
frame to apply SKIP_SAMPLES.
Signed-off-by: Nicolas George <george at nsup.org>
---
libavcodec/utils.c | 25 +++++++++++++++++++------
1 file changed, 19 insertions(+), 6 deletions(-)
diff --git a/libavcodec/utils.c b/libavcodec/utils.c
index 74c12f4..d5f271d 100644
--- a/libavcodec/utils.c
+++ b/libavcodec/utils.c
@@ -752,11 +752,24 @@ FF_ENABLE_DEPRECATION_WARNINGS
int ff_init_buffer_info(AVCodecContext *avctx, AVFrame *frame)
{
if (avctx->internal->pkt) {
+ uint8_t *side;
+ int side_size;
+ AVFrameSideData *fsd;
+
frame->pkt_pts = avctx->internal->pkt->pts;
av_frame_set_pkt_pos (frame, avctx->internal->pkt->pos);
av_frame_set_pkt_duration(frame, avctx->internal->pkt->duration);
av_frame_set_pkt_size (frame, avctx->internal->pkt->size);
av_frame_set_pkt_flags (frame, avctx->internal->pkt->flags);
+ side = av_packet_get_side_data(avctx->internal->pkt,
+ AV_PKT_DATA_SKIP_SAMPLES, &side_size);
+ if (side) {
+ fsd = av_frame_new_side_data(frame, AV_FRAME_DATA_SKIP_SAMPLES,
+ side_size);
+ if (!fsd)
+ return AVERROR(ENOMEM);
+ memcpy(fsd->data, side, side_size);
+ }
} else {
frame->pkt_pts = AV_NOPTS_VALUE;
av_frame_set_pkt_pos (frame, -1);
@@ -2272,8 +2285,7 @@ int attribute_align_arg avcodec_decode_audio4(AVCodecContext *avctx,
av_frame_unref(frame);
if ((avctx->codec->capabilities & CODEC_CAP_DELAY) || avpkt->size || (avctx->active_thread_type & FF_THREAD_FRAME)) {
- uint8_t *side;
- int side_size;
+ AVFrameSideData *side = NULL;
uint32_t discard_padding = 0;
// copy to ensure we do not change avpkt
AVPacket tmp = *avpkt;
@@ -2309,12 +2321,13 @@ int attribute_align_arg avcodec_decode_audio4(AVCodecContext *avctx,
frame->sample_rate = avctx->sample_rate;
}
- side= av_packet_get_side_data(avctx->internal->pkt, AV_PKT_DATA_SKIP_SAMPLES, &side_size);
- if(side && side_size>=10) {
- avctx->internal->skip_samples = AV_RL32(side);
+ if (*got_frame_ptr)
+ side = av_frame_get_side_data(frame, AV_FRAME_DATA_SKIP_SAMPLES);
+ if(side && side->size >= 10) {
+ avctx->internal->skip_samples = AV_RL32(side->data);
av_log(avctx, AV_LOG_DEBUG, "skip %d samples due to side data\n",
avctx->internal->skip_samples);
- discard_padding = AV_RL32(side + 4);
+ discard_padding = AV_RL32(side->data + 4);
}
if (avctx->internal->skip_samples && *got_frame_ptr) {
if(frame->nb_samples <= avctx->internal->skip_samples){
--
1.8.5.3
More information about the ffmpeg-devel
mailing list