summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libavcodec/avcodec.h2
-rw-r--r--libavcodec/avpacket.c17
-rw-r--r--libavcodec/internal.h5
-rw-r--r--libavcodec/utils.c17
4 files changed, 27 insertions, 14 deletions
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++;