diff --git a/libavcodec/internal.h b/libavcodec/internal.h index 49c1a18edf..993c42f089 100644 --- a/libavcodec/internal.h +++ b/libavcodec/internal.h @@ -84,6 +84,11 @@ typedef struct AVCodecInternal { unsigned int byte_buffer_size; void *frame_thread_encoder; + + /** + * Number of audio samples to skip at the start of the next decoded frame + */ + int skip_samples; } AVCodecInternal; struct AVCodecDefault { diff --git a/libavcodec/utils.c b/libavcodec/utils.c index abb5674e7f..3ef52728ff 100644 --- a/libavcodec/utils.c +++ b/libavcodec/utils.c @@ -1627,6 +1627,8 @@ int attribute_align_arg avcodec_decode_audio4(AVCodecContext *avctx, } if ((avctx->codec->capabilities & CODEC_CAP_DELAY) || avpkt->size) { + uint8_t *side; + int side_size; // copy to ensure we do not change avpkt AVPacket tmp = *avpkt; int did_split = av_packet_split_side_data(&tmp); @@ -1645,6 +1647,22 @@ int attribute_align_arg avcodec_decode_audio4(AVCodecContext *avctx, frame->sample_rate = avctx->sample_rate; } + side= av_packet_get_side_data(avctx->pkt, AV_PKT_DATA_SKIP_SAMPLES, &side_size); + if(side && side_size>=10) { + avctx->internal->skip_samples = AV_RL32(side); + } + if (avctx->internal->skip_samples) { + if(frame->nb_samples <= avctx->internal->skip_samples){ + *got_frame_ptr = 0; + avctx->internal->skip_samples -= frame->nb_samples; + } else { + av_samples_copy(frame->extended_data, frame->extended_data, 0, avctx->internal->skip_samples, + frame->nb_samples - avctx->internal->skip_samples, avctx->channels, frame->format); + frame->nb_samples -= avctx->internal->skip_samples; + avctx->internal->skip_samples = 0; + } + } + avctx->pkt = NULL; if (did_split) { ff_packet_free_side_data(&tmp);