mirror of
https://github.com/motioneye-project/motioneyeos.git
synced 2025-07-28 13:46:32 +00:00
motion: updated patches to match motion version
This commit is contained in:
parent
4e045cb1d5
commit
5e743f3477
@ -1,76 +0,0 @@
|
||||
commit 2c072634efd8e3b7fb70a1d85cd54e9befe96dd2
|
||||
Author: Joo Aun Saw <jasaw@dius.com.au>
|
||||
Date: Tue Sep 5 11:09:41 2017 +1000
|
||||
|
||||
set PTS value before encoding
|
||||
|
||||
diff --git a/ffmpeg.c b/ffmpeg.c
|
||||
index 87b4f75..739bcb3 100644
|
||||
--- a/ffmpeg.c
|
||||
+++ b/ffmpeg.c
|
||||
@@ -419,8 +419,7 @@ static int ffmpeg_set_pts(struct ffmpeg *ffmpeg, const struct timeval *tv1){
|
||||
|
||||
if (ffmpeg->tlapse != TIMELAPSE_NONE) {
|
||||
ffmpeg->last_pts++;
|
||||
- ffmpeg->pkt.pts = ffmpeg->last_pts;
|
||||
- ffmpeg->pkt.dts = ffmpeg->last_pts;
|
||||
+ ffmpeg->picture->pts = ffmpeg->last_pts;
|
||||
} else {
|
||||
pts_interval = ((1000000L * (tv1->tv_sec - ffmpeg->start_time.tv_sec)) + tv1->tv_usec - ffmpeg->start_time.tv_usec);
|
||||
if (pts_interval < 0){
|
||||
@@ -428,23 +427,22 @@ static int ffmpeg_set_pts(struct ffmpeg *ffmpeg, const struct timeval *tv1){
|
||||
ffmpeg_reset_movie_start_time(ffmpeg, tv1);
|
||||
pts_interval = 0;
|
||||
}
|
||||
- ffmpeg->pkt.pts = av_rescale_q(pts_interval,(AVRational){1, 1000000L},ffmpeg->video_st->time_base) + ffmpeg->base_pts;
|
||||
+ ffmpeg->picture->pts = av_rescale_q(pts_interval,(AVRational){1, 1000000L},ffmpeg->video_st->time_base) + ffmpeg->base_pts;
|
||||
|
||||
if (ffmpeg->test_mode == 1){
|
||||
MOTION_LOG(INF, TYPE_ENCODER, NO_ERRNO, "PTS %"PRId64" Base PTS %"PRId64" ms interval %"PRId64" timebase %d-%d",
|
||||
- ffmpeg->pkt.pts,ffmpeg->base_pts,pts_interval,
|
||||
+ ffmpeg->picture->pts,ffmpeg->base_pts,pts_interval,
|
||||
ffmpeg->video_st->time_base.num,ffmpeg->video_st->time_base.den);
|
||||
}
|
||||
|
||||
- if (ffmpeg->pkt.pts <= ffmpeg->last_pts){
|
||||
+ if (ffmpeg->picture->pts <= ffmpeg->last_pts){
|
||||
//We have a problem with our motion loop timing and sending frames or the rounding into the PTS.
|
||||
if (ffmpeg->test_mode == 1){
|
||||
MOTION_LOG(INF, TYPE_ENCODER, NO_ERRNO, "BAD TIMING!! Frame skipped.");
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
- ffmpeg->pkt.dts = ffmpeg->pkt.pts;
|
||||
- ffmpeg->last_pts = ffmpeg->pkt.pts;
|
||||
+ ffmpeg->last_pts = ffmpeg->picture->pts;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -703,13 +701,6 @@ static int ffmpeg_put_frame(struct ffmpeg *ffmpeg, const struct timeval *tv1){
|
||||
ffmpeg->pkt.data = NULL;
|
||||
ffmpeg->pkt.size = 0;
|
||||
|
||||
- retcd = ffmpeg_encode_video(ffmpeg);
|
||||
- if (retcd != 0){
|
||||
- MOTION_LOG(ERR, TYPE_ENCODER, NO_ERRNO, "Error while encoding picture");
|
||||
- my_packet_unref(ffmpeg->pkt);
|
||||
- return retcd;
|
||||
- }
|
||||
-
|
||||
retcd = ffmpeg_set_pts(ffmpeg, tv1);
|
||||
if (retcd < 0) {
|
||||
//If there is an error, it has already been reported.
|
||||
@@ -717,6 +708,13 @@ static int ffmpeg_put_frame(struct ffmpeg *ffmpeg, const struct timeval *tv1){
|
||||
return -1;
|
||||
}
|
||||
|
||||
+ retcd = ffmpeg_encode_video(ffmpeg);
|
||||
+ if (retcd != 0){
|
||||
+ 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 {
|
@ -1,11 +1,5 @@
|
||||
commit 52b6beab2975ec609c7a072b1ed037a84ea92c14
|
||||
Author: Joo Aun Saw <jasaw@dius.com.au>
|
||||
Date: Tue Sep 12 15:29:28 2017 +1000
|
||||
|
||||
do not force packet keyframe
|
||||
|
||||
diff --git a/ffmpeg.c b/ffmpeg.c
|
||||
index 739bcb3..dac1d6d 100644
|
||||
index 739bcb3..aa17ddc 100644
|
||||
--- a/ffmpeg.c
|
||||
+++ b/ffmpeg.c
|
||||
@@ -349,8 +349,6 @@ static int ffmpeg_encode_video(struct ffmpeg *ffmpeg){
|
||||
@ -27,13 +21,20 @@ index 739bcb3..dac1d6d 100644
|
||||
return 0;
|
||||
|
||||
#else
|
||||
@@ -402,9 +397,6 @@ static int ffmpeg_encode_video(struct ffmpeg *ffmpeg){
|
||||
@@ -399,12 +394,16 @@ static int ffmpeg_encode_video(struct ffmpeg *ffmpeg){
|
||||
return -2;
|
||||
}
|
||||
|
||||
+ // Encoder did not provide metadata, set it up manually
|
||||
ffmpeg->pkt.size = retcd;
|
||||
ffmpeg->pkt.data = video_outbuf;
|
||||
|
||||
- if (ffmpeg->picture->key_frame == 1)
|
||||
- ffmpeg->pkt.flags |= AV_PKT_FLAG_KEY;
|
||||
-
|
||||
if (ffmpeg->picture->key_frame == 1)
|
||||
ffmpeg->pkt.flags |= AV_PKT_FLAG_KEY;
|
||||
|
||||
+ ffmpeg->pkt.pts = ffmpeg->picture->pts;
|
||||
+ ffmpeg->pkt.dts = ffmpeg->pkt.pts;
|
||||
+
|
||||
free(video_outbuf);
|
||||
|
||||
return 0;
|
||||
|
@ -1,14 +1,14 @@
|
||||
commit e9e7cf1bc641202d8babe09204857ffff8e497c5
|
||||
commit 2220065f0e2240e963aeb9bc99fd7c233ea2834d
|
||||
Author: Joo Aun Saw <jasaw@dius.com.au>
|
||||
Date: Tue Sep 12 16:04:09 2017 +1000
|
||||
Date: Mon Sep 18 14:21:36 2017 +1000
|
||||
|
||||
decouple avcodec send receive
|
||||
|
||||
diff --git a/ffmpeg.c b/ffmpeg.c
|
||||
index dac1d6d..6cd48fa 100644
|
||||
index 560e7d4..aa06bef 100644
|
||||
--- a/ffmpeg.c
|
||||
+++ b/ffmpeg.c
|
||||
@@ -324,6 +324,15 @@ static int ffmpeg_get_oformat(struct ffmpeg *ffmpeg){
|
||||
@@ -341,6 +341,15 @@ static int ffmpeg_get_oformat(struct ffmpeg *ffmpeg){
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -24,7 +24,7 @@ index dac1d6d..6cd48fa 100644
|
||||
static int ffmpeg_encode_video(struct ffmpeg *ffmpeg){
|
||||
|
||||
#if (LIBAVFORMAT_VERSION_MAJOR >= 58) || ((LIBAVFORMAT_VERSION_MAJOR == 57) && (LIBAVFORMAT_VERSION_MINOR >= 41))
|
||||
@@ -331,25 +340,41 @@ static int ffmpeg_encode_video(struct ffmpeg *ffmpeg){
|
||||
@@ -348,25 +357,41 @@ static int ffmpeg_encode_video(struct ffmpeg *ffmpeg){
|
||||
int retcd = 0;
|
||||
char errstr[128];
|
||||
|
||||
@ -77,7 +77,7 @@ index dac1d6d..6cd48fa 100644
|
||||
return 0;
|
||||
|
||||
#elif (LIBAVFORMAT_VERSION_MAJOR >= 55) || ((LIBAVFORMAT_VERSION_MAJOR == 54) && (LIBAVFORMAT_VERSION_MINOR > 6))
|
||||
@@ -358,11 +383,15 @@ static int ffmpeg_encode_video(struct ffmpeg *ffmpeg){
|
||||
@@ -375,11 +400,15 @@ static int ffmpeg_encode_video(struct ffmpeg *ffmpeg){
|
||||
char errstr[128];
|
||||
int got_packet_ptr;
|
||||
|
||||
@ -94,7 +94,7 @@ index dac1d6d..6cd48fa 100644
|
||||
return -1;
|
||||
}
|
||||
if (got_packet_ptr == 0){
|
||||
@@ -371,6 +400,15 @@ static int ffmpeg_encode_video(struct ffmpeg *ffmpeg){
|
||||
@@ -388,6 +417,15 @@ static int ffmpeg_encode_video(struct ffmpeg *ffmpeg){
|
||||
return -2;
|
||||
}
|
||||
|
||||
@ -110,7 +110,7 @@ index dac1d6d..6cd48fa 100644
|
||||
return 0;
|
||||
|
||||
#else
|
||||
@@ -379,6 +417,10 @@ static int ffmpeg_encode_video(struct ffmpeg *ffmpeg){
|
||||
@@ -396,6 +434,10 @@ static int ffmpeg_encode_video(struct ffmpeg *ffmpeg){
|
||||
uint8_t *video_outbuf;
|
||||
int video_outbuf_size;
|
||||
|
||||
@ -121,9 +121,9 @@ index dac1d6d..6cd48fa 100644
|
||||
video_outbuf_size = (ffmpeg->ctx_codec->width +16) * (ffmpeg->ctx_codec->height +16) * 1;
|
||||
video_outbuf = mymalloc(video_outbuf_size);
|
||||
|
||||
@@ -397,8 +439,18 @@ static int ffmpeg_encode_video(struct ffmpeg *ffmpeg){
|
||||
ffmpeg->pkt.size = retcd;
|
||||
ffmpeg->pkt.data = video_outbuf;
|
||||
@@ -421,8 +463,18 @@ static int ffmpeg_encode_video(struct ffmpeg *ffmpeg){
|
||||
ffmpeg->pkt.pts = ffmpeg->picture->pts;
|
||||
ffmpeg->pkt.dts = ffmpeg->pkt.pts;
|
||||
|
||||
- free(video_outbuf);
|
||||
+ retcd = ffmpeg_write_packet(ffmpeg);
|
||||
@ -141,7 +141,7 @@ index dac1d6d..6cd48fa 100644
|
||||
return 0;
|
||||
|
||||
#endif
|
||||
@@ -689,36 +741,18 @@ static int ffmpeg_set_outputfile(struct ffmpeg *ffmpeg){
|
||||
@@ -759,35 +811,16 @@ static int ffmpeg_set_outputfile(struct ffmpeg *ffmpeg){
|
||||
static int ffmpeg_put_frame(struct ffmpeg *ffmpeg, const struct timeval *tv1){
|
||||
int retcd;
|
||||
|
||||
@ -153,7 +153,7 @@ index dac1d6d..6cd48fa 100644
|
||||
if (retcd < 0) {
|
||||
//If there is an error, it has already been reported.
|
||||
- my_packet_unref(ffmpeg->pkt);
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
retcd = ffmpeg_encode_video(ffmpeg);
|
||||
@ -167,17 +167,16 @@ index dac1d6d..6cd48fa 100644
|
||||
- retcd = ffmpeg_timelapse_append(ffmpeg, ffmpeg->pkt);
|
||||
- } else {
|
||||
- retcd = av_write_frame(ffmpeg->oc, &ffmpeg->pkt);
|
||||
+ if (retcd < 0){
|
||||
+ if (retcd != -2)
|
||||
+ MOTION_LOG(ERR, TYPE_ENCODER, NO_ERRNO, "Error while encoding picture");
|
||||
}
|
||||
- }
|
||||
- my_packet_unref(ffmpeg->pkt);
|
||||
|
||||
-
|
||||
- if (retcd < 0) {
|
||||
- MOTION_LOG(ERR, TYPE_ENCODER, NO_ERRNO, "Error while writing video frame");
|
||||
- ffmpeg_free_context(ffmpeg);
|
||||
- return -1;
|
||||
- }
|
||||
+ if (retcd < 0){
|
||||
+ if (retcd != -2)
|
||||
+ MOTION_LOG(ERR, TYPE_ENCODER, NO_ERRNO, "Error while encoding picture");
|
||||
}
|
||||
return retcd;
|
||||
|
||||
}
|
||||
|
@ -1,68 +1,101 @@
|
||||
commit 9c604dc427804b9620044a2bdddca1b8c1831627
|
||||
Author: Joo Aun Saw <jasaw@dius.com.au>
|
||||
Date: Mon Sep 18 14:30:22 2017 +1000
|
||||
|
||||
drain codec at end of recording
|
||||
|
||||
diff --git a/ffmpeg.c b/ffmpeg.c
|
||||
index 0e44c97..e5a2b9e 100644
|
||||
index aa06bef..c690896 100644
|
||||
--- a/ffmpeg.c
|
||||
+++ b/ffmpeg.c
|
||||
@@ -463,6 +463,55 @@ static int ffmpeg_encode_video(struct ffmpeg *ffmpeg){
|
||||
|
||||
@@ -350,7 +350,7 @@ static int ffmpeg_write_packet(struct ffmpeg *ffmpeg){
|
||||
}
|
||||
}
|
||||
|
||||
+static int ffmpeg_drain_codec(struct ffmpeg *ffmpeg){
|
||||
+
|
||||
+#if (LIBAVFORMAT_VERSION_MAJOR >= 58) || ((LIBAVFORMAT_VERSION_MAJOR == 57) && (LIBAVFORMAT_VERSION_MINOR >= 41))
|
||||
+ //ffmpeg version 3.1 and after
|
||||
+ int retcd = 0;
|
||||
+ char errstr[128];
|
||||
+
|
||||
+ av_init_packet(&ffmpeg->pkt);
|
||||
+ ffmpeg->pkt.data = NULL;
|
||||
+ ffmpeg->pkt.size = 0;
|
||||
+
|
||||
+ retcd = avcodec_send_frame(ffmpeg->ctx_codec, NULL);
|
||||
+ if (retcd < 0 ){
|
||||
+ av_strerror(retcd, errstr, sizeof(errstr));
|
||||
+ MOTION_LOG(ERR, TYPE_ENCODER, NO_ERRNO, "Error draining codec:%s",errstr);
|
||||
+ my_packet_unref(ffmpeg->pkt);
|
||||
+ return -1;
|
||||
+ }
|
||||
+ for (;;) {
|
||||
+ retcd = avcodec_receive_packet(ffmpeg->ctx_codec, &ffmpeg->pkt);
|
||||
+ if (retcd == AVERROR_EOF)
|
||||
+ break;
|
||||
+ 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 {
|
||||
+ 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);
|
||||
+ return -1;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ my_packet_unref(ffmpeg->pkt);
|
||||
+ return 0;
|
||||
+
|
||||
+#else
|
||||
+
|
||||
+ // do nothing
|
||||
+ return 0;
|
||||
+
|
||||
+#endif
|
||||
+
|
||||
+}
|
||||
+
|
||||
static int ffmpeg_set_pts(struct ffmpeg *ffmpeg, const struct timeval *tv1){
|
||||
-static int ffmpeg_encode_video(struct ffmpeg *ffmpeg){
|
||||
+static int ffmpeg_encode_video(struct ffmpeg *ffmpeg, AVFrame *picture){
|
||||
|
||||
int64_t pts_interval;
|
||||
@@ -894,6 +943,7 @@ void ffmpeg_close(struct ffmpeg *ffmpeg){
|
||||
#if (LIBAVFORMAT_VERSION_MAJOR >= 58) || ((LIBAVFORMAT_VERSION_MAJOR == 57) && (LIBAVFORMAT_VERSION_MINOR >= 41))
|
||||
//ffmpeg version 3.1 and after
|
||||
@@ -361,7 +361,7 @@ static int ffmpeg_encode_video(struct ffmpeg *ffmpeg){
|
||||
ffmpeg->pkt.data = NULL;
|
||||
ffmpeg->pkt.size = 0;
|
||||
|
||||
- retcd = avcodec_send_frame(ffmpeg->ctx_codec, ffmpeg->picture);
|
||||
+ retcd = avcodec_send_frame(ffmpeg->ctx_codec, picture);
|
||||
if (retcd < 0 ){
|
||||
av_strerror(retcd, errstr, sizeof(errstr));
|
||||
MOTION_LOG(ERR, TYPE_ENCODER, NO_ERRNO, "Error sending frame for encoding:%s",errstr);
|
||||
@@ -370,10 +370,15 @@ static int ffmpeg_encode_video(struct ffmpeg *ffmpeg){
|
||||
}
|
||||
while (retcd >= 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 (picture == NULL) {
|
||||
+ if (retcd == AVERROR_EOF)
|
||||
+ break;
|
||||
+ } else {
|
||||
+ 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));
|
||||
@@ -404,7 +409,7 @@ static int ffmpeg_encode_video(struct ffmpeg *ffmpeg){
|
||||
ffmpeg->pkt.data = NULL;
|
||||
ffmpeg->pkt.size = 0;
|
||||
|
||||
- retcd = avcodec_encode_video2(ffmpeg->ctx_codec, &ffmpeg->pkt, ffmpeg->picture, &got_packet_ptr);
|
||||
+ retcd = avcodec_encode_video2(ffmpeg->ctx_codec, &ffmpeg->pkt, 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);
|
||||
@@ -441,7 +446,7 @@ static int ffmpeg_encode_video(struct ffmpeg *ffmpeg){
|
||||
video_outbuf_size = (ffmpeg->ctx_codec->width +16) * (ffmpeg->ctx_codec->height +16) * 1;
|
||||
video_outbuf = mymalloc(video_outbuf_size);
|
||||
|
||||
- retcd = avcodec_encode_video(ffmpeg->video_st->codec, video_outbuf, video_outbuf_size, ffmpeg->picture);
|
||||
+ retcd = avcodec_encode_video(ffmpeg->video_st->codec, video_outbuf, video_outbuf_size, picture);
|
||||
if (retcd < 0 ){
|
||||
MOTION_LOG(ERR, TYPE_ENCODER, NO_ERRNO, "Error encoding video");
|
||||
my_packet_unref(ffmpeg->pkt);
|
||||
@@ -457,11 +462,12 @@ static int ffmpeg_encode_video(struct ffmpeg *ffmpeg){
|
||||
ffmpeg->pkt.size = retcd;
|
||||
ffmpeg->pkt.data = video_outbuf;
|
||||
|
||||
- if (ffmpeg->picture->key_frame == 1)
|
||||
- ffmpeg->pkt.flags |= AV_PKT_FLAG_KEY;
|
||||
-
|
||||
- ffmpeg->pkt.pts = ffmpeg->picture->pts;
|
||||
- ffmpeg->pkt.dts = ffmpeg->pkt.pts;
|
||||
+ if (picture) {
|
||||
+ if (picture->key_frame == 1)
|
||||
+ ffmpeg->pkt.flags |= AV_PKT_FLAG_KEY;
|
||||
+ ffmpeg->pkt.pts = picture->pts;
|
||||
+ ffmpeg->pkt.dts = ffmpeg->pkt.pts;
|
||||
+ }
|
||||
|
||||
retcd = ffmpeg_write_packet(ffmpeg);
|
||||
if (retcd < 0) {
|
||||
@@ -817,7 +823,7 @@ static int ffmpeg_put_frame(struct ffmpeg *ffmpeg, const struct timeval *tv1){
|
||||
return 0;
|
||||
}
|
||||
|
||||
- retcd = ffmpeg_encode_video(ffmpeg);
|
||||
+ retcd = ffmpeg_encode_video(ffmpeg, ffmpeg->picture);
|
||||
if (retcd < 0){
|
||||
if (retcd != -2)
|
||||
MOTION_LOG(ERR, TYPE_ENCODER, NO_ERRNO, "Error while encoding picture");
|
||||
@@ -957,6 +963,7 @@ void ffmpeg_close(struct ffmpeg *ffmpeg){
|
||||
#ifdef HAVE_FFMPEG
|
||||
|
||||
if (ffmpeg != NULL) {
|
||||
+ ffmpeg_drain_codec(ffmpeg);
|
||||
+ ffmpeg_encode_video(ffmpeg, NULL); // drain codec
|
||||
if (ffmpeg->tlapse != TIMELAPSE_APPEND) {
|
||||
av_write_trailer(ffmpeg->oc);
|
||||
}
|
||||
|
13
package/motion/enable-h264-omx-codec.patch
Normal file
13
package/motion/enable-h264-omx-codec.patch
Normal file
@ -0,0 +1,13 @@
|
||||
diff --git a/ffmpeg.c b/ffmpeg.c
|
||||
index a729cda..798c017 100644
|
||||
--- a/ffmpeg.c
|
||||
+++ b/ffmpeg.c
|
||||
@@ -513,7 +513,7 @@ static int ffmpeg_codec_is_blacklisted(const char *codec_name){
|
||||
* - remove the "h264_omx" from this blacklist.
|
||||
* More information: https://github.com/Motion-Project/motion/issues/433
|
||||
*/
|
||||
- "h264_omx",
|
||||
+ //"h264_omx",
|
||||
};
|
||||
size_t i;
|
||||
|
@ -1,151 +0,0 @@
|
||||
diff --git a/ffmpeg.c b/ffmpeg.c
|
||||
index 87b4f75..f3c685a 100644
|
||||
--- a/ffmpeg.c
|
||||
+++ b/ffmpeg.c
|
||||
@@ -236,12 +236,24 @@ static void ffmpeg_free_context(struct ffmpeg *ffmpeg){
|
||||
|
||||
static int ffmpeg_get_oformat(struct ffmpeg *ffmpeg){
|
||||
|
||||
+ size_t codec_name_len = strcspn(ffmpeg->codec_name, ":");
|
||||
+ char *codec_name = malloc(codec_name_len + 1);
|
||||
+
|
||||
+ if (codec_name == NULL) {
|
||||
+ MOTION_LOG(ERR, TYPE_ENCODER, NO_ERRNO, "Failed to allocate memory for codec name");
|
||||
+ ffmpeg_free_context(ffmpeg);
|
||||
+ return -1;
|
||||
+ }
|
||||
+ memcpy(codec_name, ffmpeg->codec_name, codec_name_len);
|
||||
+ codec_name[codec_name_len] = 0;
|
||||
+
|
||||
/* Only the newer codec and containers can handle the really fast FPS */
|
||||
- if (((strcmp(ffmpeg->codec_name, "msmpeg4") == 0) ||
|
||||
- (strcmp(ffmpeg->codec_name, "mpeg4") == 0) ||
|
||||
- (strcmp(ffmpeg->codec_name, "swf") == 0) ) && (ffmpeg->fps >50)){
|
||||
+ if (((strcmp(codec_name, "msmpeg4") == 0) ||
|
||||
+ (strcmp(codec_name, "mpeg4") == 0) ||
|
||||
+ (strcmp(codec_name, "swf") == 0) ) && (ffmpeg->fps >50)){
|
||||
MOTION_LOG(ERR, TYPE_ENCODER, NO_ERRNO, "The frame rate specified is too high for the ffmpeg movie type specified. Choose a different ffmpeg container or lower framerate.");
|
||||
ffmpeg_free_context(ffmpeg);
|
||||
+ free(codec_name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -250,59 +262,61 @@ static int ffmpeg_get_oformat(struct ffmpeg *ffmpeg){
|
||||
if (ffmpeg->oc->oformat) ffmpeg->oc->oformat->video_codec = MY_CODEC_ID_MPEG2VIDEO;
|
||||
strncat(ffmpeg->filename, ".mpg", 4);
|
||||
if (!ffmpeg->oc->oformat) {
|
||||
- MOTION_LOG(ERR, TYPE_ENCODER, NO_ERRNO, "ffmpeg_video_codec option value %s is not supported", ffmpeg->codec_name);
|
||||
+ MOTION_LOG(ERR, TYPE_ENCODER, NO_ERRNO, "ffmpeg_video_codec option value %s is not supported", codec_name);
|
||||
ffmpeg_free_context(ffmpeg);
|
||||
+ free(codec_name);
|
||||
return -1;
|
||||
}
|
||||
+ free(codec_name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
- if (strcmp(ffmpeg->codec_name, "mpeg4") == 0) {
|
||||
+ if (strcmp(codec_name, "mpeg4") == 0) {
|
||||
ffmpeg->oc->oformat = av_guess_format("avi", NULL, NULL);
|
||||
strncat(ffmpeg->filename, ".avi", 4);
|
||||
}
|
||||
|
||||
- if (strcmp(ffmpeg->codec_name, "msmpeg4") == 0) {
|
||||
+ if (strcmp(codec_name, "msmpeg4") == 0) {
|
||||
ffmpeg->oc->oformat = av_guess_format("avi", NULL, NULL);
|
||||
strncat(ffmpeg->filename, ".avi", 4);
|
||||
if (ffmpeg->oc->oformat) ffmpeg->oc->oformat->video_codec = MY_CODEC_ID_MSMPEG4V2;
|
||||
}
|
||||
|
||||
- if (strcmp(ffmpeg->codec_name, "swf") == 0) {
|
||||
+ if (strcmp(codec_name, "swf") == 0) {
|
||||
ffmpeg->oc->oformat = av_guess_format("swf", NULL, NULL);
|
||||
strncat(ffmpeg->filename, ".swf", 4);
|
||||
}
|
||||
|
||||
- if (strcmp(ffmpeg->codec_name, "flv") == 0) {
|
||||
+ if (strcmp(codec_name, "flv") == 0) {
|
||||
ffmpeg->oc->oformat = av_guess_format("flv", NULL, NULL);
|
||||
strncat(ffmpeg->filename, ".flv", 4);
|
||||
if (ffmpeg->oc->oformat) ffmpeg->oc->oformat->video_codec = MY_CODEC_ID_FLV1;
|
||||
}
|
||||
|
||||
- if (strcmp(ffmpeg->codec_name, "ffv1") == 0) {
|
||||
+ if (strcmp(codec_name, "ffv1") == 0) {
|
||||
ffmpeg->oc->oformat = av_guess_format("avi", NULL, NULL);
|
||||
strncat(ffmpeg->filename, ".avi", 4);
|
||||
if (ffmpeg->oc->oformat) ffmpeg->oc->oformat->video_codec = MY_CODEC_ID_FFV1;
|
||||
}
|
||||
|
||||
- if (strcmp(ffmpeg->codec_name, "mov") == 0) {
|
||||
+ if (strcmp(codec_name, "mov") == 0) {
|
||||
ffmpeg->oc->oformat = av_guess_format("mov", NULL, NULL);
|
||||
strncat(ffmpeg->filename, ".mov", 4);
|
||||
}
|
||||
|
||||
- if (strcmp(ffmpeg->codec_name, "mp4") == 0) {
|
||||
+ if (strcmp(codec_name, "mp4") == 0) {
|
||||
ffmpeg->oc->oformat = av_guess_format("mp4", NULL, NULL);
|
||||
strncat(ffmpeg->filename, ".mp4", 4);
|
||||
if (ffmpeg->oc->oformat) ffmpeg->oc->oformat->video_codec = MY_CODEC_ID_H264;
|
||||
}
|
||||
|
||||
- if (strcmp(ffmpeg->codec_name, "mkv") == 0) {
|
||||
+ if (strcmp(codec_name, "mkv") == 0) {
|
||||
ffmpeg->oc->oformat = av_guess_format("matroska", NULL, NULL);
|
||||
strncat(ffmpeg->filename, ".mkv", 4);
|
||||
if (ffmpeg->oc->oformat) ffmpeg->oc->oformat->video_codec = MY_CODEC_ID_H264;
|
||||
}
|
||||
|
||||
- if (strcmp(ffmpeg->codec_name, "hevc") == 0) {
|
||||
+ if (strcmp(codec_name, "hevc") == 0) {
|
||||
ffmpeg->oc->oformat = av_guess_format("mp4", NULL, NULL);
|
||||
strncat(ffmpeg->filename, ".mp4", 4);
|
||||
if (ffmpeg->oc->oformat) ffmpeg->oc->oformat->video_codec = MY_CODEC_ID_HEVC;
|
||||
@@ -310,17 +324,20 @@ static int ffmpeg_get_oformat(struct ffmpeg *ffmpeg){
|
||||
|
||||
//Check for valid results
|
||||
if (!ffmpeg->oc->oformat) {
|
||||
- MOTION_LOG(ERR, TYPE_ENCODER, NO_ERRNO, "codec option value %s is not supported", ffmpeg->codec_name);
|
||||
+ MOTION_LOG(ERR, TYPE_ENCODER, NO_ERRNO, "codec option value %s is not supported", codec_name);
|
||||
ffmpeg_free_context(ffmpeg);
|
||||
+ free(codec_name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ffmpeg->oc->oformat->video_codec == MY_CODEC_ID_NONE) {
|
||||
MOTION_LOG(ERR, TYPE_ENCODER, NO_ERRNO, "Could not get the codec");
|
||||
ffmpeg_free_context(ffmpeg);
|
||||
+ free(codec_name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
+ free(codec_name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -484,13 +501,23 @@ static int ffmpeg_set_codec(struct ffmpeg *ffmpeg){
|
||||
int retcd;
|
||||
char errstr[128];
|
||||
int chkrate;
|
||||
+ size_t codec_name_len = strcspn(ffmpeg->codec_name, ":");
|
||||
|
||||
- ffmpeg->codec = avcodec_find_encoder(ffmpeg->oc->oformat->video_codec);
|
||||
+ ffmpeg->codec = NULL;
|
||||
+ if (ffmpeg->codec_name[codec_name_len]) {
|
||||
+ ffmpeg->codec = avcodec_find_encoder_by_name(&ffmpeg->codec_name[codec_name_len+1]);
|
||||
+ if (!ffmpeg->codec)
|
||||
+ MOTION_LOG(WRN, TYPE_ENCODER, NO_ERRNO, "Preferred codec %s not found", &ffmpeg->codec_name[codec_name_len+1]);
|
||||
+ }
|
||||
+ if (!ffmpeg->codec)
|
||||
+ ffmpeg->codec = avcodec_find_encoder(ffmpeg->oc->oformat->video_codec);
|
||||
if (!ffmpeg->codec) {
|
||||
MOTION_LOG(ERR, TYPE_ENCODER, NO_ERRNO, "Codec %s not found", ffmpeg->codec_name);
|
||||
ffmpeg_free_context(ffmpeg);
|
||||
return -1;
|
||||
}
|
||||
+ if (ffmpeg->codec_name[codec_name_len])
|
||||
+ MOTION_LOG(NTC, TYPE_ENCODER, NO_ERRNO, "Using codec %s", ffmpeg->codec->name);
|
||||
|
||||
#if (LIBAVFORMAT_VERSION_MAJOR >= 58) || ((LIBAVFORMAT_VERSION_MAJOR == 57) && (LIBAVFORMAT_VERSION_MINOR >= 41))
|
||||
//If we provide the codec to this, it results in a memory leak. ffmpeg ticket: 5714
|
@ -1,53 +0,0 @@
|
||||
diff --git a/ffmpeg.c b/ffmpeg.c
|
||||
index 87b4f75..4816adf 100644
|
||||
--- a/ffmpeg.c
|
||||
+++ b/ffmpeg.c
|
||||
@@ -451,21 +451,30 @@ static int ffmpeg_set_pts(struct ffmpeg *ffmpeg, const struct timeval *tv1){
|
||||
|
||||
static int ffmpeg_set_quality(struct ffmpeg *ffmpeg){
|
||||
|
||||
- char crf[4];
|
||||
-
|
||||
ffmpeg->opts = 0;
|
||||
if (ffmpeg->vbr > 100) ffmpeg->vbr = 100;
|
||||
if (ffmpeg->ctx_codec->codec_id == MY_CODEC_ID_H264 ||
|
||||
ffmpeg->ctx_codec->codec_id == MY_CODEC_ID_HEVC){
|
||||
- if (ffmpeg->vbr > 0) {
|
||||
- ffmpeg->vbr = (int)(( (100-ffmpeg->vbr) * 51)/100);
|
||||
+ if (ffmpeg->vbr <= 0)
|
||||
+ ffmpeg->vbr = 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)) {
|
||||
+ // H264 OMX encoder quality can only be controlled via bit_rate
|
||||
+ // bit_rate = ffmpeg->width * ffmpeg->height * ffmpeg->fps * quality_factor
|
||||
+ ffmpeg->vbr = (ffmpeg->width * ffmpeg->height * ffmpeg->fps * ffmpeg->vbr) >> 7;
|
||||
+ // Clip bit rate to min
|
||||
+ if (ffmpeg->vbr < 4000) // magic number
|
||||
+ ffmpeg->vbr = 4000;
|
||||
+ ffmpeg->ctx_codec->profile = FF_PROFILE_H264_HIGH;
|
||||
+ ffmpeg->ctx_codec->bit_rate = ffmpeg->vbr;
|
||||
} else {
|
||||
- ffmpeg->vbr = 28;
|
||||
+ // Control other H264 encoders quality via CRF
|
||||
+ char crf[4];
|
||||
+ ffmpeg->vbr = (int)(( (100-ffmpeg->vbr) * 51)/100);
|
||||
+ snprintf(crf, 4, "%d", ffmpeg->vbr);
|
||||
+ av_dict_set(&ffmpeg->opts, "crf", crf, 0);
|
||||
}
|
||||
- snprintf(crf, 4, "%d",ffmpeg->vbr);
|
||||
- av_dict_set(&ffmpeg->opts, "preset", "ultrafast", 0);
|
||||
- av_dict_set(&ffmpeg->opts, "tune", "zerolatency", 0);
|
||||
- av_dict_set(&ffmpeg->opts, "crf", crf, 0);
|
||||
} else {
|
||||
/* The selection of 8000 in the else is a subjective number based upon viewing output files */
|
||||
if (ffmpeg->vbr > 0){
|
||||
@@ -474,7 +483,7 @@ static int ffmpeg_set_quality(struct ffmpeg *ffmpeg){
|
||||
ffmpeg->ctx_codec->global_quality=ffmpeg->vbr;
|
||||
}
|
||||
}
|
||||
- MOTION_LOG(INF, TYPE_ENCODER, NO_ERRNO, "vbr/crf for codec: %d", ffmpeg->vbr);
|
||||
+ MOTION_LOG(INF, TYPE_ENCODER, NO_ERRNO, "%s codec vbr/crf/bit_rate: %d", ffmpeg->codec->name, ffmpeg->vbr);
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user