Skip to content

Commit

Permalink
AvFormatDecoder: Pass optional AVDictionary options to avcodec_open2
Browse files Browse the repository at this point in the history
- used to reduce the number of v4l2_m2m capture buffers
  • Loading branch information
mark-kendall committed Jul 10, 2019
1 parent eba8bab commit 5162cc0
Show file tree
Hide file tree
Showing 5 changed files with 22 additions and 6 deletions.
12 changes: 7 additions & 5 deletions mythtv/libs/libmythtv/decoders/avformatdecoder.cpp
Expand Up @@ -2601,16 +2601,17 @@ int AvFormatDecoder::ScanStreams(bool novideo)
QString("Using %1 for video decoding")
.arg(GetCodecDecoderName()));

AVDictionary *options = m_mythcodecctx->GetDecoderOptions();
{
QMutexLocker locker(avcodeclock);

if (!OpenAVCodec(enc, codec))
if (!OpenAVCodec(enc, codec, options))
{
av_dict_free(&options);
scanerror = -1;
break;
}
}

av_dict_free(&options);
break;
}
}
Expand Down Expand Up @@ -2673,15 +2674,16 @@ int AvFormatDecoder::ScanStreams(bool novideo)
return scanerror;
}

bool AvFormatDecoder::OpenAVCodec(AVCodecContext *avctx, const AVCodec *codec)
bool AvFormatDecoder::OpenAVCodec(AVCodecContext *avctx, const AVCodec *codec,
AVDictionary *Options)
{
QMutexLocker locker(avcodeclock);

#ifdef USING_MEDIACODEC
if (QString("mediacodec") == codec->wrapper_name)
av_jni_set_java_vm(QAndroidJniEnvironment::javaVM(), nullptr);
#endif
int ret = avcodec_open2(avctx, codec, nullptr);
int ret = avcodec_open2(avctx, codec, &Options);
if (ret < 0)
{
char error[AV_ERROR_MAX_STRING_SIZE];
Expand Down
2 changes: 1 addition & 1 deletion mythtv/libs/libmythtv/decoders/avformatdecoder.h
Expand Up @@ -261,7 +261,7 @@ class AvFormatDecoder : public DecoderBase
bool HasVideo(const AVFormatContext *ic);
float normalized_fps(AVStream *stream, AVCodecContext *enc);
void av_update_stream_timings_video(AVFormatContext *ic);
bool OpenAVCodec(AVCodecContext *avctx, const AVCodec *codec);
bool OpenAVCodec(AVCodecContext *avctx, const AVCodec *codec, AVDictionary *Options = nullptr);

void UpdateFramesPlayed(void) override; // DecoderBase
bool DoRewindSeek(long long desiredFrame) override; // DecoderBase
Expand Down
1 change: 1 addition & 0 deletions mythtv/libs/libmythtv/decoders/mythcodeccontext.h
Expand Up @@ -67,6 +67,7 @@ class MTV_PUBLIC MythCodecContext
virtual void SetDeinterlacing (AVCodecContext*, VideoDisplayProfile*, bool) {}
virtual void PostProcessFrame (AVCodecContext*, VideoFrame*) {}
virtual bool IsDeinterlacing (bool &, bool = false) { return false; }
virtual AVDictionary* GetDecoderOptions(void) { return nullptr; }

protected:
virtual bool RetrieveHWFrame (VideoFrame* Frame, AVFrame* AvFrame);
Expand Down
12 changes: 12 additions & 0 deletions mythtv/libs/libmythtv/mythv4l2m2mcontext.cpp
Expand Up @@ -83,6 +83,18 @@ bool MythV4L2M2MContext::RetrieveFrame(AVCodecContext *Context, VideoFrame *Fram
return false;
}

/*! \brief Reduce the number of capture buffers
*
* Testing on Pi 3, the default of 20 is too high and leads to memory allocation
* failures in the the kernel driver.
*/
AVDictionary* MythV4L2M2MContext::GetDecoderOptions(void)
{
AVDictionary *options = nullptr;
av_dict_set_int(&options, "num_capture_buffers", 2, 0);
return options;
}

/*! \brief Retrieve a frame from CPU memory
*
* This is similar to the default, direct render supporting, get_av_buffer in
Expand Down
1 change: 1 addition & 0 deletions mythtv/libs/libmythtv/mythv4l2m2mcontext.h
Expand Up @@ -14,6 +14,7 @@ class MythV4L2M2MContext : public MythCodecContext
uint StreamType,
AVPixelFormat &PixFmt);
bool RetrieveFrame (AVCodecContext *Context, VideoFrame *Frame, AVFrame *AvFrame) override;
AVDictionary* GetDecoderOptions (void) override;
static bool GetBuffer (AVCodecContext *Context, VideoFrame *Frame, AVFrame *AvFrame, int);
static bool GetDRMBuffer (AVCodecContext *Context, VideoFrame *Frame, AVFrame *AvFrame, int);
static bool HaveV4L2Codecs (AVCodecID Codec = AV_CODEC_ID_NONE);
Expand Down

0 comments on commit 5162cc0

Please sign in to comment.