mirror of
https://github.com/motioneye-project/motioneyeos.git
synced 2025-07-27 13:16:35 +00:00
commit
2af955fbfc
@ -12,7 +12,7 @@ BR2_ROOTFS_OVERLAY="board/common/overlay board/odroidxu4/overlay"
|
|||||||
BR2_ROOTFS_POST_BUILD_SCRIPT="board/common/postscript.sh"
|
BR2_ROOTFS_POST_BUILD_SCRIPT="board/common/postscript.sh"
|
||||||
BR2_LINUX_KERNEL=y
|
BR2_LINUX_KERNEL=y
|
||||||
BR2_LINUX_KERNEL_CUSTOM_TARBALL=y
|
BR2_LINUX_KERNEL_CUSTOM_TARBALL=y
|
||||||
BR2_LINUX_KERNEL_CUSTOM_TARBALL_LOCATION="https://github.com/hardkernel/linux/archive/be592282a08a2493692448e365e46b52ac715b3f.tar.gz"
|
BR2_LINUX_KERNEL_CUSTOM_TARBALL_LOCATION="https://github.com/hardkernel/linux/archive/4.14.127-164.tar.gz"
|
||||||
BR2_LINUX_KERNEL_DEFCONFIG="odroidxu4"
|
BR2_LINUX_KERNEL_DEFCONFIG="odroidxu4"
|
||||||
BR2_LINUX_KERNEL_DTS_SUPPORT=y
|
BR2_LINUX_KERNEL_DTS_SUPPORT=y
|
||||||
BR2_LINUX_KERNEL_INTREE_DTS_NAME="exynos5422-odroidxu4"
|
BR2_LINUX_KERNEL_INTREE_DTS_NAME="exynos5422-odroidxu4"
|
||||||
|
@ -27,8 +27,8 @@ index c86e578..76523c8 100755
|
|||||||
qsvdec_select="qsv"
|
qsvdec_select="qsv"
|
||||||
qsvenc_select="qsv"
|
qsvenc_select="qsv"
|
||||||
vaapi_encode_deps="vaapi"
|
vaapi_encode_deps="vaapi"
|
||||||
-v4l2_m2m_deps_any="linux_videodev2_h"
|
-v4l2_m2m_deps="linux_videodev2_h sem_timedwait"
|
||||||
+v4l2_m2m_deps="linux_videodev2_h pthreads"
|
+v4l2_m2m_deps="linux_videodev2_h sem_timedwait pthreads"
|
||||||
|
|
||||||
hwupload_cuda_filter_deps="cuda"
|
hwupload_cuda_filter_deps="cuda"
|
||||||
scale_npp_filter_deps="cuda libnpp"
|
scale_npp_filter_deps="cuda libnpp"
|
||||||
|
@ -1,100 +0,0 @@
|
|||||||
From c60fb550302878aba7e86037451f7996e8069289 Mon Sep 17 00:00:00 2001
|
|
||||||
From: =?UTF-8?q?Martin=20Storsj=C3=B6?= <martin@martin.st>
|
|
||||||
Date: Fri, 31 Aug 2018 14:25:30 +0300
|
|
||||||
Subject: [PATCH] libfdk-aacenc: Fix building with libfdk-aac v2
|
|
||||||
MIME-Version: 1.0
|
|
||||||
Content-Type: text/plain; charset=UTF-8
|
|
||||||
Content-Transfer-Encoding: 8bit
|
|
||||||
|
|
||||||
When flushing the encoder, we now need to provide non-null buffer
|
|
||||||
parameters for everything, even if they are unused.
|
|
||||||
|
|
||||||
The encoderDelay parameter has been replaced by two, nDelay and
|
|
||||||
nDelayCore.
|
|
||||||
|
|
||||||
Downloaded from
|
|
||||||
http://git.videolan.org/?p=ffmpeg.git;a=commitdiff;h=141c960e21d2860e354f9b90df136184dd00a9a8
|
|
||||||
|
|
||||||
Signed-off-by: Martin Storsjö <martin@martin.st>
|
|
||||||
[Bernd: rebased for ffmpeg 3.4.5]
|
|
||||||
Signed-off-by: Bernd Kuhls <bernd.kuhls@t-online.de>
|
|
||||||
---
|
|
||||||
libavcodec/libfdk-aacenc.c | 34 +++++++++++++++++++++++++---------
|
|
||||||
1 file changed, 25 insertions(+), 9 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/libavcodec/libfdk-aacenc.c b/libavcodec/libfdk-aacenc.c
|
|
||||||
index 0e2051b468..f5adb407ed 100644
|
|
||||||
--- a/libavcodec/libfdk-aacenc.c
|
|
||||||
+++ b/libavcodec/libfdk-aacenc.c
|
|
||||||
@@ -26,6 +26,11 @@
|
|
||||||
#include "audio_frame_queue.h"
|
|
||||||
#include "internal.h"
|
|
||||||
|
|
||||||
+#define FDKENC_VER_AT_LEAST(vl0, vl1) \
|
|
||||||
+ (defined(AACENCODER_LIB_VL0) && \
|
|
||||||
+ ((AACENCODER_LIB_VL0 > vl0) || \
|
|
||||||
+ (AACENCODER_LIB_VL0 == vl0 && AACENCODER_LIB_VL1 >= vl1)))
|
|
||||||
+
|
|
||||||
typedef struct AACContext {
|
|
||||||
const AVClass *class;
|
|
||||||
HANDLE_AACENCODER handle;
|
|
||||||
@@ -286,7 +291,11 @@ static av_cold int aac_encode_init(AVCodecContext *avctx)
|
|
||||||
}
|
|
||||||
|
|
||||||
avctx->frame_size = info.frameLength;
|
|
||||||
+#if FDKENC_VER_AT_LEAST(4, 0)
|
|
||||||
+ avctx->initial_padding = info.nDelay;
|
|
||||||
+#else
|
|
||||||
avctx->initial_padding = info.encoderDelay;
|
|
||||||
+#endif
|
|
||||||
ff_af_queue_init(avctx, &s->afq);
|
|
||||||
|
|
||||||
if (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER) {
|
|
||||||
@@ -319,28 +328,35 @@ static int aac_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
|
|
||||||
int out_buffer_size, out_buffer_element_size;
|
|
||||||
void *in_ptr, *out_ptr;
|
|
||||||
int ret;
|
|
||||||
+ uint8_t dummy_buf[1];
|
|
||||||
AACENC_ERROR err;
|
|
||||||
|
|
||||||
/* handle end-of-stream small frame and flushing */
|
|
||||||
if (!frame) {
|
|
||||||
+ /* Must be a non-null pointer, even if it's a dummy. We could use
|
|
||||||
+ * the address of anything else on the stack as well. */
|
|
||||||
+ in_ptr = dummy_buf;
|
|
||||||
+ in_buffer_size = 0;
|
|
||||||
+
|
|
||||||
in_args.numInSamples = -1;
|
|
||||||
} else {
|
|
||||||
- in_ptr = frame->data[0];
|
|
||||||
- in_buffer_size = 2 * avctx->channels * frame->nb_samples;
|
|
||||||
- in_buffer_element_size = 2;
|
|
||||||
+ in_ptr = frame->data[0];
|
|
||||||
+ in_buffer_size = 2 * avctx->channels * frame->nb_samples;
|
|
||||||
|
|
||||||
- in_args.numInSamples = avctx->channels * frame->nb_samples;
|
|
||||||
- in_buf.numBufs = 1;
|
|
||||||
- in_buf.bufs = &in_ptr;
|
|
||||||
- in_buf.bufferIdentifiers = &in_buffer_identifier;
|
|
||||||
- in_buf.bufSizes = &in_buffer_size;
|
|
||||||
- in_buf.bufElSizes = &in_buffer_element_size;
|
|
||||||
+ in_args.numInSamples = avctx->channels * frame->nb_samples;
|
|
||||||
|
|
||||||
/* add current frame to the queue */
|
|
||||||
if ((ret = ff_af_queue_add(&s->afq, frame)) < 0)
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
+ in_buffer_element_size = 2;
|
|
||||||
+ in_buf.numBufs = 1;
|
|
||||||
+ in_buf.bufs = &in_ptr;
|
|
||||||
+ in_buf.bufferIdentifiers = &in_buffer_identifier;
|
|
||||||
+ in_buf.bufSizes = &in_buffer_size;
|
|
||||||
+ in_buf.bufElSizes = &in_buffer_element_size;
|
|
||||||
+
|
|
||||||
/* The maximum packet size is 6144 bits aka 768 bytes per channel. */
|
|
||||||
if ((ret = ff_alloc_packet2(avctx, avpkt, FFMAX(8192, 768 * avctx->channels), 0)) < 0)
|
|
||||||
return ret;
|
|
||||||
--
|
|
||||||
2.20.1
|
|
||||||
|
|
@ -1,99 +0,0 @@
|
|||||||
From 48be4c81e0ad081edab65e133e6e1bdec7de3b55 Mon Sep 17 00:00:00 2001
|
|
||||||
From: =?UTF-8?q?Martin=20Storsj=C3=B6?= <martin@martin.st>
|
|
||||||
Date: Tue, 4 Sep 2018 08:29:37 +0300
|
|
||||||
Subject: [PATCH] libfdk-aac: Consistently use a proper version check macro for
|
|
||||||
detecting features
|
|
||||||
MIME-Version: 1.0
|
|
||||||
Content-Type: text/plain; charset=UTF-8
|
|
||||||
Content-Transfer-Encoding: 8bit
|
|
||||||
|
|
||||||
libfdk-aac: Consistently use a proper version check macro for detecting features
|
|
||||||
|
|
||||||
The previous version checks checked explicitly for the version
|
|
||||||
where the version define was added to the installed headers,
|
|
||||||
making an "#ifdef AACDECODER_LIB_VL0" enough. Now that we have
|
|
||||||
a need for more diverse version checks than this, convert all checks
|
|
||||||
to such checks.
|
|
||||||
|
|
||||||
Downloaded from
|
|
||||||
http://git.videolan.org/?p=ffmpeg.git;a=commitdiff;h=ffb9b7a6bab6c6bfd3dd9a7c32e3724209824999
|
|
||||||
|
|
||||||
Signed-off-by: Martin Storsjö <martin@martin.st>
|
|
||||||
Signed-off-by: Bernd Kuhls <bernd.kuhls@t-online.de>
|
|
||||||
---
|
|
||||||
libavcodec/libfdk-aacdec.c | 13 ++++++++-----
|
|
||||||
libavcodec/libfdk-aacenc.c | 6 +++---
|
|
||||||
2 files changed, 11 insertions(+), 8 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/libavcodec/libfdk-aacdec.c b/libavcodec/libfdk-aacdec.c
|
|
||||||
index 2857b9453f..ef51184ebd 100644
|
|
||||||
--- a/libavcodec/libfdk-aacdec.c
|
|
||||||
+++ b/libavcodec/libfdk-aacdec.c
|
|
||||||
@@ -25,9 +25,12 @@
|
|
||||||
#include "avcodec.h"
|
|
||||||
#include "internal.h"
|
|
||||||
|
|
||||||
-/* The version macro is introduced the same time as the setting enum was
|
|
||||||
- * changed, so this check should suffice. */
|
|
||||||
-#ifndef AACDECODER_LIB_VL0
|
|
||||||
+#define FDKDEC_VER_AT_LEAST(vl0, vl1) \
|
|
||||||
+ (defined(AACDECODER_LIB_VL0) && \
|
|
||||||
+ ((AACDECODER_LIB_VL0 > vl0) || \
|
|
||||||
+ (AACDECODER_LIB_VL0 == vl0 && AACDECODER_LIB_VL1 >= vl1)))
|
|
||||||
+
|
|
||||||
+#if !FDKDEC_VER_AT_LEAST(2, 5) // < 2.5.10
|
|
||||||
#define AAC_PCM_MAX_OUTPUT_CHANNELS AAC_PCM_OUTPUT_CHANNELS
|
|
||||||
#endif
|
|
||||||
|
|
||||||
@@ -72,7 +75,7 @@ static const AVOption fdk_aac_dec_options[] = {
|
|
||||||
OFFSET(drc_level), AV_OPT_TYPE_INT, { .i64 = -1}, -1, 127, AD, NULL },
|
|
||||||
{ "drc_heavy", "Dynamic Range Control: heavy compression, where [1] is on (RF mode) and [0] is off",
|
|
||||||
OFFSET(drc_heavy), AV_OPT_TYPE_INT, { .i64 = -1}, -1, 1, AD, NULL },
|
|
||||||
-#ifdef AACDECODER_LIB_VL0
|
|
||||||
+#if FDKDEC_VER_AT_LEAST(2, 5) // 2.5.10
|
|
||||||
{ "level_limit", "Signal level limiting", OFFSET(level_limit), AV_OPT_TYPE_INT, { .i64 = 0 }, -1, 1, AD },
|
|
||||||
#endif
|
|
||||||
{ NULL }
|
|
||||||
@@ -293,7 +296,7 @@ static av_cold int fdk_aac_decode_init(AVCodecContext *avctx)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
-#ifdef AACDECODER_LIB_VL0
|
|
||||||
+#if FDKDEC_VER_AT_LEAST(2, 5) // 2.5.10
|
|
||||||
if (aacDecoder_SetParam(s->handle, AAC_PCM_LIMITER_ENABLE, s->level_limit) != AAC_DEC_OK) {
|
|
||||||
av_log(avctx, AV_LOG_ERROR, "Unable to set in signal level limiting in the decoder\n");
|
|
||||||
return AVERROR_UNKNOWN;
|
|
||||||
diff --git a/libavcodec/libfdk-aacenc.c b/libavcodec/libfdk-aacenc.c
|
|
||||||
index f5adb407ed..91dcb5a1b9 100644
|
|
||||||
--- a/libavcodec/libfdk-aacenc.c
|
|
||||||
+++ b/libavcodec/libfdk-aacenc.c
|
|
||||||
@@ -156,7 +156,7 @@ static av_cold int aac_encode_init(AVCodecContext *avctx)
|
|
||||||
case 6: mode = MODE_1_2_2_1; sce = 2; cpe = 2; break;
|
|
||||||
/* The version macro is introduced the same time as the 7.1 support, so this
|
|
||||||
should suffice. */
|
|
||||||
-#ifdef AACENCODER_LIB_VL0
|
|
||||||
+#if FDKENC_VER_AT_LEAST(3, 4) // 3.4.12
|
|
||||||
case 8:
|
|
||||||
sce = 2;
|
|
||||||
cpe = 3;
|
|
||||||
@@ -291,7 +291,7 @@ static av_cold int aac_encode_init(AVCodecContext *avctx)
|
|
||||||
}
|
|
||||||
|
|
||||||
avctx->frame_size = info.frameLength;
|
|
||||||
-#if FDKENC_VER_AT_LEAST(4, 0)
|
|
||||||
+#if FDKENC_VER_AT_LEAST(4, 0) // 4.0.0
|
|
||||||
avctx->initial_padding = info.nDelay;
|
|
||||||
#else
|
|
||||||
avctx->initial_padding = info.encoderDelay;
|
|
||||||
@@ -412,7 +412,7 @@ static const uint64_t aac_channel_layout[] = {
|
|
||||||
AV_CH_LAYOUT_4POINT0,
|
|
||||||
AV_CH_LAYOUT_5POINT0_BACK,
|
|
||||||
AV_CH_LAYOUT_5POINT1_BACK,
|
|
||||||
-#ifdef AACENCODER_LIB_VL0
|
|
||||||
+#if FDKENC_VER_AT_LEAST(3, 4) // 3.4.12
|
|
||||||
AV_CH_LAYOUT_7POINT1_WIDE_BACK,
|
|
||||||
AV_CH_LAYOUT_7POINT1,
|
|
||||||
#endif
|
|
||||||
--
|
|
||||||
2.20.1
|
|
||||||
|
|
@ -1,72 +0,0 @@
|
|||||||
From 452746d80fdaaaf1b546860eb78449c6de3678d7 Mon Sep 17 00:00:00 2001
|
|
||||||
From: =?UTF-8?q?Martin=20Storsj=C3=B6?= <martin@martin.st>
|
|
||||||
Date: Wed, 12 Sep 2018 20:03:12 +0300
|
|
||||||
Subject: [PATCH] libfdk-aac: Don't use defined() in a #define
|
|
||||||
MIME-Version: 1.0
|
|
||||||
Content-Type: text/plain; charset=UTF-8
|
|
||||||
Content-Transfer-Encoding: 8bit
|
|
||||||
|
|
||||||
libfdk-aac: Don't use defined() in a #define
|
|
||||||
|
|
||||||
MSVC expands the preprocessor directives differently, making the
|
|
||||||
version check fail in the previous form.
|
|
||||||
|
|
||||||
Clang can warn about this with -Wexpansion-to-defined (not currently
|
|
||||||
enabled by default):
|
|
||||||
warning: macro expansion producing 'defined' has undefined behavior [-Wexpansion-to-defined]
|
|
||||||
|
|
||||||
Downloaded from
|
|
||||||
http://git.videolan.org/?p=ffmpeg.git;a=commitdiff;h=2a9e1c122eed66be1b26b747342b848300b226c7
|
|
||||||
|
|
||||||
Signed-off-by: Martin Storsjö <martin@martin.st>
|
|
||||||
Signed-off-by: Bernd Kuhls <bernd.kuhls@t-online.de>
|
|
||||||
---
|
|
||||||
libavcodec/libfdk-aacdec.c | 9 ++++++---
|
|
||||||
libavcodec/libfdk-aacenc.c | 9 ++++++---
|
|
||||||
2 files changed, 12 insertions(+), 6 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/libavcodec/libfdk-aacdec.c b/libavcodec/libfdk-aacdec.c
|
|
||||||
index ef51184ebd..0fbab36463 100644
|
|
||||||
--- a/libavcodec/libfdk-aacdec.c
|
|
||||||
+++ b/libavcodec/libfdk-aacdec.c
|
|
||||||
@@ -25,10 +25,13 @@
|
|
||||||
#include "avcodec.h"
|
|
||||||
#include "internal.h"
|
|
||||||
|
|
||||||
+#ifdef AACDECODER_LIB_VL0
|
|
||||||
#define FDKDEC_VER_AT_LEAST(vl0, vl1) \
|
|
||||||
- (defined(AACDECODER_LIB_VL0) && \
|
|
||||||
- ((AACDECODER_LIB_VL0 > vl0) || \
|
|
||||||
- (AACDECODER_LIB_VL0 == vl0 && AACDECODER_LIB_VL1 >= vl1)))
|
|
||||||
+ ((AACDECODER_LIB_VL0 > vl0) || \
|
|
||||||
+ (AACDECODER_LIB_VL0 == vl0 && AACDECODER_LIB_VL1 >= vl1))
|
|
||||||
+#else
|
|
||||||
+#define FDKDEC_VER_AT_LEAST(vl0, vl1) 0
|
|
||||||
+#endif
|
|
||||||
|
|
||||||
#if !FDKDEC_VER_AT_LEAST(2, 5) // < 2.5.10
|
|
||||||
#define AAC_PCM_MAX_OUTPUT_CHANNELS AAC_PCM_OUTPUT_CHANNELS
|
|
||||||
diff --git a/libavcodec/libfdk-aacenc.c b/libavcodec/libfdk-aacenc.c
|
|
||||||
index 91dcb5a1b9..8349e56dcb 100644
|
|
||||||
--- a/libavcodec/libfdk-aacenc.c
|
|
||||||
+++ b/libavcodec/libfdk-aacenc.c
|
|
||||||
@@ -26,10 +26,13 @@
|
|
||||||
#include "audio_frame_queue.h"
|
|
||||||
#include "internal.h"
|
|
||||||
|
|
||||||
+#ifdef AACENCODER_LIB_VL0
|
|
||||||
#define FDKENC_VER_AT_LEAST(vl0, vl1) \
|
|
||||||
- (defined(AACENCODER_LIB_VL0) && \
|
|
||||||
- ((AACENCODER_LIB_VL0 > vl0) || \
|
|
||||||
- (AACENCODER_LIB_VL0 == vl0 && AACENCODER_LIB_VL1 >= vl1)))
|
|
||||||
+ ((AACENCODER_LIB_VL0 > vl0) || \
|
|
||||||
+ (AACENCODER_LIB_VL0 == vl0 && AACENCODER_LIB_VL1 >= vl1))
|
|
||||||
+#else
|
|
||||||
+#define FDKENC_VER_AT_LEAST(vl0, vl1) 0
|
|
||||||
+#endif
|
|
||||||
|
|
||||||
typedef struct AACContext {
|
|
||||||
const AVClass *class;
|
|
||||||
--
|
|
||||||
2.20.1
|
|
||||||
|
|
@ -0,0 +1,27 @@
|
|||||||
|
commit 24ae67b3fb9e081b9306c2391a79b4388152332f
|
||||||
|
Author: memeka <mihailescu2m@gmail.com>
|
||||||
|
Date: Thu Oct 19 13:22:18 2017 +1030
|
||||||
|
|
||||||
|
avcodec/v4l2: enable bit rate control for MFC encoder
|
||||||
|
|
||||||
|
Signed-off-by: memeka <mihailescu2m@gmail.com>
|
||||||
|
|
||||||
|
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), "
|
@ -0,0 +1,30 @@
|
|||||||
|
commit 05ee1b8f65e4029fcad832743701712a1a000ea3
|
||||||
|
Author: Joo Aun Saw <jasaw@dius.com.au>
|
||||||
|
Date: Mon Aug 19 15:21:30 2019 +1000
|
||||||
|
|
||||||
|
avcodec/v4l2: add timeout when dequeueing buffers
|
||||||
|
|
||||||
|
Add timeout to prevent lock up when buffer queue is empty.
|
||||||
|
|
||||||
|
diff --git a/libavcodec/v4l2_context.c b/libavcodec/v4l2_context.c
|
||||||
|
index efcb0426e4..8f9420e28d 100644
|
||||||
|
--- a/libavcodec/v4l2_context.c
|
||||||
|
+++ b/libavcodec/v4l2_context.c
|
||||||
|
@@ -580,7 +580,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, -1);
|
||||||
|
+ avbuf = v4l2_dequeue_v4l2buf(ctx, ctx_to_m2mctx(ctx)->draining ? -1 : 0);
|
||||||
|
if (!avbuf) {
|
||||||
|
if (ctx->done)
|
||||||
|
return AVERROR_EOF;
|
||||||
|
@@ -600,7 +600,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, -1);
|
||||||
|
+ avbuf = v4l2_dequeue_v4l2buf(ctx, ctx_to_m2mctx(ctx)->draining ? -1 : 0);
|
||||||
|
if (!avbuf) {
|
||||||
|
if (ctx->done)
|
||||||
|
return AVERROR_EOF;
|
@ -0,0 +1,41 @@
|
|||||||
|
commit 0550486542f4c4628abf9e5cf1090c8f328f215f
|
||||||
|
Author: Dave Stevenson <dave.stevenson@raspberrypi.org>
|
||||||
|
Date: Thu Mar 22 16:01:35 2018 +0000
|
||||||
|
|
||||||
|
v4l2_buffers: Add handling for NV21 and YUV420P
|
||||||
|
|
||||||
|
diff --git a/libavcodec/v4l2_buffers.c b/libavcodec/v4l2_buffers.c
|
||||||
|
index aef911f..0f4dbb2 100644
|
||||||
|
--- a/libavcodec/v4l2_buffers.c
|
||||||
|
+++ b/libavcodec/v4l2_buffers.c
|
||||||
|
@@ -321,11 +321,21 @@ int ff_v4l2_buffer_buf_to_avframe(AVFrame *frame, V4L2Buffer *avbuf)
|
||||||
|
/* 1.1 fixup special cases */
|
||||||
|
switch (avbuf->context->av_pix_fmt) {
|
||||||
|
case AV_PIX_FMT_NV12:
|
||||||
|
+ case AV_PIX_FMT_NV21:
|
||||||
|
if (avbuf->num_planes > 1)
|
||||||
|
break;
|
||||||
|
frame->linesize[1] = avbuf->plane_info[0].bytesperline;
|
||||||
|
frame->data[1] = frame->buf[0]->data + avbuf->plane_info[0].bytesperline * avbuf->context->format.fmt.pix_mp.height;
|
||||||
|
break;
|
||||||
|
+ case AV_PIX_FMT_YUV420P:
|
||||||
|
+ /* No YV12? support? */
|
||||||
|
+ if (avbuf->num_planes > 1)
|
||||||
|
+ break;
|
||||||
|
+ frame->linesize[1] = avbuf->plane_info[0].bytesperline >> 1;
|
||||||
|
+ frame->linesize[2] = avbuf->plane_info[0].bytesperline >> 1;
|
||||||
|
+ frame->data[1] = frame->buf[0]->data + avbuf->plane_info[0].bytesperline * avbuf->context->format.fmt.pix_mp.height;
|
||||||
|
+ frame->data[2] = frame->data[1] + ((avbuf->plane_info[0].bytesperline * avbuf->context->format.fmt.pix_mp.height) >> 2);
|
||||||
|
+ break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
@@ -468,6 +478,7 @@ int ff_v4l2_buffer_enqueue(V4L2Buffer* avbuf)
|
||||||
|
|
||||||
|
avbuf->buf.flags = avbuf->flags;
|
||||||
|
|
||||||
|
+ av_log(NULL, AV_LOG_ERROR, "ff_v4l2_buffer_enqueue: VIDIOC_QBUF : fd %d, index %u type %u\n", buf_to_m2mctx(avbuf)->fd, avbuf->buf.index, avbuf->buf.type);
|
||||||
|
ret = ioctl(buf_to_m2mctx(avbuf)->fd, VIDIOC_QBUF, &avbuf->buf);
|
||||||
|
if (ret < 0)
|
||||||
|
return AVERROR(errno);
|
||||||
|
|
@ -1,5 +1,5 @@
|
|||||||
# Locally calculated
|
# Locally calculated
|
||||||
sha256 741cbd6394eaed370774ca4cc089eaafbc54d0824b9aa360d4b3b0cbcbc4a92c ffmpeg-3.4.5.tar.xz
|
sha256 023f10831a97ad93d798f53a3640e55cd564abfeba807ecbe8524dac4fedecd5 ffmpeg-4.2.tar.xz
|
||||||
sha256 8177f97513213526df2cf6184d8ff986c675afb514d4e68a404010521b880643 COPYING.GPLv2
|
sha256 8177f97513213526df2cf6184d8ff986c675afb514d4e68a404010521b880643 COPYING.GPLv2
|
||||||
sha256 b634ab5640e258563c536e658cad87080553df6f34f62269a21d554844e58bfe COPYING.LGPLv2.1
|
sha256 b634ab5640e258563c536e658cad87080553df6f34f62269a21d554844e58bfe COPYING.LGPLv2.1
|
||||||
sha256 73d99bc83313fff665b426d6672b4e0479102bc402fe22314ac9ce94a38aa5ff LICENSE.md
|
sha256 73d99bc83313fff665b426d6672b4e0479102bc402fe22314ac9ce94a38aa5ff LICENSE.md
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
#
|
#
|
||||||
################################################################################
|
################################################################################
|
||||||
|
|
||||||
FFMPEG_VERSION = 3.4.5
|
FFMPEG_VERSION = 4.2
|
||||||
FFMPEG_SOURCE = ffmpeg-$(FFMPEG_VERSION).tar.xz
|
FFMPEG_SOURCE = ffmpeg-$(FFMPEG_VERSION).tar.xz
|
||||||
FFMPEG_SITE = http://ffmpeg.org/releases
|
FFMPEG_SITE = http://ffmpeg.org/releases
|
||||||
FFMPEG_INSTALL_STAGING = YES
|
FFMPEG_INSTALL_STAGING = YES
|
||||||
@ -84,12 +84,6 @@ else
|
|||||||
FFMPEG_CONF_OPTS += --disable-ffplay
|
FFMPEG_CONF_OPTS += --disable-ffplay
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(BR2_PACKAGE_FFMPEG_FFSERVER),y)
|
|
||||||
FFMPEG_CONF_OPTS += --enable-ffserver
|
|
||||||
else
|
|
||||||
FFMPEG_CONF_OPTS += --disable-ffserver
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(BR2_PACKAGE_FFMPEG_AVRESAMPLE),y)
|
ifeq ($(BR2_PACKAGE_FFMPEG_AVRESAMPLE),y)
|
||||||
FFMPEG_CONF_OPTS += --enable-avresample
|
FFMPEG_CONF_OPTS += --enable-avresample
|
||||||
else
|
else
|
||||||
|
233
package/motion/0002-enable-h264-v4l2m2m.patch
Normal file
233
package/motion/0002-enable-h264-v4l2m2m.patch
Normal file
@ -0,0 +1,233 @@
|
|||||||
|
diff --git a/ffmpeg.c b/ffmpeg.c
|
||||||
|
index 3f731ca..7a42d24 100644
|
||||||
|
--- a/ffmpeg.c
|
||||||
|
+++ b/ffmpeg.c
|
||||||
|
@@ -179,6 +179,14 @@ int my_copy_packet(AVPacket *dest_pkt, AVPacket *src_pkt){
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
/*********************************************/
|
||||||
|
+void my_free_nal_info(struct ffmpeg *ffmpeg){
|
||||||
|
+ if (ffmpeg->nal_info) {
|
||||||
|
+ free(ffmpeg->nal_info);
|
||||||
|
+ ffmpeg->nal_info = NULL;
|
||||||
|
+ ffmpeg->nal_info_len = 0;
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+/*********************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
****************************************************************************
|
||||||
|
@@ -409,6 +417,25 @@ static int ffmpeg_encode_video(struct ffmpeg *ffmpeg){
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ if (ffmpeg->nal_info_separated) {
|
||||||
|
+ // h264_v4l2m2m has NAL units separated from the first frame, which makes
|
||||||
|
+ // some players very unhappy.
|
||||||
|
+ if ((ffmpeg->pkt.pts == 0) && (!(ffmpeg->pkt.flags & AV_PKT_FLAG_KEY))) {
|
||||||
|
+ my_free_nal_info(ffmpeg);
|
||||||
|
+ ffmpeg->nal_info_len = ffmpeg->pkt.size;
|
||||||
|
+ ffmpeg->nal_info = malloc(ffmpeg->nal_info_len);
|
||||||
|
+ if (ffmpeg->nal_info)
|
||||||
|
+ memcpy(ffmpeg->nal_info, &ffmpeg->pkt.data[0], ffmpeg->nal_info_len);
|
||||||
|
+ else
|
||||||
|
+ ffmpeg->nal_info_len = 0;
|
||||||
|
+ } else if (ffmpeg->nal_info) {
|
||||||
|
+ int old_size = ffmpeg->pkt.size;
|
||||||
|
+ av_grow_packet(&ffmpeg->pkt, ffmpeg->nal_info_len);
|
||||||
|
+ memmove(&ffmpeg->pkt.data[ffmpeg->nal_info_len], &ffmpeg->pkt.data[0], old_size);
|
||||||
|
+ memcpy(&ffmpeg->pkt.data[0], ffmpeg->nal_info, ffmpeg->nal_info_len);
|
||||||
|
+ my_free_nal_info(ffmpeg);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
#elif (LIBAVFORMAT_VERSION_MAJOR >= 55) || ((LIBAVFORMAT_VERSION_MAJOR == 54) && (LIBAVFORMAT_VERSION_MINOR > 6))
|
||||||
|
@@ -555,7 +582,9 @@ static int ffmpeg_set_quality(struct ffmpeg *ffmpeg){
|
||||||
|
ffmpeg->quality = 45; // default to 45% quality
|
||||||
|
av_dict_set(&ffmpeg->opts, "preset", "ultrafast", 0);
|
||||||
|
av_dict_set(&ffmpeg->opts, "tune", "zerolatency", 0);
|
||||||
|
- if ((strcmp(ffmpeg->codec->name, "h264_omx") == 0) || (strcmp(ffmpeg->codec->name, "mpeg4_omx") == 0)) {
|
||||||
|
+ if ((strcmp(ffmpeg->codec->name, "h264_omx") == 0) ||
|
||||||
|
+ (strcmp(ffmpeg->codec->name, "mpeg4_omx") == 0) ||
|
||||||
|
+ (strcmp(ffmpeg->codec->name, "h264_v4l2m2m") == 0)) {
|
||||||
|
// H264 OMX encoder quality can only be controlled via bit_rate
|
||||||
|
// bit_rate = ffmpeg->width * ffmpeg->height * ffmpeg->fps * quality_factor
|
||||||
|
ffmpeg->quality = (int)(((int64_t)ffmpeg->width * ffmpeg->height * ffmpeg->fps * ffmpeg->quality) >> 7);
|
||||||
|
@@ -702,13 +731,20 @@ static int ffmpeg_set_codec(struct ffmpeg *ffmpeg){
|
||||||
|
ffmpeg->ctx_codec->height = ffmpeg->height;
|
||||||
|
ffmpeg->ctx_codec->time_base.num = 1;
|
||||||
|
ffmpeg->ctx_codec->time_base.den = ffmpeg->fps;
|
||||||
|
- ffmpeg->ctx_codec->pix_fmt = MY_PIX_FMT_YUV420P;
|
||||||
|
+ if (strcmp(ffmpeg->codec->name, "h264_v4l2m2m") == 0)
|
||||||
|
+ ffmpeg->ctx_codec->pix_fmt = AV_PIX_FMT_NV21;
|
||||||
|
+ else
|
||||||
|
+ ffmpeg->ctx_codec->pix_fmt = MY_PIX_FMT_YUV420P;
|
||||||
|
ffmpeg->ctx_codec->max_b_frames = 0;
|
||||||
|
if (strcmp(ffmpeg->codec_name, "ffv1") == 0){
|
||||||
|
ffmpeg->ctx_codec->strict_std_compliance = -2;
|
||||||
|
ffmpeg->ctx_codec->level = 3;
|
||||||
|
}
|
||||||
|
ffmpeg->ctx_codec->flags |= MY_CODEC_FLAG_GLOBAL_HEADER;
|
||||||
|
+ // h264_v4l2m2m has NAL units separated from the first frame. We need to deal
|
||||||
|
+ // with it appriopriately later
|
||||||
|
+ if (strcmp(ffmpeg->codec->name, "h264_v4l2m2m") == 0)
|
||||||
|
+ ffmpeg->nal_info_separated = 1;
|
||||||
|
|
||||||
|
retcd = ffmpeg_set_quality(ffmpeg);
|
||||||
|
if (retcd < 0){
|
||||||
|
@@ -768,8 +804,69 @@ static int ffmpeg_set_stream(struct ffmpeg *ffmpeg){
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
+
|
||||||
|
+static int ffmpeg_alloc_video_buffer(AVFrame *frame, int align)
|
||||||
|
+{
|
||||||
|
+ const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(frame->format);
|
||||||
|
+ int ret, i, padded_height;
|
||||||
|
+ int plane_padding = FFMAX(16 + 16/*STRIDE_ALIGN*/, align);
|
||||||
|
+
|
||||||
|
+ if (!desc)
|
||||||
|
+ return AVERROR(EINVAL);
|
||||||
|
+
|
||||||
|
+ if ((ret = av_image_check_size(frame->width, frame->height, 0, NULL)) < 0)
|
||||||
|
+ return ret;
|
||||||
|
+
|
||||||
|
+ if (!frame->linesize[0]) {
|
||||||
|
+ if (align <= 0)
|
||||||
|
+ align = 32; /* STRIDE_ALIGN. Should be av_cpu_max_align() */
|
||||||
|
+
|
||||||
|
+ for(i=1; i<=align; i+=i) {
|
||||||
|
+ ret = av_image_fill_linesizes(frame->linesize, frame->format,
|
||||||
|
+ FFALIGN(frame->width, i));
|
||||||
|
+ if (ret < 0)
|
||||||
|
+ return ret;
|
||||||
|
+ if (!(frame->linesize[0] & (align-1)))
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ for (i = 0; i < 4 && frame->linesize[i]; i++)
|
||||||
|
+ frame->linesize[i] = FFALIGN(frame->linesize[i], align);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ padded_height = FFALIGN(frame->height, 32);
|
||||||
|
+ if ((ret = av_image_fill_pointers(frame->data, frame->format, padded_height,
|
||||||
|
+ NULL, frame->linesize)) < 0)
|
||||||
|
+ return ret;
|
||||||
|
+
|
||||||
|
+ frame->buf[0] = av_buffer_alloc(ret + 4*plane_padding);
|
||||||
|
+ if (!frame->buf[0]) {
|
||||||
|
+ ret = AVERROR(ENOMEM);
|
||||||
|
+ av_frame_unref(frame);
|
||||||
|
+ return ret;
|
||||||
|
+ }
|
||||||
|
+ frame->buf[1] = av_buffer_alloc(ret + 4*plane_padding);
|
||||||
|
+ if (!frame->buf[1]) {
|
||||||
|
+ ret = AVERROR(ENOMEM);
|
||||||
|
+ av_frame_unref(frame);
|
||||||
|
+ return ret;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ frame->data[0] = frame->buf[0]->data;
|
||||||
|
+ frame->data[1] = frame->buf[1]->data;
|
||||||
|
+ frame->data[2] = frame->data[1] + ((frame->width * padded_height) / 4);
|
||||||
|
+
|
||||||
|
+ frame->extended_data = frame->data;
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+
|
||||||
|
static int ffmpeg_set_picture(struct ffmpeg *ffmpeg){
|
||||||
|
|
||||||
|
+ int retcd;
|
||||||
|
+ char errstr[128];
|
||||||
|
+
|
||||||
|
ffmpeg->picture = my_frame_alloc();
|
||||||
|
if (!ffmpeg->picture) {
|
||||||
|
MOTION_LOG(ERR, TYPE_ENCODER, NO_ERRNO, _("could not alloc frame"));
|
||||||
|
@@ -789,6 +886,17 @@ static int ffmpeg_set_picture(struct ffmpeg *ffmpeg){
|
||||||
|
ffmpeg->picture->width = ffmpeg->ctx_codec->width;
|
||||||
|
ffmpeg->picture->height = ffmpeg->ctx_codec->height;
|
||||||
|
|
||||||
|
+ // h264_v4l2m2m encoder expects video buffer to be allocated
|
||||||
|
+ if (strcmp(ffmpeg->codec->name, "h264_v4l2m2m") == 0) {
|
||||||
|
+ retcd = ffmpeg_alloc_video_buffer(ffmpeg->picture, 32);
|
||||||
|
+ if (retcd) {
|
||||||
|
+ av_strerror(retcd, errstr, sizeof(errstr));
|
||||||
|
+ MOTION_LOG(ERR, TYPE_ENCODER, NO_ERRNO, _("could not alloc buffers %s"), errstr);
|
||||||
|
+ ffmpeg_free_context(ffmpeg);
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
@@ -891,6 +999,12 @@ static int ffmpeg_flush_codec(struct ffmpeg *ffmpeg){
|
||||||
|
my_packet_unref(ffmpeg->pkt);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
+ // v4l2_m2m encoder uses pts 0 and size 0 to indicate AVERROR_EOF
|
||||||
|
+ if ((ffmpeg->pkt.pts == 0) || (ffmpeg->pkt.size == 0)) {
|
||||||
|
+ recv_cd = AVERROR_EOF;
|
||||||
|
+ my_packet_unref(ffmpeg->pkt);
|
||||||
|
+ continue;
|
||||||
|
+ }
|
||||||
|
retcd = av_write_frame(ffmpeg->oc, &ffmpeg->pkt);
|
||||||
|
if (retcd < 0) {
|
||||||
|
MOTION_LOG(ERR, TYPE_ENCODER, NO_ERRNO
|
||||||
|
@@ -1339,6 +1453,7 @@ void ffmpeg_close(struct ffmpeg *ffmpeg){
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ffmpeg_free_context(ffmpeg);
|
||||||
|
+ my_free_nal_info(ffmpeg);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
@@ -1365,9 +1480,28 @@ int ffmpeg_put_image(struct ffmpeg *ffmpeg, struct image_data *img_data, const s
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Setup pointers and line widths. */
|
||||||
|
- ffmpeg->picture->data[0] = image;
|
||||||
|
- ffmpeg->picture->data[1] = image + (ffmpeg->ctx_codec->width * ffmpeg->ctx_codec->height);
|
||||||
|
- ffmpeg->picture->data[2] = ffmpeg->picture->data[1] + ((ffmpeg->ctx_codec->width * ffmpeg->ctx_codec->height) / 4);
|
||||||
|
+ if (strcmp(ffmpeg->codec->name, "h264_v4l2m2m") == 0) {
|
||||||
|
+ // assume NV21 format
|
||||||
|
+ int cr_len = ffmpeg->ctx_codec->width * ffmpeg->ctx_codec->height / 4;
|
||||||
|
+ unsigned char *imagecr = image + (ffmpeg->ctx_codec->width * ffmpeg->ctx_codec->height);
|
||||||
|
+ unsigned char *imagecb = image + (ffmpeg->ctx_codec->width * ffmpeg->ctx_codec->height) + cr_len;
|
||||||
|
+ int x;
|
||||||
|
+ int y;
|
||||||
|
+ memcpy(ffmpeg->picture->data[0], image, ffmpeg->ctx_codec->width * ffmpeg->ctx_codec->height);
|
||||||
|
+ for (y = 0; y < ffmpeg->ctx_codec->height; y++) {
|
||||||
|
+ for (x = 0; x < ffmpeg->ctx_codec->width/4; x++) {
|
||||||
|
+ ffmpeg->picture->data[1][y*ffmpeg->ctx_codec->width/2 + x*2] = *imagecb;
|
||||||
|
+ ffmpeg->picture->data[1][y*ffmpeg->ctx_codec->width/2 + x*2 + 1] = *imagecr;
|
||||||
|
+ imagecb++;
|
||||||
|
+ imagecr++;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ } else {
|
||||||
|
+ // assume YUV420P format
|
||||||
|
+ ffmpeg->picture->data[0] = image;
|
||||||
|
+ ffmpeg->picture->data[1] = image + (ffmpeg->ctx_codec->width * ffmpeg->ctx_codec->height);
|
||||||
|
+ ffmpeg->picture->data[2] = ffmpeg->picture->data[1] + ((ffmpeg->ctx_codec->width * ffmpeg->ctx_codec->height) / 4);
|
||||||
|
+ }
|
||||||
|
|
||||||
|
ffmpeg->gop_cnt ++;
|
||||||
|
if (ffmpeg->gop_cnt == ffmpeg->ctx_codec->gop_size ){
|
||||||
|
diff --git a/ffmpeg.h b/ffmpeg.h
|
||||||
|
index ca77430..c4ae7bb 100644
|
||||||
|
--- a/ffmpeg.h
|
||||||
|
+++ b/ffmpeg.h
|
||||||
|
@@ -61,6 +61,9 @@ struct ffmpeg {
|
||||||
|
int high_resolution;
|
||||||
|
int motion_images;
|
||||||
|
int passthrough;
|
||||||
|
+ int nal_info_separated;
|
||||||
|
+ char *nal_info;
|
||||||
|
+ int nal_info_len;
|
||||||
|
};
|
||||||
|
#else
|
||||||
|
struct ffmpeg {
|
23
package/motion/0003-ensure-first-frame-pts-zero.patch
Normal file
23
package/motion/0003-ensure-first-frame-pts-zero.patch
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
commit 0cd12918f93fc6559dad56d176a60ddc3f0844d6
|
||||||
|
Author: Joo Aun Saw <jasaw@dius.com.au>
|
||||||
|
Date: Thu Sep 5 14:20:07 2019 +1000
|
||||||
|
|
||||||
|
ffmpeg: ensure first frame PTS is zero
|
||||||
|
|
||||||
|
diff --git a/ffmpeg.c b/ffmpeg.c
|
||||||
|
index 7a42d24..665aa00 100644
|
||||||
|
--- a/ffmpeg.c
|
||||||
|
+++ b/ffmpeg.c
|
||||||
|
@@ -512,7 +512,11 @@ static int ffmpeg_set_pts(struct ffmpeg *ffmpeg, const struct timeval *tv1){
|
||||||
|
ffmpeg_reset_movie_start_time(ffmpeg, tv1);
|
||||||
|
pts_interval = 0;
|
||||||
|
}
|
||||||
|
- ffmpeg->picture->pts = av_rescale_q(pts_interval,(AVRational){1, 1000000L},ffmpeg->video_st->time_base) + ffmpeg->base_pts;
|
||||||
|
+ if (ffmpeg->last_pts < 0) {
|
||||||
|
+ // This is the very first frame, ensure PTS is zero
|
||||||
|
+ ffmpeg->picture->pts = 0;
|
||||||
|
+ } else
|
||||||
|
+ ffmpeg->picture->pts = av_rescale_q(pts_interval,(AVRational){1, 1000000L},ffmpeg->video_st->time_base) + ffmpeg->base_pts;
|
||||||
|
|
||||||
|
if (ffmpeg->test_mode == TRUE){
|
||||||
|
MOTION_LOG(INF, TYPE_ENCODER, NO_ERRNO
|
202
package/motion/1001-decouple-avcodec-send-and-receive.patch
Normal file
202
package/motion/1001-decouple-avcodec-send-and-receive.patch
Normal file
@ -0,0 +1,202 @@
|
|||||||
|
diff --git a/ffmpeg.c b/ffmpeg.c
|
||||||
|
index 665aa00..1246fdc 100644
|
||||||
|
--- a/ffmpeg.c
|
||||||
|
+++ b/ffmpeg.c
|
||||||
|
@@ -386,6 +386,14 @@ static int ffmpeg_get_oformat(struct ffmpeg *ffmpeg){
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static int ffmpeg_write_packet(struct ffmpeg *ffmpeg){
|
||||||
|
+ if (ffmpeg->tlapse == TIMELAPSE_APPEND) {
|
||||||
|
+ return ffmpeg_timelapse_append(ffmpeg, ffmpeg->pkt);
|
||||||
|
+ } else {
|
||||||
|
+ return av_write_frame(ffmpeg->oc, &ffmpeg->pkt);
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static int ffmpeg_encode_video(struct ffmpeg *ffmpeg){
|
||||||
|
|
||||||
|
#if (LIBAVFORMAT_VERSION_MAJOR >= 58) || ((LIBAVFORMAT_VERSION_MAJOR == 57) && (LIBAVFORMAT_VERSION_MINOR >= 41))
|
||||||
|
@@ -400,41 +408,49 @@ static int ffmpeg_encode_video(struct ffmpeg *ffmpeg){
|
||||||
|
,_("Error sending frame for encoding:%s"),errstr);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
- retcd = avcodec_receive_packet(ffmpeg->ctx_codec, &ffmpeg->pkt);
|
||||||
|
- if (retcd == AVERROR(EAGAIN)){
|
||||||
|
- //Buffered packet. Throw special return code
|
||||||
|
- av_strerror(retcd, errstr, sizeof(errstr));
|
||||||
|
- MOTION_LOG(DBG, TYPE_ENCODER, NO_ERRNO
|
||||||
|
- ,_("Receive packet threw EAGAIN returning -2 code :%s"),errstr);
|
||||||
|
- my_packet_unref(ffmpeg->pkt);
|
||||||
|
- return -2;
|
||||||
|
- }
|
||||||
|
- if (retcd < 0 ){
|
||||||
|
- av_strerror(retcd, errstr, sizeof(errstr));
|
||||||
|
- MOTION_LOG(ERR, TYPE_ENCODER, NO_ERRNO
|
||||||
|
- ,_("Error receiving encoded packet video:%s"),errstr);
|
||||||
|
- //Packet is freed upon failure of encoding
|
||||||
|
- return -1;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- if (ffmpeg->nal_info_separated) {
|
||||||
|
- // h264_v4l2m2m has NAL units separated from the first frame, which makes
|
||||||
|
- // some players very unhappy.
|
||||||
|
- if ((ffmpeg->pkt.pts == 0) && (!(ffmpeg->pkt.flags & AV_PKT_FLAG_KEY))) {
|
||||||
|
- my_free_nal_info(ffmpeg);
|
||||||
|
- ffmpeg->nal_info_len = ffmpeg->pkt.size;
|
||||||
|
- ffmpeg->nal_info = malloc(ffmpeg->nal_info_len);
|
||||||
|
- if (ffmpeg->nal_info)
|
||||||
|
- memcpy(ffmpeg->nal_info, &ffmpeg->pkt.data[0], ffmpeg->nal_info_len);
|
||||||
|
- else
|
||||||
|
- ffmpeg->nal_info_len = 0;
|
||||||
|
- } else if (ffmpeg->nal_info) {
|
||||||
|
- int old_size = ffmpeg->pkt.size;
|
||||||
|
- av_grow_packet(&ffmpeg->pkt, ffmpeg->nal_info_len);
|
||||||
|
- memmove(&ffmpeg->pkt.data[ffmpeg->nal_info_len], &ffmpeg->pkt.data[0], old_size);
|
||||||
|
- memcpy(&ffmpeg->pkt.data[0], ffmpeg->nal_info, ffmpeg->nal_info_len);
|
||||||
|
- my_free_nal_info(ffmpeg);
|
||||||
|
+ while (retcd >= 0) {
|
||||||
|
+ av_init_packet(&ffmpeg->pkt);
|
||||||
|
+ ffmpeg->pkt.data = NULL;
|
||||||
|
+ ffmpeg->pkt.size = 0;
|
||||||
|
+ retcd = avcodec_receive_packet(ffmpeg->ctx_codec, &ffmpeg->pkt);
|
||||||
|
+ if (retcd == AVERROR(EAGAIN)){
|
||||||
|
+ //Buffered packet. Throw special return code
|
||||||
|
+ my_packet_unref(ffmpeg->pkt);
|
||||||
|
+ return -2;
|
||||||
|
}
|
||||||
|
+ if (retcd < 0 ){
|
||||||
|
+ av_strerror(retcd, errstr, sizeof(errstr));
|
||||||
|
+ MOTION_LOG(ERR, TYPE_ENCODER, NO_ERRNO, "Error receiving encoded packet video:%s",errstr);
|
||||||
|
+ my_packet_unref(ffmpeg->pkt);
|
||||||
|
+ return -1;
|
||||||
|
+ } else {
|
||||||
|
+ if (ffmpeg->nal_info_separated) {
|
||||||
|
+ // h264_v4l2m2m has NAL units separated from the first frame, which makes
|
||||||
|
+ // some players very unhappy.
|
||||||
|
+ if ((ffmpeg->pkt.pts == 0) && (!(ffmpeg->pkt.flags & AV_PKT_FLAG_KEY))) {
|
||||||
|
+ my_free_nal_info(ffmpeg);
|
||||||
|
+ ffmpeg->nal_info_len = ffmpeg->pkt.size;
|
||||||
|
+ ffmpeg->nal_info = malloc(ffmpeg->nal_info_len);
|
||||||
|
+ if (ffmpeg->nal_info)
|
||||||
|
+ memcpy(ffmpeg->nal_info, &ffmpeg->pkt.data[0], ffmpeg->nal_info_len);
|
||||||
|
+ else
|
||||||
|
+ ffmpeg->nal_info_len = 0;
|
||||||
|
+ } else if (ffmpeg->nal_info) {
|
||||||
|
+ int old_size = ffmpeg->pkt.size;
|
||||||
|
+ av_grow_packet(&ffmpeg->pkt, ffmpeg->nal_info_len);
|
||||||
|
+ memmove(&ffmpeg->pkt.data[ffmpeg->nal_info_len], &ffmpeg->pkt.data[0], old_size);
|
||||||
|
+ memcpy(&ffmpeg->pkt.data[0], ffmpeg->nal_info, ffmpeg->nal_info_len);
|
||||||
|
+ my_free_nal_info(ffmpeg);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ if (ffmpeg_write_packet(ffmpeg) < 0) {
|
||||||
|
+ MOTION_LOG(ERR, TYPE_ENCODER, NO_ERRNO, "Error while writing video frame");
|
||||||
|
+ my_packet_unref(ffmpeg->pkt);
|
||||||
|
+ ffmpeg_free_context(ffmpeg);
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ my_packet_unref(ffmpeg->pkt);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
@@ -444,11 +460,15 @@ static int ffmpeg_encode_video(struct ffmpeg *ffmpeg){
|
||||||
|
char errstr[128];
|
||||||
|
int got_packet_ptr;
|
||||||
|
|
||||||
|
+ av_init_packet(&ffmpeg->pkt);
|
||||||
|
+ ffmpeg->pkt.data = NULL;
|
||||||
|
+ ffmpeg->pkt.size = 0;
|
||||||
|
+
|
||||||
|
retcd = avcodec_encode_video2(ffmpeg->ctx_codec, &ffmpeg->pkt, ffmpeg->picture, &got_packet_ptr);
|
||||||
|
if (retcd < 0 ){
|
||||||
|
av_strerror(retcd, errstr, sizeof(errstr));
|
||||||
|
MOTION_LOG(ERR, TYPE_ENCODER, NO_ERRNO, _("Error encoding video:%s"),errstr);
|
||||||
|
- //Packet is freed upon failure of encoding
|
||||||
|
+ my_packet_unref(ffmpeg->pkt);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (got_packet_ptr == 0){
|
||||||
|
@@ -457,6 +477,15 @@ static int ffmpeg_encode_video(struct ffmpeg *ffmpeg){
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ retcd = ffmpeg_write_packet(ffmpeg);
|
||||||
|
+ if (retcd < 0) {
|
||||||
|
+ MOTION_LOG(ERR, TYPE_ENCODER, NO_ERRNO, "Error while writing video frame");
|
||||||
|
+ my_packet_unref(ffmpeg->pkt);
|
||||||
|
+ ffmpeg_free_context(ffmpeg);
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+ my_packet_unref(ffmpeg->pkt);
|
||||||
|
+
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
#else
|
||||||
|
@@ -465,6 +494,10 @@ static int ffmpeg_encode_video(struct ffmpeg *ffmpeg){
|
||||||
|
uint8_t *video_outbuf;
|
||||||
|
int video_outbuf_size;
|
||||||
|
|
||||||
|
+ av_init_packet(&ffmpeg->pkt);
|
||||||
|
+ ffmpeg->pkt.data = NULL;
|
||||||
|
+ ffmpeg->pkt.size = 0;
|
||||||
|
+
|
||||||
|
video_outbuf_size = (ffmpeg->ctx_codec->width +16) * (ffmpeg->ctx_codec->height +16) * 1;
|
||||||
|
video_outbuf = mymalloc(video_outbuf_size);
|
||||||
|
|
||||||
|
@@ -490,6 +523,17 @@ static int ffmpeg_encode_video(struct ffmpeg *ffmpeg){
|
||||||
|
ffmpeg->pkt.pts = ffmpeg->picture->pts;
|
||||||
|
ffmpeg->pkt.dts = ffmpeg->pkt.pts;
|
||||||
|
|
||||||
|
+ retcd = ffmpeg_write_packet(ffmpeg);
|
||||||
|
+ if (retcd < 0) {
|
||||||
|
+ av_strerror(retcd, errstr, sizeof(errstr));
|
||||||
|
+ MOTION_LOG(ERR, TYPE_ENCODER, NO_ERRNO, "Error while writing video frame");
|
||||||
|
+ my_packet_unref(ffmpeg->pkt);
|
||||||
|
+ free(video_outbuf);
|
||||||
|
+ ffmpeg_free_context(ffmpeg);
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ my_packet_unref(ffmpeg->pkt);
|
||||||
|
free(video_outbuf);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
@@ -1034,14 +1078,9 @@ static int ffmpeg_flush_codec(struct ffmpeg *ffmpeg){
|
||||||
|
static int ffmpeg_put_frame(struct ffmpeg *ffmpeg, const struct timeval *tv1){
|
||||||
|
int retcd;
|
||||||
|
|
||||||
|
- av_init_packet(&ffmpeg->pkt);
|
||||||
|
- ffmpeg->pkt.data = NULL;
|
||||||
|
- ffmpeg->pkt.size = 0;
|
||||||
|
-
|
||||||
|
retcd = ffmpeg_set_pts(ffmpeg, tv1);
|
||||||
|
if (retcd < 0) {
|
||||||
|
//If there is an error, it has already been reported.
|
||||||
|
- my_packet_unref(ffmpeg->pkt);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -1050,21 +1089,9 @@ static int ffmpeg_put_frame(struct ffmpeg *ffmpeg, const struct timeval *tv1){
|
||||||
|
if (retcd != -2){
|
||||||
|
MOTION_LOG(ERR, TYPE_ENCODER, NO_ERRNO, _("Error while encoding picture"));
|
||||||
|
}
|
||||||
|
- my_packet_unref(ffmpeg->pkt);
|
||||||
|
return retcd;
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (ffmpeg->tlapse == TIMELAPSE_APPEND) {
|
||||||
|
- retcd = ffmpeg_timelapse_append(ffmpeg, ffmpeg->pkt);
|
||||||
|
- } else {
|
||||||
|
- retcd = av_write_frame(ffmpeg->oc, &ffmpeg->pkt);
|
||||||
|
- }
|
||||||
|
- my_packet_unref(ffmpeg->pkt);
|
||||||
|
-
|
||||||
|
- if (retcd < 0) {
|
||||||
|
- MOTION_LOG(ERR, TYPE_ENCODER, NO_ERRNO, _("Error while writing video frame"));
|
||||||
|
- return -1;
|
||||||
|
- }
|
||||||
|
return retcd;
|
||||||
|
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user