From 8e4cece9e2b6aa4259da12fae52b544df7aa5da7 Mon Sep 17 00:00:00 2001 From: Joo Aun Saw Date: Mon, 1 Jul 2019 15:20:38 +1000 Subject: [PATCH] ffmpeg: h264_v4l2m2m: pull in memeka's patches --- ...e-unnecessary-timeout-while-draining.patch | 54 ++++++++++++++++ ...fix-segmentation-fault-on-codec-exit.patch | 63 +++++++++++++++++++ ...ble-bit-rate-control-for-mfc-encoder.patch | 27 ++++++++ ...ge-number-of-buffers-for-mfc-encoder.patch | 34 ++++++++++ 4 files changed, 178 insertions(+) create mode 100644 package/ffmpeg/1001-avcodec-v4l2-remove-unnecessary-timeout-while-draining.patch create mode 100644 package/ffmpeg/1002-avcodec-v4l2-fix-segmentation-fault-on-codec-exit.patch create mode 100644 package/ffmpeg/1003-avcodec-v4l2-enable-bit-rate-control-for-mfc-encoder.patch create mode 100644 package/ffmpeg/1004-avcodec-v4l2-change-number-of-buffers-for-mfc-encoder.patch diff --git a/package/ffmpeg/1001-avcodec-v4l2-remove-unnecessary-timeout-while-draining.patch b/package/ffmpeg/1001-avcodec-v4l2-remove-unnecessary-timeout-while-draining.patch new file mode 100644 index 0000000000..bbf052c6b3 --- /dev/null +++ b/package/ffmpeg/1001-avcodec-v4l2-remove-unnecessary-timeout-while-draining.patch @@ -0,0 +1,54 @@ +commit d338ad5e95e6d7b3c4131418d5a92b4717135dec +Author: Jorge Ramirez-Ortiz +Date: Tue Oct 3 10:31:47 2017 +0200 + + avcodec/v4l2_context: remove unnecessary timeout while draining + + This timeout was introduced to work around a bug in the test platform + used to upstream the v4l2 support (DragonBoard 410c, Venus driver). + + Signed-off-by: memeka + +diff --git a/libavcodec/v4l2_context.c b/libavcodec/v4l2_context.c +index 652472fcd6..d5f9f8edac 100644 +--- a/libavcodec/v4l2_context.c ++++ b/libavcodec/v4l2_context.c +@@ -261,17 +261,15 @@ static V4L2Buffer* v4l2_dequeue_v4l2buf(V4L2Context *ctx, int timeout) + if (V4L2_TYPE_IS_OUTPUT(ctx->type)) + pfd.events = POLLOUT | POLLWRNORM; + ++ if (!V4L2_TYPE_IS_OUTPUT(ctx->type) && ctx_to_m2mctx(ctx)->draining) ++ pfd.events = POLLIN | POLLRDNORM | POLLPRI; ++ + for (;;) { + ret = poll(&pfd, 1, timeout); + if (ret > 0) + break; + if (errno == EINTR) + continue; +- +- /* timeout is being used to indicate last valid bufer when draining */ +- if (ctx_to_m2mctx(ctx)->draining) +- ctx->done = 1; +- + return NULL; + } + +@@ -559,7 +557,7 @@ int ff_v4l2_context_dequeue_frame(V4L2Context* ctx, AVFrame* frame) + * 1. decoded frame available + * 2. an input buffer is ready to be dequeued + */ +- avbuf = v4l2_dequeue_v4l2buf(ctx, ctx_to_m2mctx(ctx)->draining ? 200 : -1); ++ avbuf = v4l2_dequeue_v4l2buf(ctx, -1); + if (!avbuf) { + if (ctx->done) + return AVERROR_EOF; +@@ -581,7 +579,7 @@ int ff_v4l2_context_dequeue_packet(V4L2Context* ctx, AVPacket* pkt) + * 1. encoded packet available + * 2. an input buffer ready to be dequeued + */ +- avbuf = v4l2_dequeue_v4l2buf(ctx, ctx_to_m2mctx(ctx)->draining ? 200 : -1); ++ avbuf = v4l2_dequeue_v4l2buf(ctx, -1); + if (!avbuf) { + if (ctx->done) + return AVERROR_EOF; diff --git a/package/ffmpeg/1002-avcodec-v4l2-fix-segmentation-fault-on-codec-exit.patch b/package/ffmpeg/1002-avcodec-v4l2-fix-segmentation-fault-on-codec-exit.patch new file mode 100644 index 0000000000..e18a435b7e --- /dev/null +++ b/package/ffmpeg/1002-avcodec-v4l2-fix-segmentation-fault-on-codec-exit.patch @@ -0,0 +1,63 @@ +commit 18d00a8264b42b9bf9c11b539557ea8e6186aa8e +Author: Jorge Ramirez-Ortiz +Date: Fri Oct 6 09:24:57 2017 +0200 + + avcodec/v4l2: fix segmentation fault on codec exit + + It occurs when the codec is closed while buffer references still + exist. This is a regression from the original patchset where support + for this use-case was implemented. + + Signed-off-by: memeka + +diff --git a/libavcodec/v4l2_buffers.c b/libavcodec/v4l2_buffers.c +index ba70c5d14b..109f611c8a 100644 +--- a/libavcodec/v4l2_buffers.c ++++ b/libavcodec/v4l2_buffers.c +@@ -219,8 +219,17 @@ static void v4l2_free_buffer(void *opaque, uint8_t *unused) + return; + } + +- if (!atomic_load(&s->refcount)) +- ff_v4l2_m2m_codec_end(s->avctx); ++ if (!atomic_load(&s->refcount)) { ++ ++ ff_v4l2_context_release(&s->capture); ++ sem_destroy(&s->refsync); ++ ++ /* release the hardware */ ++ if (close(s->fd) < 0 ) ++ av_log(s->avctx, AV_LOG_ERROR, "failure closing %s (%s)\n", s->devname, av_err2str(AVERROR(errno))); ++ ++ s->fd = -1; ++ } + } + + static int v4l2_buf_to_bufref(V4L2Buffer *in, int plane, AVBufferRef **buf) +diff --git a/libavcodec/v4l2_m2m.c b/libavcodec/v4l2_m2m.c +index bd96a6d979..b78e0315f6 100644 +--- a/libavcodec/v4l2_m2m.c ++++ b/libavcodec/v4l2_m2m.c +@@ -321,6 +321,9 @@ int ff_v4l2_m2m_codec_end(AVCodecContext *avctx) + V4L2m2mContext* s = avctx->priv_data; + int ret; + ++ if (s->fd < 0) ++ return 0; ++ + ret = ff_v4l2_context_set_status(&s->output, VIDIOC_STREAMOFF); + if (ret) + av_log(avctx, AV_LOG_ERROR, "VIDIOC_STREAMOFF %s\n", s->output.name); +@@ -331,8 +334,10 @@ int ff_v4l2_m2m_codec_end(AVCodecContext *avctx) + + ff_v4l2_context_release(&s->output); + +- if (atomic_load(&s->refcount)) +- av_log(avctx, AV_LOG_ERROR, "ff_v4l2m2m_codec_end leaving pending buffers\n"); ++ if (atomic_load(&s->refcount)) { ++ av_log(avctx, AV_LOG_DEBUG, "ff_v4l2m2m_codec_end leaving pending buffers\n"); ++ return 0; ++ } + + ff_v4l2_context_release(&s->capture); + sem_destroy(&s->refsync); diff --git a/package/ffmpeg/1003-avcodec-v4l2-enable-bit-rate-control-for-mfc-encoder.patch b/package/ffmpeg/1003-avcodec-v4l2-enable-bit-rate-control-for-mfc-encoder.patch new file mode 100644 index 0000000000..7eee3bf041 --- /dev/null +++ b/package/ffmpeg/1003-avcodec-v4l2-enable-bit-rate-control-for-mfc-encoder.patch @@ -0,0 +1,27 @@ +commit 24ae67b3fb9e081b9306c2391a79b4388152332f +Author: memeka +Date: Thu Oct 19 13:22:18 2017 +1030 + + avcodec/v4l2: enable bit rate control for MFC encoder + + Signed-off-by: memeka + +diff --git a/libavcodec/v4l2_m2m_enc.c b/libavcodec/v4l2_m2m_enc.c +index e40a120b53..2c35f95847 100644 +--- a/libavcodec/v4l2_m2m_enc.c ++++ b/libavcodec/v4l2_m2m_enc.c +@@ -183,8 +183,13 @@ static int v4l2_prepare_encoder(V4L2m2mContext *s) + + /* set ext ctrls */ + v4l2_set_ext_ctrl(s, MPEG_CID(HEADER_MODE), MPEG_VIDEO(HEADER_MODE_SEPARATE), "header mode"); ++ /* enable bit rate control */ ++ if (avctx->bit_rate > 1) { ++ v4l2_set_ext_ctrl(s, MPEG_CID(FRAME_RC_ENABLE) , 1, "rate control"); ++ av_log(avctx, AV_LOG_INFO, "h264_v4l2m2m encoder: enabling bit rate control: %llu\n", avctx->bit_rate); ++ } + v4l2_set_ext_ctrl(s, MPEG_CID(BITRATE) , avctx->bit_rate, "bit rate"); +- v4l2_set_ext_ctrl(s, MPEG_CID(GOP_SIZE), avctx->gop_size,"gop size"); ++ v4l2_set_ext_ctrl(s, MPEG_CID(GOP_SIZE), avctx->gop_size, "gop size"); + + av_log(avctx, AV_LOG_DEBUG, + "Encoder Context: id (%d), profile (%d), frame rate(%d/%d), number b-frames (%d), " diff --git a/package/ffmpeg/1004-avcodec-v4l2-change-number-of-buffers-for-mfc-encoder.patch b/package/ffmpeg/1004-avcodec-v4l2-change-number-of-buffers-for-mfc-encoder.patch new file mode 100644 index 0000000000..2735e439a4 --- /dev/null +++ b/package/ffmpeg/1004-avcodec-v4l2-change-number-of-buffers-for-mfc-encoder.patch @@ -0,0 +1,34 @@ +commit 530a3fc31b515fe1cdcbbd03ca884c84d72580b1 +Author: memeka +Date: Thu Oct 19 13:23:34 2017 +1030 + + avcodec/v4l2: change number of buffers for MFC encoder + + Signed-off-by: memeka + +diff --git a/libavcodec/v4l2_m2m_dec.c b/libavcodec/v4l2_m2m_dec.c +index 2d96f13954..266caa7bac 100644 +--- a/libavcodec/v4l2_m2m_dec.c ++++ b/libavcodec/v4l2_m2m_dec.c +@@ -288,7 +288,7 @@ static av_cold int v4l2_decode_init(AVCodecContext *avctx) + static const AVOption options[] = { + V4L_M2M_DEFAULT_OPTS, + { "num_capture_buffers", "Number of buffers in the capture context", +- OFFSET(capture.num_buffers), AV_OPT_TYPE_INT, {.i64 = 20}, 20, INT_MAX, FLAGS }, ++ OFFSET(capture.num_buffers), AV_OPT_TYPE_INT, {.i64 = 16}, 16, INT_MAX, FLAGS }, + { NULL}, + }; + +diff --git a/libavcodec/v4l2_m2m_enc.c b/libavcodec/v4l2_m2m_enc.c +index 2c35f95847..ce4b45816e 100644 +--- a/libavcodec/v4l2_m2m_enc.c ++++ b/libavcodec/v4l2_m2m_enc.c +@@ -325,7 +325,7 @@ static av_cold int v4l2_encode_init(AVCodecContext *avctx) + static const AVOption options[] = { + V4L_M2M_DEFAULT_OPTS, + { "num_capture_buffers", "Number of buffers in the capture context", +- OFFSET(capture.num_buffers), AV_OPT_TYPE_INT, {.i64 = 4 }, 4, INT_MAX, FLAGS }, ++ OFFSET(capture.num_buffers), AV_OPT_TYPE_INT, {.i64 = 8}, 8, INT_MAX, FLAGS }, + { NULL }, + }; +