[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