mirror of
https://github.com/roytam1/palemoon27.git
synced 2026-05-26 14:18:48 +00:00
Have specialized AVCodecContext initialization
A common initialization procedure is too restrictive, and we end up setting up audio configuration for video decoding and vice-versa.
This commit is contained in:
@@ -35,6 +35,22 @@ FFmpegAudioDecoder<LIBAV_VER>::Init()
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
FFmpegAudioDecoder<LIBAV_VER>::InitCodecContext()
|
||||
{
|
||||
MOZ_ASSERT(mCodecContext);
|
||||
// We do not want to set this value to 0 as FFmpeg by default will
|
||||
// use the number of cores, which with our mozlibavutil get_cpu_count
|
||||
// isn't implemented.
|
||||
mCodecContext->thread_count = 1;
|
||||
// FFmpeg takes this as a suggestion for what format to use for audio samples.
|
||||
uint32_t major, minor;
|
||||
FFmpegRuntimeLinker::GetVersion(major, minor);
|
||||
// LibAV 0.8 produces rubbish float interleaved samples, request 16 bits audio.
|
||||
mCodecContext->request_sample_fmt =
|
||||
(major == 53) ? AV_SAMPLE_FMT_S16 : AV_SAMPLE_FMT_FLT;
|
||||
}
|
||||
|
||||
static AudioDataValue*
|
||||
CopyAndPackAudio(AVFrame* aFrame, uint32_t aNumChannels, uint32_t aNumAFrames)
|
||||
{
|
||||
|
||||
@@ -28,6 +28,7 @@ public:
|
||||
virtual nsresult Init() override;
|
||||
virtual nsresult Input(MediaRawData* aSample) override;
|
||||
virtual nsresult Drain() override;
|
||||
void InitCodecContext() override;
|
||||
static AVCodecID GetCodecId(const nsACString& aMimeType);
|
||||
|
||||
private:
|
||||
|
||||
@@ -27,13 +27,8 @@ FFmpegDataDecoder<LIBAV_VER>::FFmpegDataDecoder(FlushableMediaTaskQueue* aTaskQu
|
||||
, mFrame(NULL)
|
||||
, mExtraData(nullptr)
|
||||
, mCodecID(aCodecID)
|
||||
, mCodecParser(nullptr)
|
||||
{
|
||||
MOZ_COUNT_CTOR(FFmpegDataDecoder);
|
||||
if (mCodecParser) {
|
||||
av_parser_close(mCodecParser);
|
||||
mCodecParser = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
FFmpegDataDecoder<LIBAV_VER>::~FFmpegDataDecoder()
|
||||
@@ -41,27 +36,6 @@ FFmpegDataDecoder<LIBAV_VER>::~FFmpegDataDecoder()
|
||||
MOZ_COUNT_DTOR(FFmpegDataDecoder);
|
||||
}
|
||||
|
||||
/**
|
||||
* FFmpeg calls back to this function with a list of pixel formats it supports.
|
||||
* We choose a pixel format that we support and return it.
|
||||
* For now, we just look for YUV420P as it is the only non-HW accelerated format
|
||||
* supported by FFmpeg's H264 decoder.
|
||||
*/
|
||||
static PixelFormat
|
||||
ChoosePixelFormat(AVCodecContext* aCodecContext, const PixelFormat* aFormats)
|
||||
{
|
||||
FFMPEG_LOG("Choosing FFmpeg pixel format for video decoding.");
|
||||
for (; *aFormats > -1; aFormats++) {
|
||||
if (*aFormats == PIX_FMT_YUV420P || *aFormats == PIX_FMT_YUVJ420P) {
|
||||
FFMPEG_LOG("Requesting pixel format YUV420P.");
|
||||
return PIX_FMT_YUV420P;
|
||||
}
|
||||
}
|
||||
|
||||
NS_WARNING("FFmpeg does not share any supported pixel formats.");
|
||||
return PIX_FMT_NONE;
|
||||
}
|
||||
|
||||
nsresult
|
||||
FFmpegDataDecoder<LIBAV_VER>::Init()
|
||||
{
|
||||
@@ -82,19 +56,7 @@ FFmpegDataDecoder<LIBAV_VER>::Init()
|
||||
|
||||
mCodecContext->opaque = this;
|
||||
|
||||
// FFmpeg takes this as a suggestion for what format to use for audio samples.
|
||||
uint32_t major, minor;
|
||||
FFmpegRuntimeLinker::GetVersion(major, minor);
|
||||
// LibAV 0.8 produces rubbish float interleaved samples, request 16 bits audio.
|
||||
mCodecContext->request_sample_fmt = major == 53 ?
|
||||
AV_SAMPLE_FMT_S16 : AV_SAMPLE_FMT_FLT;
|
||||
|
||||
// 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_SLICE | FF_THREAD_FRAME;
|
||||
mCodecContext->thread_safe_callbacks = false;
|
||||
InitCodecContext();
|
||||
|
||||
if (mExtraData) {
|
||||
mCodecContext->extradata_size = mExtraData->Length();
|
||||
@@ -126,11 +88,6 @@ FFmpegDataDecoder<LIBAV_VER>::Init()
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
mCodecParser = av_parser_init(mCodecID);
|
||||
if (mCodecParser) {
|
||||
mCodecParser->flags |= PARSER_FLAG_COMPLETE_FRAMES;
|
||||
}
|
||||
|
||||
FFMPEG_LOG("FFmpeg init successful.");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@@ -38,6 +38,7 @@ public:
|
||||
static AVCodec* FindAVCodec(AVCodecID aCodec);
|
||||
|
||||
protected:
|
||||
virtual void InitCodecContext() {}
|
||||
AVFrame* PrepareFrame();
|
||||
|
||||
FlushableMediaTaskQueue* mTaskQueue;
|
||||
@@ -45,7 +46,6 @@ protected:
|
||||
AVFrame* mFrame;
|
||||
nsRefPtr<MediaByteBuffer> mExtraData;
|
||||
AVCodecID mCodecID;
|
||||
AVCodecParserContext* mCodecParser;
|
||||
|
||||
private:
|
||||
static bool sFFmpegInitDone;
|
||||
|
||||
@@ -21,6 +21,27 @@ typedef mozilla::layers::PlanarYCbCrImage PlanarYCbCrImage;
|
||||
namespace mozilla
|
||||
{
|
||||
|
||||
/**
|
||||
* FFmpeg calls back to this function with a list of pixel formats it supports.
|
||||
* We choose a pixel format that we support and return it.
|
||||
* For now, we just look for YUV420P as it is the only non-HW accelerated format
|
||||
* supported by FFmpeg's H264 decoder.
|
||||
*/
|
||||
static PixelFormat
|
||||
ChoosePixelFormat(AVCodecContext* aCodecContext, const PixelFormat* aFormats)
|
||||
{
|
||||
FFMPEG_LOG("Choosing FFmpeg pixel format for video decoding.");
|
||||
for (; *aFormats > -1; aFormats++) {
|
||||
if (*aFormats == PIX_FMT_YUV420P || *aFormats == PIX_FMT_YUVJ420P) {
|
||||
FFMPEG_LOG("Requesting pixel format YUV420P.");
|
||||
return PIX_FMT_YUV420P;
|
||||
}
|
||||
}
|
||||
|
||||
NS_WARNING("FFmpeg does not share any supported pixel formats.");
|
||||
return PIX_FMT_NONE;
|
||||
}
|
||||
|
||||
FFmpegH264Decoder<LIBAV_VER>::PtsCorrectionContext::PtsCorrectionContext()
|
||||
: mNumFaultyPts(0)
|
||||
, mNumFaultyDts(0)
|
||||
@@ -71,6 +92,7 @@ FFmpegH264Decoder<LIBAV_VER>::FFmpegH264Decoder(
|
||||
, mPictureHeight(aConfig.mImage.height)
|
||||
, mDisplayWidth(aConfig.mDisplay.width)
|
||||
, mDisplayHeight(aConfig.mDisplay.height)
|
||||
, mCodecParser(nullptr)
|
||||
{
|
||||
MOZ_COUNT_CTOR(FFmpegH264Decoder);
|
||||
// Use a new MediaByteBuffer as the object will be modified during initialization.
|
||||
@@ -84,10 +106,25 @@ FFmpegH264Decoder<LIBAV_VER>::Init()
|
||||
nsresult rv = FFmpegDataDecoder::Init();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
FFmpegH264Decoder<LIBAV_VER>::InitCodecContext()
|
||||
{
|
||||
mCodecContext->width = mPictureWidth;
|
||||
mCodecContext->height = mPictureHeight;
|
||||
|
||||
return NS_OK;
|
||||
mCodecContext->thread_count = PR_GetNumberOfProcessors();
|
||||
mCodecContext->thread_type = FF_THREAD_SLICE | FF_THREAD_FRAME;
|
||||
|
||||
// FFmpeg will call back to this to negotiate a video pixel format.
|
||||
mCodecContext->get_format = ChoosePixelFormat;
|
||||
|
||||
mCodecParser = av_parser_init(mCodecID);
|
||||
if (mCodecParser) {
|
||||
mCodecParser->flags |= PARSER_FLAG_COMPLETE_FRAMES;
|
||||
}
|
||||
}
|
||||
|
||||
FFmpegH264Decoder<LIBAV_VER>::DecodeResult
|
||||
@@ -292,6 +329,10 @@ FFmpegH264Decoder<LIBAV_VER>::Flush()
|
||||
FFmpegH264Decoder<LIBAV_VER>::~FFmpegH264Decoder()
|
||||
{
|
||||
MOZ_COUNT_DTOR(FFmpegH264Decoder);
|
||||
if (mCodecParser) {
|
||||
av_parser_close(mCodecParser);
|
||||
mCodecParser = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
AVCodecID
|
||||
|
||||
@@ -42,6 +42,7 @@ public:
|
||||
virtual nsresult Input(MediaRawData* aSample) override;
|
||||
virtual nsresult Drain() override;
|
||||
virtual nsresult Flush() override;
|
||||
void InitCodecContext() override;
|
||||
static AVCodecID GetCodecId(const nsACString& aMimeType);
|
||||
|
||||
private:
|
||||
@@ -67,6 +68,9 @@ private:
|
||||
uint32_t mDisplayWidth;
|
||||
uint32_t mDisplayHeight;
|
||||
|
||||
// Parser used for VP8 and VP9 decoding.
|
||||
AVCodecParserContext* mCodecParser;
|
||||
|
||||
class PtsCorrectionContext {
|
||||
public:
|
||||
PtsCorrectionContext();
|
||||
|
||||
Reference in New Issue
Block a user