зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1033137 - Fix image lifetime issues in libav backend; r=edwin
This commit is contained in:
Родитель
441cb860ec
Коммит
7905911bfd
|
@ -12,6 +12,7 @@
|
|||
#include "FFmpegLibs.h"
|
||||
#include "FFmpegLog.h"
|
||||
#include "FFmpegDataDecoder.h"
|
||||
#include "prsystem.h"
|
||||
|
||||
namespace mozilla
|
||||
{
|
||||
|
@ -83,6 +84,10 @@ FFmpegDataDecoder<LIBAV_VER>::Init()
|
|||
// FFmpeg will call back to this to negotiate a video pixel format.
|
||||
mCodecContext.get_format = ChoosePixelFormat;
|
||||
|
||||
mCodecContext.thread_count = PR_GetNumberOfProcessors();
|
||||
mCodecContext.thread_type = FF_THREAD_FRAME;
|
||||
mCodecContext.thread_safe_callbacks = false;
|
||||
|
||||
mCodecContext.extradata = mExtraData.begin();
|
||||
mCodecContext.extradata_size = mExtraData.length();
|
||||
|
||||
|
|
|
@ -42,6 +42,7 @@ FFmpegH264Decoder<LIBAV_VER>::Init()
|
|||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
mCodecContext.get_buffer = AllocateBufferCb;
|
||||
mCodecContext.release_buffer = ReleaseBufferCb;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -82,8 +83,8 @@ FFmpegH264Decoder<LIBAV_VER>::DecodeFrame(mp4_demuxer::MP4Sample* aSample)
|
|||
|
||||
data = VideoData::CreateFromImage(
|
||||
info, mImageContainer, aSample->byte_offset,
|
||||
aSample->composition_timestamp, aSample->duration, mCurrentImage,
|
||||
aSample->is_sync_point, -1,
|
||||
aSample->composition_timestamp, aSample->duration,
|
||||
reinterpret_cast<Image*>(frame->opaque), aSample->is_sync_point, -1,
|
||||
gfx::IntRect(0, 0, mCodecContext.width, mCodecContext.height));
|
||||
|
||||
mCallback->Output(data.forget());
|
||||
|
@ -132,6 +133,13 @@ FFmpegH264Decoder<LIBAV_VER>::AllocateBufferCb(AVCodecContext* aCodecContext,
|
|||
}
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
FFmpegH264Decoder<LIBAV_VER>::ReleaseBufferCb(AVCodecContext* aCodecContext,
|
||||
AVFrame* aFrame)
|
||||
{
|
||||
reinterpret_cast<Image*>(aFrame->opaque)->Release();
|
||||
}
|
||||
|
||||
int
|
||||
FFmpegH264Decoder<LIBAV_VER>::AllocateYUV420PVideoBuffer(
|
||||
AVCodecContext* aCodecContext, AVFrame* aFrame)
|
||||
|
@ -194,7 +202,7 @@ FFmpegH264Decoder<LIBAV_VER>::AllocateYUV420PVideoBuffer(
|
|||
PlanarYCbCrDataFromAVFrame(data, aFrame);
|
||||
ycbcr->SetDataNoCopy(data);
|
||||
|
||||
mCurrentImage.swap(image);
|
||||
aFrame->opaque = reinterpret_cast<void*>(image.forget().take());
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -49,22 +49,10 @@ private:
|
|||
AVFrame* aFrame);
|
||||
|
||||
static int AllocateBufferCb(AVCodecContext* aCodecContext, AVFrame* aFrame);
|
||||
static void ReleaseBufferCb(AVCodecContext* aCodecContext, AVFrame* aFrame);
|
||||
|
||||
MediaDataDecoderCallback* mCallback;
|
||||
nsRefPtr<ImageContainer> mImageContainer;
|
||||
|
||||
/**
|
||||
* Pass Image back from the allocator to our DoDecode method.
|
||||
* We *should* return the image back through ffmpeg wrapped in an AVFrame like
|
||||
* we're meant to. However, if avcodec_decode_video2 fails, it returns a
|
||||
* completely different frame from the one holding our image and it will be
|
||||
* leaked.
|
||||
* This could be handled in the future by wrapping our Image in a reference
|
||||
* counted AVBuffer and letting ffmpeg hold the nsAutoPtr<Image>, but
|
||||
* currently we have to support older versions of ffmpeg which lack
|
||||
* refcounting.
|
||||
*/
|
||||
nsRefPtr<Image> mCurrentImage;
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
|
Загрузка…
Ссылка в новой задаче