diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index 69e541a8f0..9a8ca81db9 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -4297,7 +4297,7 @@ int avcodec_decode_audio4(AVCodecContext *avctx, AVFrame *frame, */ int avcodec_decode_video2(AVCodecContext *avctx, AVFrame *picture, int *got_picture_ptr, - AVPacket *avpkt); + const AVPacket *avpkt); /** * Decode a subtitle message. diff --git a/libavcodec/avpacket.c b/libavcodec/avpacket.c index a4bd442176..5a51900ebf 100644 --- a/libavcodec/avpacket.c +++ b/libavcodec/avpacket.c @@ -20,6 +20,7 @@ */ #include "avcodec.h" +#include "internal.h" #include "libavutil/avassert.h" #include "bytestream.h" @@ -30,19 +31,23 @@ void av_destruct_packet_nofree(AVPacket *pkt) pkt->side_data_elems = 0; } -void av_destruct_packet(AVPacket *pkt) +void ff_packet_free_side_data(AVPacket *pkt) { int i; - - av_free(pkt->data); - pkt->data = NULL; pkt->size = 0; - for (i = 0; i < pkt->side_data_elems; i++) av_free(pkt->side_data[i].data); av_freep(&pkt->side_data); pkt->side_data_elems = 0; } +void av_destruct_packet(AVPacket *pkt) +{ + av_free(pkt->data); + pkt->data = NULL; pkt->size = 0; + + ff_packet_free_side_data(pkt); +} + void av_init_packet(AVPacket *pkt) { pkt->pts = AV_NOPTS_VALUE; @@ -239,8 +244,6 @@ int av_packet_split_side_data(AVPacket *pkt){ unsigned int size; uint8_t *p; - av_dup_packet(pkt); - p = pkt->data + pkt->size - 8 - 5; for (i=1; ; i++){ size = AV_RB32(p); diff --git a/libavcodec/internal.h b/libavcodec/internal.h index 068b34bbaa..e6270f81bf 100644 --- a/libavcodec/internal.h +++ b/libavcodec/internal.h @@ -96,6 +96,11 @@ unsigned int avpriv_toupper4(unsigned int x); */ void ff_init_buffer_info(AVCodecContext *s, AVFrame *pic); +/** + * Remove and free all side data from packet. + */ +void ff_packet_free_side_data(AVPacket *pkt); + int avpriv_lock_avformat(void); int avpriv_unlock_avformat(void); diff --git a/libavcodec/utils.c b/libavcodec/utils.c index 219be6b7fb..e25f1dfb41 100644 --- a/libavcodec/utils.c +++ b/libavcodec/utils.c @@ -994,24 +994,26 @@ static void apply_param_change(AVCodecContext *avctx, AVPacket *avpkt) int attribute_align_arg avcodec_decode_video2(AVCodecContext *avctx, AVFrame *picture, int *got_picture_ptr, - AVPacket *avpkt) + const AVPacket *avpkt) { int ret; + // copy to ensure we do not change avpkt + AVPacket tmp = *avpkt; *got_picture_ptr= 0; if((avctx->coded_width||avctx->coded_height) && av_image_check_size(avctx->coded_width, avctx->coded_height, 0, avctx)) return -1; if((avctx->codec->capabilities & CODEC_CAP_DELAY) || avpkt->size || (avctx->active_thread_type&FF_THREAD_FRAME)){ - av_packet_split_side_data(avpkt); - apply_param_change(avctx, avpkt); - avctx->pkt = avpkt; + int did_split = av_packet_split_side_data(&tmp); + apply_param_change(avctx, &tmp); + avctx->pkt = &tmp; if (HAVE_THREADS && avctx->active_thread_type&FF_THREAD_FRAME) ret = ff_thread_decode_frame(avctx, picture, got_picture_ptr, - avpkt); + &tmp); else { ret = avctx->codec->decode(avctx, picture, got_picture_ptr, - avpkt); + &tmp); picture->pkt_dts= avpkt->dts; if(!avctx->has_b_frames){ @@ -1030,6 +1032,9 @@ int attribute_align_arg avcodec_decode_video2(AVCodecContext *avctx, AVFrame *pi emms_c(); //needed to avoid an emms_c() call before every return; + avctx->pkt = NULL; + if (did_split) + ff_packet_free_side_data(&tmp); if (*got_picture_ptr){ avctx->frame_number++;