mirror of
https://github.com/motioneye-project/motioneyeos.git
synced 2025-07-29 14:16:31 +00:00
motion: drain codec at end of recording
This commit is contained in:
parent
d9fb726710
commit
ea56807852
76
package/motion/0010-set-pts-before-encode.patch
Normal file
76
package/motion/0010-set-pts-before-encode.patch
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
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 {
|
176
package/motion/0011-decouple-avcodec-send-receive.patch
Normal file
176
package/motion/0011-decouple-avcodec-send-receive.patch
Normal file
@ -0,0 +1,176 @@
|
|||||||
|
diff --git a/ffmpeg.c b/ffmpeg.c
|
||||||
|
index 739bcb3..0e44c97 100644
|
||||||
|
--- a/ffmpeg.c
|
||||||
|
+++ b/ffmpeg.c
|
||||||
|
@@ -324,6 +324,15 @@ 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))
|
||||||
|
@@ -331,27 +340,41 @@ static int ffmpeg_encode_video(struct ffmpeg *ffmpeg){
|
||||||
|
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, ffmpeg->picture);
|
||||||
|
if (retcd < 0 ){
|
||||||
|
av_strerror(retcd, errstr, sizeof(errstr));
|
||||||
|
MOTION_LOG(ERR, TYPE_ENCODER, NO_ERRNO, "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
|
||||||
|
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->picture->key_frame == 1)
|
||||||
|
- ffmpeg->pkt.flags |= AV_PKT_FLAG_KEY;
|
||||||
|
+ 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 (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);
|
||||||
|
+ ffmpeg_free_context(ffmpeg);
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
|
||||||
|
+ my_packet_unref(ffmpeg->pkt);
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
#elif (LIBAVFORMAT_VERSION_MAJOR >= 55) || ((LIBAVFORMAT_VERSION_MAJOR == 54) && (LIBAVFORMAT_VERSION_MINOR > 6))
|
||||||
|
@@ -360,11 +383,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){
|
||||||
|
@@ -376,6 +403,15 @@ static int ffmpeg_encode_video(struct ffmpeg *ffmpeg){
|
||||||
|
if (ffmpeg->picture->key_frame == 1)
|
||||||
|
ffmpeg->pkt.flags |= AV_PKT_FLAG_KEY;
|
||||||
|
|
||||||
|
+ 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
|
||||||
|
@@ -384,6 +420,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);
|
||||||
|
|
||||||
|
@@ -407,6 +447,16 @@ static int ffmpeg_encode_video(struct ffmpeg *ffmpeg){
|
||||||
|
|
||||||
|
free(video_outbuf);
|
||||||
|
|
||||||
|
+ 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);
|
||||||
|
+ ffmpeg_free_context(ffmpeg);
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ my_packet_unref(ffmpeg->pkt);
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
@@ -697,36 +747,18 @@ static int ffmpeg_set_outputfile(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 -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 {
|
||||||
|
- 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;
|
||||||
|
- }
|
||||||
|
return retcd;
|
||||||
|
|
||||||
|
}
|
68
package/motion/0012-drain-codec.patch
Normal file
68
package/motion/0012-drain-codec.patch
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
diff --git a/ffmpeg.c b/ffmpeg.c
|
||||||
|
index 0e44c97..e5a2b9e 100644
|
||||||
|
--- a/ffmpeg.c
|
||||||
|
+++ b/ffmpeg.c
|
||||||
|
@@ -463,6 +463,55 @@ static int ffmpeg_encode_video(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){
|
||||||
|
|
||||||
|
int64_t pts_interval;
|
||||||
|
@@ -894,6 +943,7 @@ void ffmpeg_close(struct ffmpeg *ffmpeg){
|
||||||
|
#ifdef HAVE_FFMPEG
|
||||||
|
|
||||||
|
if (ffmpeg != NULL) {
|
||||||
|
+ ffmpeg_drain_codec(ffmpeg);
|
||||||
|
if (ffmpeg->tlapse != TIMELAPSE_APPEND) {
|
||||||
|
av_write_trailer(ffmpeg->oc);
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user