From fa1ad381da72c76ea8f5f85c19959630aab7e3ea Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Sat, 15 Dec 2012 08:42:54 -0800 Subject: [PATCH] Make sure packets are cleaned up properly --- apps/openmw/mwrender/videoplayer.cpp | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/apps/openmw/mwrender/videoplayer.cpp b/apps/openmw/mwrender/videoplayer.cpp index bfcb927459..b0bf371549 100644 --- a/apps/openmw/mwrender/videoplayer.cpp +++ b/apps/openmw/mwrender/videoplayer.cpp @@ -118,7 +118,6 @@ struct VideoState { double audio_clock; AVStream *audio_st; PacketQueue audioq; - AVPacket audio_pkt; double audio_diff_cum; /* used for AV difference average computation */ double audio_diff_avg_coef; double audio_diff_threshold; @@ -239,8 +238,19 @@ class MovieAudioDecoder : public MWSound::Sound_Decoder throw std::runtime_error(str); } + struct AutoAVPacket : public AVPacket { + AutoAVPacket(int size=0) + { + if(av_new_packet(this, size) < 0) + throw std::bad_alloc(); + } + ~AutoAVPacket() + { av_free_packet(this); } + }; + VideoState *is; + AutoAVPacket mPacket; AVFrame *mFrame; ssize_t mFramePos; ssize_t mFrameSize; @@ -276,7 +286,7 @@ class MovieAudioDecoder : public MWSound::Sound_Decoder int audio_decode_frame(AVFrame *frame) { - AVPacket *pkt = &is->audio_pkt; + AVPacket *pkt = &mPacket; for(;;) { @@ -292,8 +302,7 @@ class MovieAudioDecoder : public MWSound::Sound_Decoder /* Move the unread data to the front and clear the end bits */ int remaining = pkt->size - len1; memmove(pkt->data, &pkt->data[len1], remaining); - memset(&pkt->data[remaining], 0, pkt->size - remaining); - pkt->size -= len1; + av_shrink_packet(pkt, remaining); } /* No data yet? Look for more frames */ @@ -307,8 +316,7 @@ class MovieAudioDecoder : public MWSound::Sound_Decoder return frame->nb_samples * av_get_bytes_per_sample(is->audio_st->codec->sample_fmt) * is->audio_st->codec->channels; } - if(pkt->data) - av_free_packet(pkt); + av_free_packet(pkt); if(is->quit) return -1; @@ -717,6 +725,8 @@ void VideoState::video_thread_loop(VideoState *self) pts = *(uint64_t*)pFrame->opaque; pts *= av_q2d(self->video_st->time_base); + av_free_packet(packet); + // Did we get a video frame? if(frameFinished) { @@ -724,7 +734,6 @@ void VideoState::video_thread_loop(VideoState *self) if(self->queue_picture(pFrame, pts) < 0) break; } - av_free_packet(packet); } av_free(pFrame); @@ -814,8 +823,6 @@ int VideoState::stream_open(int stream_index, AVFormatContext *pFormatCtx) /* Correct audio only if larger error than this */ this->audio_diff_threshold = 2.0 * 0.050/* 50 ms */; - memset(&this->audio_pkt, 0, sizeof(this->audio_pkt)); - decoder.reset(new MovieAudioDecoder(this)); this->AudioTrack = MWBase::Environment::get().getSoundManager()->playTrack(decoder); if(!this->AudioTrack)