nsresult FFmpegDataDecoder<LIBAV_VER>::InitDecoder() { FFMPEG_LOG("Initialising FFmpeg decoder."); AVCodec* codec = FindAVCodec(mCodecID); if (!codec) { NS_WARNING("Couldn't find ffmpeg decoder"); return NS_ERROR_FAILURE; } StaticMutexAutoLock mon(sMonitor); if (!(mCodecContext = avcodec_alloc_context3(codec))) { NS_WARNING("Couldn't init ffmpeg context"); return NS_ERROR_FAILURE; } mCodecContext->opaque = this; InitCodecContext(); if (mExtraData) { mCodecContext->extradata_size = mExtraData->Length(); // FFmpeg may use SIMD instructions to access the data which reads the // data in 32 bytes block. Must ensure we have enough data to read. mExtraData->AppendElements(FF_INPUT_BUFFER_PADDING_SIZE); mCodecContext->extradata = mExtraData->Elements(); } else { mCodecContext->extradata_size = 0; } if (codec->capabilities & CODEC_CAP_DR1) { mCodecContext->flags |= CODEC_FLAG_EMU_EDGE; } if (avcodec_open2(mCodecContext, codec, nullptr) < 0) { NS_WARNING("Couldn't initialise ffmpeg decoder"); avcodec_close(mCodecContext); av_freep(&mCodecContext); return NS_ERROR_FAILURE; } if (mCodecContext->codec_type == AVMEDIA_TYPE_AUDIO && mCodecContext->sample_fmt != AV_SAMPLE_FMT_FLT && mCodecContext->sample_fmt != AV_SAMPLE_FMT_FLTP && mCodecContext->sample_fmt != AV_SAMPLE_FMT_S16 && mCodecContext->sample_fmt != AV_SAMPLE_FMT_S16P) { NS_WARNING("FFmpeg audio decoder outputs unsupported audio format."); return NS_ERROR_FAILURE; } FFMPEG_LOG("FFmpeg init successful."); return NS_OK; }
nsresult FFmpegDataDecoder<LIBAV_VER>::InitDecoder() { FFMPEG_LOG("Initialising FFmpeg decoder."); AVCodec* codec = FindAVCodec(mCodecID); if (!codec) { NS_WARNING("Couldn't find ffmpeg decoder"); return NS_ERROR_FAILURE; } StaticMutexAutoLock mon(sMonitor); if (!(mCodecContext = avcodec_alloc_context3(codec))) { NS_WARNING("Couldn't init ffmpeg context"); return NS_ERROR_FAILURE; } 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 interlaved samples, request 16 bits audio. mCodecContext->request_sample_fmt = major == 53 && minor <= 34 ? 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; if (mExtraData) { mCodecContext->extradata_size = mExtraData->Length(); // FFmpeg may use SIMD instructions to access the data which reads the // data in 32 bytes block. Must ensure we have enough data to read. mExtraData->AppendElements(FF_INPUT_BUFFER_PADDING_SIZE); mCodecContext->extradata = mExtraData->Elements(); } else { mCodecContext->extradata_size = 0; } if (codec->capabilities & CODEC_CAP_DR1) { mCodecContext->flags |= CODEC_FLAG_EMU_EDGE; } if (avcodec_open2(mCodecContext, codec, nullptr) < 0) { NS_WARNING("Couldn't initialise ffmpeg decoder"); avcodec_close(mCodecContext); av_freep(&mCodecContext); return NS_ERROR_FAILURE; } if (mCodecContext->codec_type == AVMEDIA_TYPE_AUDIO && mCodecContext->sample_fmt != AV_SAMPLE_FMT_FLT && mCodecContext->sample_fmt != AV_SAMPLE_FMT_FLTP && mCodecContext->sample_fmt != AV_SAMPLE_FMT_S16 && mCodecContext->sample_fmt != AV_SAMPLE_FMT_S16P) { NS_WARNING("FFmpeg audio decoder outputs unsupported audio format."); 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; }