1 /*
2 *
3 * ffmpeg.c
4 *
5 * This software is distributed under the GNU Public License version 2
6 * See also the file 'COPYING'.
7 *
8 * The contents of this file has been derived from output_example.c
9 * and apiexample.c from the FFmpeg distribution.
10 *
11 * This file has been modified so that only major versions greater than
12 * 53 are supported.
13 * Note that while the conditions are based upon LIBAVFORMAT, not all of the changes are
14 * specific to libavformat.h. Some changes could be related to other components of ffmpeg.
15 * This is for simplicity. The avformat version has historically changed at the same time
16 * as the other components so it is easier to have a single version number to track rather
17 * than the particular version numbers which are associated with each component.
18 * The libav variant also has different apis with the same major/minor version numbers.
19 * As such, it is occasionally necessary to look at the microversion number. Numbers
20 * greater than 100 for micro version indicate ffmpeg whereas numbers less than 100
21 * indicate libav
22 */
23
24 #include "translate.h"
25 #include "motion.h"
26
27 #ifdef HAVE_FFMPEG
28
29 /****************************************************************************
30 * The section below is the "my" section of functions.
31 * These are designed to be extremely simple version specific
32 * variants of the libav functions.
33 ****************************************************************************/
34 #if (LIBAVFORMAT_VERSION_MAJOR >= 55) || ((LIBAVFORMAT_VERSION_MAJOR == 54) && (LIBAVFORMAT_VERSION_MINOR > 6))
35
36 #define MY_FLAG_READ AVIO_FLAG_READ
37 #define MY_FLAG_WRITE AVIO_FLAG_WRITE
38 #define MY_FLAG_READ_WRITE AVIO_FLAG_READ_WRITE
39
40 #else //Older versions
41
42 #define MY_FLAG_READ URL_RDONLY
43 #define MY_FLAG_WRITE URL_WRONLY
44 #define MY_FLAG_READ_WRITE URL_RDWR
45
46 #endif
47 /*********************************************/
48 #if (LIBAVFORMAT_VERSION_MAJOR >= 56)
49
50 #define MY_CODEC_ID_MSMPEG4V2 AV_CODEC_ID_MSMPEG4V2
51 #define MY_CODEC_ID_FLV1 AV_CODEC_ID_FLV1
52 #define MY_CODEC_ID_FFV1 AV_CODEC_ID_FFV1
53 #define MY_CODEC_ID_NONE AV_CODEC_ID_NONE
54 #define MY_CODEC_ID_MPEG2VIDEO AV_CODEC_ID_MPEG2VIDEO
55 #define MY_CODEC_ID_H264 AV_CODEC_ID_H264
56 #define MY_CODEC_ID_HEVC AV_CODEC_ID_HEVC
57
58 #else
59
60 #define MY_CODEC_ID_MSMPEG4V2 CODEC_ID_MSMPEG4V2
61 #define MY_CODEC_ID_FLV1 CODEC_ID_FLV1
62 #define MY_CODEC_ID_FFV1 CODEC_ID_FFV1
63 #define MY_CODEC_ID_NONE CODEC_ID_NONE
64 #define MY_CODEC_ID_MPEG2VIDEO CODEC_ID_MPEG2VIDEO
65 #define MY_CODEC_ID_H264 CODEC_ID_H264
66 #define MY_CODEC_ID_HEVC CODEC_ID_H264
67
68 #endif
69
70 /*********************************************/
71 #if (LIBAVCODEC_VERSION_MAJOR >= 57)
72
73 #define MY_CODEC_FLAG_GLOBAL_HEADER AV_CODEC_FLAG_GLOBAL_HEADER
74 #define MY_CODEC_FLAG_QSCALE AV_CODEC_FLAG_QSCALE
75
76 #else
77
78 #define MY_CODEC_FLAG_GLOBAL_HEADER CODEC_FLAG_GLOBAL_HEADER
79 #define MY_CODEC_FLAG_QSCALE CODEC_FLAG_QSCALE
80
81 #endif
82
83 /*********************************************/
my_frame_alloc(void)84 AVFrame *my_frame_alloc(void){
85 AVFrame *pic;
86 #if (LIBAVFORMAT_VERSION_MAJOR >= 55)
87 pic = av_frame_alloc();
88 #else
89 pic = avcodec_alloc_frame();
90 #endif
91 return pic;
92 }
93 /*********************************************/
my_frame_free(AVFrame * frame)94 void my_frame_free(AVFrame *frame){
95 #if (LIBAVFORMAT_VERSION_MAJOR >= 55)
96 av_frame_free(&frame);
97 #else
98 av_freep(&frame);
99 #endif
100 }
101 /*********************************************/
my_image_get_buffer_size(enum MyPixelFormat pix_fmt,int width,int height)102 int my_image_get_buffer_size(enum MyPixelFormat pix_fmt, int width, int height){
103 int retcd = 0;
104 #if (LIBAVFORMAT_VERSION_MAJOR >= 57)
105 int align = 1;
106 retcd = av_image_get_buffer_size(pix_fmt, width, height, align);
107 #else
108 retcd = avpicture_get_size(pix_fmt, width, height);
109 #endif
110 return retcd;
111 }
112 /*********************************************/
my_image_copy_to_buffer(AVFrame * frame,uint8_t * buffer_ptr,enum MyPixelFormat pix_fmt,int width,int height,int dest_size)113 int my_image_copy_to_buffer(AVFrame *frame, uint8_t *buffer_ptr, enum MyPixelFormat pix_fmt,int width, int height,int dest_size){
114 int retcd = 0;
115 #if (LIBAVFORMAT_VERSION_MAJOR >= 57)
116 int align = 1;
117 retcd = av_image_copy_to_buffer((uint8_t *)buffer_ptr,dest_size
118 ,(const uint8_t * const*)frame,frame->linesize,pix_fmt,width,height,align);
119 #else
120 retcd = avpicture_layout((const AVPicture*)frame,pix_fmt,width,height
121 ,(unsigned char *)buffer_ptr,dest_size);
122 #endif
123 return retcd;
124 }
125 /*********************************************/
my_image_fill_arrays(AVFrame * frame,uint8_t * buffer_ptr,enum MyPixelFormat pix_fmt,int width,int height)126 int my_image_fill_arrays(AVFrame *frame,uint8_t *buffer_ptr,enum MyPixelFormat pix_fmt,int width,int height){
127 int retcd = 0;
128 #if (LIBAVFORMAT_VERSION_MAJOR >= 57)
129 int align = 1;
130 retcd = av_image_fill_arrays(
131 frame->data
132 ,frame->linesize
133 ,buffer_ptr
134 ,pix_fmt
135 ,width
136 ,height
137 ,align
138 );
139 #else
140 retcd = avpicture_fill(
141 (AVPicture *)frame
142 ,buffer_ptr
143 ,pix_fmt
144 ,width
145 ,height);
146 #endif
147 return retcd;
148 }
149 /*********************************************/
my_packet_unref(AVPacket pkt)150 void my_packet_unref(AVPacket pkt){
151 #if (LIBAVFORMAT_VERSION_MAJOR >= 57)
152 av_packet_unref(&pkt);
153 #else
154 av_free_packet(&pkt);
155 #endif
156 }
157 /*********************************************/
my_avcodec_close(AVCodecContext * codec_context)158 void my_avcodec_close(AVCodecContext *codec_context){
159 #if (LIBAVFORMAT_VERSION_MAJOR >= 58) || ((LIBAVFORMAT_VERSION_MAJOR == 57) && (LIBAVFORMAT_VERSION_MINOR >= 41))
160 avcodec_free_context(&codec_context);
161 #else
162 avcodec_close(codec_context);
163 #endif
164 }
165 /*********************************************/
my_copy_packet(AVPacket * dest_pkt,AVPacket * src_pkt)166 int my_copy_packet(AVPacket *dest_pkt, AVPacket *src_pkt){
167 #if (LIBAVFORMAT_VERSION_MAJOR >= 55)
168 return av_packet_ref(dest_pkt, src_pkt);
169 #else
170 /* Old versions of libav do not support copying packet
171 * We therefore disable the pass through recording and
172 * for this function, simply do not do anything
173 */
174 if (dest_pkt == src_pkt ){
175 return 0;
176 } else {
177 return 0;
178 }
179 #endif
180 }
181 /*********************************************/
182
183 /****************************************************************************
184 ****************************************************************************
185 ****************************************************************************/
186 /*********************************************/
ffmpeg_free_nal(struct ffmpeg * ffmpeg)187 static void ffmpeg_free_nal(struct ffmpeg *ffmpeg){
188 if (ffmpeg->nal_info) {
189 free(ffmpeg->nal_info);
190 ffmpeg->nal_info = NULL;
191 ffmpeg->nal_info_len = 0;
192 }
193 }
194
ffmpeg_encode_nal(struct ffmpeg * ffmpeg)195 static int ffmpeg_encode_nal(struct ffmpeg *ffmpeg){
196 // h264_v4l2m2m has NAL units separated from the first frame, which makes
197 // some players very unhappy.
198 if ((ffmpeg->pkt.pts == 0) && (!(ffmpeg->pkt.flags & AV_PKT_FLAG_KEY))) {
199 ffmpeg_free_nal(ffmpeg);
200 ffmpeg->nal_info_len = ffmpeg->pkt.size;
201 ffmpeg->nal_info = malloc(ffmpeg->nal_info_len);
202 if (ffmpeg->nal_info) {
203 memcpy(ffmpeg->nal_info, &ffmpeg->pkt.data[0], ffmpeg->nal_info_len);
204 return 1;
205 } else
206 ffmpeg->nal_info_len = 0;
207 } else if (ffmpeg->nal_info) {
208 int old_size = ffmpeg->pkt.size;
209 av_grow_packet(&ffmpeg->pkt, ffmpeg->nal_info_len);
210 memmove(&ffmpeg->pkt.data[ffmpeg->nal_info_len], &ffmpeg->pkt.data[0], old_size);
211 memcpy(&ffmpeg->pkt.data[0], ffmpeg->nal_info, ffmpeg->nal_info_len);
212 ffmpeg_free_nal(ffmpeg);
213 }
214 return 0;
215 }
216
ffmpeg_timelapse_exists(const char * fname)217 static int ffmpeg_timelapse_exists(const char *fname){
218 FILE *file;
219 file = fopen(fname, "r");
220 if (file)
221 {
222 fclose(file);
223 return 1;
224 }
225 return 0;
226 }
227
ffmpeg_timelapse_append(struct ffmpeg * ffmpeg,AVPacket pkt)228 static int ffmpeg_timelapse_append(struct ffmpeg *ffmpeg, AVPacket pkt){
229 FILE *file;
230
231 file = fopen(ffmpeg->filename, "a");
232 if (!file) return -1;
233
234 fwrite(pkt.data,1,pkt.size,file);
235
236 fclose(file);
237
238 return 0;
239 }
240
241 #if (LIBAVFORMAT_VERSION_MAJOR < 58)
242 /* TODO Determine if this is even needed for old versions. Per
243 * documentation for version 58, 'av_lockmgr_register This function does nothing'
244 */
ffmpeg_lockmgr_cb(void ** arg,enum AVLockOp op)245 static int ffmpeg_lockmgr_cb(void **arg, enum AVLockOp op){
246 pthread_mutex_t *mutex = *arg;
247 int err;
248
249 switch (op) {
250 case AV_LOCK_CREATE:
251 mutex = malloc(sizeof(*mutex));
252 if (!mutex)
253 return AVERROR(ENOMEM);
254 if ((err = pthread_mutex_init(mutex, NULL))) {
255 free(mutex);
256 return AVERROR(err);
257 }
258 *arg = mutex;
259 return 0;
260 case AV_LOCK_OBTAIN:
261 if ((err = pthread_mutex_lock(mutex)))
262 return AVERROR(err);
263
264 return 0;
265 case AV_LOCK_RELEASE:
266 if ((err = pthread_mutex_unlock(mutex)))
267 return AVERROR(err);
268
269 return 0;
270 case AV_LOCK_DESTROY:
271 if (mutex)
272 pthread_mutex_destroy(mutex);
273 free(mutex);
274 *arg = NULL;
275 return 0;
276 }
277 return 1;
278 }
279 #endif
280
ffmpeg_free_context(struct ffmpeg * ffmpeg)281 static void ffmpeg_free_context(struct ffmpeg *ffmpeg){
282
283 if (ffmpeg->picture != NULL){
284 my_frame_free(ffmpeg->picture);
285 ffmpeg->picture = NULL;
286 }
287
288 if (ffmpeg->ctx_codec != NULL){
289 my_avcodec_close(ffmpeg->ctx_codec);
290 ffmpeg->ctx_codec = NULL;
291 }
292
293 if (ffmpeg->oc != NULL){
294 avformat_free_context(ffmpeg->oc);
295 ffmpeg->oc = NULL;
296 }
297
298 }
299
ffmpeg_get_oformat(struct ffmpeg * ffmpeg)300 static int ffmpeg_get_oformat(struct ffmpeg *ffmpeg){
301
302 size_t codec_name_len = strcspn(ffmpeg->codec_name, ":");
303 char *codec_name = malloc(codec_name_len + 1);
304 char basename[PATH_MAX];
305 int retcd;
306
307 /* TODO: Rework the extenstion asssignment along with the code in event.c
308 * If extension is ever something other than three bytes,
309 * preceded by . then lots of things will fail
310 */
311 if (codec_name == NULL) {
312 MOTION_LOG(ERR, TYPE_ENCODER, NO_ERRNO
313 ,_("Failed to allocate memory for codec name"));
314 ffmpeg_free_context(ffmpeg);
315 return -1;
316 }
317 memcpy(codec_name, ffmpeg->codec_name, codec_name_len);
318 codec_name[codec_name_len] = 0;
319
320 /* Only the newer codec and containers can handle the really fast FPS */
321 if (((strcmp(codec_name, "msmpeg4") == 0) ||
322 (strcmp(codec_name, "mpeg4") == 0) ||
323 (strcmp(codec_name, "swf") == 0) ) && (ffmpeg->fps >50)){
324 MOTION_LOG(ERR, TYPE_ENCODER, NO_ERRNO
325 ,_("The frame rate specified is too high for the ffmpeg movie type specified. "
326 "Choose a different ffmpeg container or lower framerate."));
327 ffmpeg_free_context(ffmpeg);
328 free(codec_name);
329 return -1;
330 }
331
332 retcd = snprintf(basename,PATH_MAX,"%s",ffmpeg->filename);
333 if ((retcd < 0) || (retcd >= PATH_MAX)){
334 MOTION_LOG(ERR, TYPE_ENCODER, NO_ERRNO
335 ,_("Error setting base file name"));
336 ffmpeg_free_context(ffmpeg);
337 free(codec_name);
338 return -1;
339 }
340
341 if (ffmpeg->tlapse == TIMELAPSE_APPEND){
342 ffmpeg->oc->oformat = av_guess_format ("mpeg2video", NULL, NULL);
343 if (ffmpeg->oc->oformat) ffmpeg->oc->oformat->video_codec = MY_CODEC_ID_MPEG2VIDEO;
344 retcd = snprintf(ffmpeg->filename,PATH_MAX,"%s.mpg",basename);
345 if ((!ffmpeg->oc->oformat) ||
346 (retcd < 0) || (retcd >= PATH_MAX)){
347 MOTION_LOG(ERR, TYPE_ENCODER, NO_ERRNO
348 ,_("Error setting timelapse append for codec %s"), codec_name);
349 ffmpeg_free_context(ffmpeg);
350 free(codec_name);
351 return -1;
352 }
353 free(codec_name);
354 return 0;
355 }
356
357 if (strcmp(codec_name, "mpeg4") == 0) {
358 ffmpeg->oc->oformat = av_guess_format("avi", NULL, NULL);
359 retcd = snprintf(ffmpeg->filename,PATH_MAX,"%s.avi",basename);
360 }
361
362 if (strcmp(codec_name, "msmpeg4") == 0) {
363 ffmpeg->oc->oformat = av_guess_format("avi", NULL, NULL);
364 retcd = snprintf(ffmpeg->filename,PATH_MAX,"%s.avi",basename);
365 if (ffmpeg->oc->oformat) ffmpeg->oc->oformat->video_codec = MY_CODEC_ID_MSMPEG4V2;
366 }
367
368 if (strcmp(codec_name, "swf") == 0) {
369 ffmpeg->oc->oformat = av_guess_format("swf", NULL, NULL);
370 retcd = snprintf(ffmpeg->filename,PATH_MAX,"%s.swf",basename);
371 }
372
373 if (strcmp(codec_name, "flv") == 0) {
374 ffmpeg->oc->oformat = av_guess_format("flv", NULL, NULL);
375 retcd = snprintf(ffmpeg->filename,PATH_MAX,"%s.flv",basename);
376 if (ffmpeg->oc->oformat) ffmpeg->oc->oformat->video_codec = MY_CODEC_ID_FLV1;
377 }
378
379 if (strcmp(codec_name, "ffv1") == 0) {
380 ffmpeg->oc->oformat = av_guess_format("avi", NULL, NULL);
381 retcd = snprintf(ffmpeg->filename,PATH_MAX,"%s.avi",basename);
382 if (ffmpeg->oc->oformat) ffmpeg->oc->oformat->video_codec = MY_CODEC_ID_FFV1;
383 }
384
385 if (strcmp(codec_name, "mov") == 0) {
386 ffmpeg->oc->oformat = av_guess_format("mov", NULL, NULL);
387 retcd = snprintf(ffmpeg->filename,PATH_MAX,"%s.mov",basename);
388 }
389
390 if (strcmp(codec_name, "mp4") == 0) {
391 ffmpeg->oc->oformat = av_guess_format("mp4", NULL, NULL);
392 retcd = snprintf(ffmpeg->filename,PATH_MAX,"%s.mp4",basename);
393 if (ffmpeg->oc->oformat) ffmpeg->oc->oformat->video_codec = MY_CODEC_ID_H264;
394 }
395
396 if (strcmp(codec_name, "mkv") == 0) {
397 ffmpeg->oc->oformat = av_guess_format("matroska", NULL, NULL);
398 retcd = snprintf(ffmpeg->filename,PATH_MAX,"%s.mkv",basename);
399 if (ffmpeg->oc->oformat) ffmpeg->oc->oformat->video_codec = MY_CODEC_ID_H264;
400 }
401
402 if (strcmp(codec_name, "hevc") == 0) {
403 ffmpeg->oc->oformat = av_guess_format("mp4", NULL, NULL);
404 retcd = snprintf(ffmpeg->filename,PATH_MAX,"%s.mp4",basename);
405 if (ffmpeg->oc->oformat) ffmpeg->oc->oformat->video_codec = MY_CODEC_ID_HEVC;
406 }
407
408 //Check for valid results
409 if ((retcd < 0) || (retcd >= PATH_MAX)){
410 MOTION_LOG(ERR, TYPE_ENCODER, NO_ERRNO
411 ,_("Error setting file name"));
412 ffmpeg_free_context(ffmpeg);
413 free(codec_name);
414 return -1;
415 }
416
417 if (!ffmpeg->oc->oformat) {
418 MOTION_LOG(ERR, TYPE_ENCODER, NO_ERRNO
419 ,_("codec option value %s is not supported"), codec_name);
420 ffmpeg_free_context(ffmpeg);
421 free(codec_name);
422 return -1;
423 }
424
425 if (ffmpeg->oc->oformat->video_codec == MY_CODEC_ID_NONE) {
426 MOTION_LOG(ERR, TYPE_ENCODER, NO_ERRNO, _("Could not get the codec"));
427 ffmpeg_free_context(ffmpeg);
428 free(codec_name);
429 return -1;
430 }
431
432 free(codec_name);
433 return 0;
434 }
435
ffmpeg_encode_video(struct ffmpeg * ffmpeg)436 static int ffmpeg_encode_video(struct ffmpeg *ffmpeg){
437
438 #if (LIBAVFORMAT_VERSION_MAJOR >= 58) || ((LIBAVFORMAT_VERSION_MAJOR == 57) && (LIBAVFORMAT_VERSION_MINOR >= 41))
439 //ffmpeg version 3.1 and after
440 int retcd = 0;
441 char errstr[128];
442
443 retcd = avcodec_send_frame(ffmpeg->ctx_codec, ffmpeg->picture);
444 if (retcd < 0 ){
445 av_strerror(retcd, errstr, sizeof(errstr));
446 MOTION_LOG(ERR, TYPE_ENCODER, NO_ERRNO
447 ,_("Error sending frame for encoding:%s"),errstr);
448 return -1;
449 }
450 retcd = avcodec_receive_packet(ffmpeg->ctx_codec, &ffmpeg->pkt);
451 if (retcd == AVERROR(EAGAIN)){
452 //Buffered packet. Throw special return code
453 av_strerror(retcd, errstr, sizeof(errstr));
454 MOTION_LOG(DBG, TYPE_ENCODER, NO_ERRNO
455 ,_("Receive packet threw EAGAIN returning -2 code :%s"),errstr);
456 my_packet_unref(ffmpeg->pkt);
457 return -2;
458 }
459 if (retcd < 0 ){
460 av_strerror(retcd, errstr, sizeof(errstr));
461 MOTION_LOG(ERR, TYPE_ENCODER, NO_ERRNO
462 ,_("Error receiving encoded packet video:%s"),errstr);
463 //Packet is freed upon failure of encoding
464 return -1;
465 }
466
467 if (ffmpeg->preferred_codec == USER_CODEC_V4L2M2M){
468 if (ffmpeg_encode_nal(ffmpeg)) {
469 // Throw special return code
470 return -2;
471 }
472 }
473
474 return 0;
475
476 #elif (LIBAVFORMAT_VERSION_MAJOR >= 55) || ((LIBAVFORMAT_VERSION_MAJOR == 54) && (LIBAVFORMAT_VERSION_MINOR > 6))
477
478 int retcd = 0;
479 char errstr[128];
480 int got_packet_ptr;
481
482 retcd = avcodec_encode_video2(ffmpeg->ctx_codec, &ffmpeg->pkt, ffmpeg->picture, &got_packet_ptr);
483 if (retcd < 0 ){
484 av_strerror(retcd, errstr, sizeof(errstr));
485 MOTION_LOG(ERR, TYPE_ENCODER, NO_ERRNO, _("Error encoding video:%s"),errstr);
486 //Packet is freed upon failure of encoding
487 return -1;
488 }
489 if (got_packet_ptr == 0){
490 //Buffered packet. Throw special return code
491 my_packet_unref(ffmpeg->pkt);
492 return -2;
493 }
494
495 /* This kills compiler warnings. Nal setting is only for recent ffmpeg versions*/
496 if (ffmpeg->preferred_codec == USER_CODEC_V4L2M2M){
497 if (ffmpeg_encode_nal(ffmpeg)) {
498 // Throw special return code
499 return -2;
500 }
501 }
502
503 return 0;
504
505 #else
506
507 int retcd = 0;
508 uint8_t *video_outbuf;
509 int video_outbuf_size;
510
511 video_outbuf_size = (ffmpeg->ctx_codec->width +16) * (ffmpeg->ctx_codec->height +16) * 1;
512 video_outbuf = mymalloc(video_outbuf_size);
513
514 retcd = avcodec_encode_video(ffmpeg->video_st->codec, video_outbuf, video_outbuf_size, ffmpeg->picture);
515 if (retcd < 0 ){
516 MOTION_LOG(ERR, TYPE_ENCODER, NO_ERRNO, _("Error encoding video"));
517 my_packet_unref(ffmpeg->pkt);
518 return -1;
519 }
520 if (retcd == 0 ){
521 // No bytes encoded => buffered=>special handling
522 my_packet_unref(ffmpeg->pkt);
523 return -2;
524 }
525
526 // Encoder did not provide metadata, set it up manually
527 ffmpeg->pkt.size = retcd;
528 ffmpeg->pkt.data = video_outbuf;
529
530 if (ffmpeg->picture->key_frame == 1)
531 ffmpeg->pkt.flags |= AV_PKT_FLAG_KEY;
532
533 ffmpeg->pkt.pts = ffmpeg->picture->pts;
534 ffmpeg->pkt.dts = ffmpeg->pkt.pts;
535
536 free(video_outbuf);
537
538 /* This kills compiler warnings. Nal setting is only for recent ffmpeg versions*/
539 if (ffmpeg->preferred_codec == USER_CODEC_V4L2M2M){
540 if (ffmpeg_encode_nal(ffmpeg)) {
541 // Throw special return code
542 return -2;
543 }
544 }
545
546 return 0;
547
548 #endif
549
550 }
551
ffmpeg_set_pts(struct ffmpeg * ffmpeg,const struct timeval * tv1)552 static int ffmpeg_set_pts(struct ffmpeg *ffmpeg, const struct timeval *tv1){
553
554 int64_t pts_interval;
555
556 if (ffmpeg->tlapse != TIMELAPSE_NONE) {
557 ffmpeg->last_pts++;
558 ffmpeg->picture->pts = ffmpeg->last_pts;
559 } else {
560 pts_interval = ((1000000L * (tv1->tv_sec - ffmpeg->start_time.tv_sec)) + tv1->tv_usec - ffmpeg->start_time.tv_usec);
561 if (pts_interval < 0){
562 /* This can occur when we have pre-capture frames. Reset start time of video. */
563 ffmpeg_reset_movie_start_time(ffmpeg, tv1);
564 pts_interval = 0;
565 }
566 if (ffmpeg->last_pts < 0) {
567 // This is the very first frame, ensure PTS is zero
568 ffmpeg->picture->pts = 0;
569 } else
570 ffmpeg->picture->pts = av_rescale_q(pts_interval,(AVRational){1, 1000000L},ffmpeg->video_st->time_base) + ffmpeg->base_pts;
571
572 if (ffmpeg->test_mode == TRUE){
573 MOTION_LOG(INF, TYPE_ENCODER, NO_ERRNO
574 ,_("PTS %"PRId64" Base PTS %"PRId64" ms interval %"PRId64" timebase %d-%d")
575 ,ffmpeg->picture->pts,ffmpeg->base_pts,pts_interval
576 ,ffmpeg->video_st->time_base.num,ffmpeg->video_st->time_base.den);
577 }
578
579 if (ffmpeg->picture->pts <= ffmpeg->last_pts){
580 //We have a problem with our motion loop timing and sending frames or the rounding into the PTS.
581 if (ffmpeg->test_mode == TRUE){
582 MOTION_LOG(INF, TYPE_ENCODER, NO_ERRNO, _("BAD TIMING!! Frame skipped."));
583 }
584 return -1;
585 }
586 ffmpeg->last_pts = ffmpeg->picture->pts;
587 }
588 return 0;
589 }
590
ffmpeg_set_pktpts(struct ffmpeg * ffmpeg,const struct timeval * tv1)591 static int ffmpeg_set_pktpts(struct ffmpeg *ffmpeg, const struct timeval *tv1){
592
593 int64_t pts_interval;
594
595 if (ffmpeg->tlapse != TIMELAPSE_NONE) {
596 ffmpeg->last_pts++;
597 ffmpeg->pkt.pts = ffmpeg->last_pts;
598 } else {
599 pts_interval = ((1000000L * (tv1->tv_sec - ffmpeg->start_time.tv_sec)) + tv1->tv_usec - ffmpeg->start_time.tv_usec);
600 if (pts_interval < 0){
601 /* This can occur when we have pre-capture frames. Reset start time of video. */
602 ffmpeg_reset_movie_start_time(ffmpeg, tv1);
603 pts_interval = 0;
604 }
605 ffmpeg->pkt.pts = av_rescale_q(pts_interval,(AVRational){1, 1000000L},ffmpeg->video_st->time_base) + ffmpeg->base_pts;
606
607 if (ffmpeg->test_mode == TRUE){
608 MOTION_LOG(INF, TYPE_ENCODER, NO_ERRNO
609 ,_("PTS %"PRId64" Base PTS %"PRId64" ms interval %"PRId64" timebase %d-%d Change %d")
610 ,ffmpeg->pkt.pts
611 ,ffmpeg->base_pts,pts_interval
612 ,ffmpeg->video_st->time_base.num
613 ,ffmpeg->video_st->time_base.den
614 ,(ffmpeg->pkt.pts-ffmpeg->last_pts) );
615 }
616
617 if (ffmpeg->pkt.pts <= ffmpeg->last_pts){
618 //We have a problem with our motion loop timing and sending frames or the rounding into the PTS.
619 if (ffmpeg->test_mode == TRUE){
620 MOTION_LOG(INF, TYPE_ENCODER, NO_ERRNO, _("BAD TIMING!! Frame skipped."));
621 }
622 return -1;
623 }
624 ffmpeg->last_pts = ffmpeg->pkt.pts;
625 ffmpeg->pkt.dts=ffmpeg->pkt.pts;
626 }
627 return 0;
628 }
629
ffmpeg_set_quality(struct ffmpeg * ffmpeg)630 static int ffmpeg_set_quality(struct ffmpeg *ffmpeg){
631
632 ffmpeg->opts = 0;
633 if (ffmpeg->quality > 100) ffmpeg->quality = 100;
634 if (ffmpeg->ctx_codec->codec_id == MY_CODEC_ID_H264 ||
635 ffmpeg->ctx_codec->codec_id == MY_CODEC_ID_HEVC){
636 if (ffmpeg->quality <= 0)
637 ffmpeg->quality = 45; // default to 45% quality
638 av_dict_set(&ffmpeg->opts, "preset", "ultrafast", 0);
639 av_dict_set(&ffmpeg->opts, "tune", "zerolatency", 0);
640 /* This next if statement needs validation. Are mpeg4omx
641 * and v4l2m2m even MY_CODEC_ID_H264 or MY_CODEC_ID_HEVC
642 * such that it even would be possible to be part of this
643 * if block to start with? */
644 if ((ffmpeg->preferred_codec == USER_CODEC_H264OMX) ||
645 (ffmpeg->preferred_codec == USER_CODEC_MPEG4OMX) ||
646 (ffmpeg->preferred_codec == USER_CODEC_V4L2M2M)) {
647 // bit_rate = ffmpeg->width * ffmpeg->height * ffmpeg->fps * quality_factor
648 ffmpeg->quality = (int)(((int64_t)ffmpeg->width * ffmpeg->height * ffmpeg->fps * ffmpeg->quality) >> 7);
649 // Clip bit rate to min
650 if (ffmpeg->quality < 4000) // magic number
651 ffmpeg->quality = 4000;
652 ffmpeg->ctx_codec->profile = FF_PROFILE_H264_HIGH;
653 ffmpeg->ctx_codec->bit_rate = ffmpeg->quality;
654 } else {
655 // Control other H264 encoders quality via CRF
656 char crf[10];
657 ffmpeg->quality = (int)(( (100-ffmpeg->quality) * 51)/100);
658 snprintf(crf, 10, "%d", ffmpeg->quality);
659 av_dict_set(&ffmpeg->opts, "crf", crf, 0);
660 }
661 } else {
662 /* The selection of 8000 is a subjective number based upon viewing output files */
663 if (ffmpeg->quality > 0){
664 ffmpeg->quality =(int)(((100-ffmpeg->quality)*(100-ffmpeg->quality)*(100-ffmpeg->quality) * 8000) / 1000000) + 1;
665 ffmpeg->ctx_codec->flags |= MY_CODEC_FLAG_QSCALE;
666 ffmpeg->ctx_codec->global_quality=ffmpeg->quality;
667 }
668 }
669 MOTION_LOG(INF, TYPE_ENCODER, NO_ERRNO
670 ,_("%s codec vbr/crf/bit_rate: %d"), ffmpeg->codec->name, ffmpeg->quality);
671
672 return 0;
673 }
674
675 struct blacklist_t
676 {
677 const char *codec_name;
678 const char *reason;
679 };
680
ffmpeg_codec_is_blacklisted(const char * codec_name)681 static const char *ffmpeg_codec_is_blacklisted(const char *codec_name){
682
683 static struct blacklist_t blacklisted_codec[] =
684 {
685 #if (LIBAVFORMAT_VERSION_MAJOR < 58) || ( (LIBAVFORMAT_VERSION_MAJOR == 58) && ( (LIBAVFORMAT_VERSION_MINOR < 29) || ((LIBAVFORMAT_VERSION_MINOR == 29) && (LIBAVFORMAT_VERSION_MICRO <= 100)) ) )
686 /* h264_omx & ffmpeg combination locks up on Raspberry Pi.
687 * Newer versions of ffmpeg allow zerocopy to be disabled to workaround
688 * this issue.
689 * To use h264_omx encoder on older versions of ffmpeg:
690 * - disable input_zerocopy in ffmpeg omx.c:omx_encode_init function.
691 * - remove the "h264_omx" from this blacklist.
692 * More information: https://github.com/Motion-Project/motion/issues/433
693 */
694 {"h264_omx", "Codec causes lock up on your FFMpeg version"},
695 #endif
696 #if (LIBAVFORMAT_VERSION_MAJOR < 57) || ((LIBAVFORMAT_VERSION_MAJOR == 57) && (LIBAVFORMAT_VERSION_MINOR < 41))
697 {"h264_v4l2m2m", "FFMpeg version is too old"},
698 #endif
699 };
700 size_t i,i_mx;
701
702 i_mx = (size_t)(sizeof(blacklisted_codec)/sizeof(blacklisted_codec[0]));
703
704 for (i = 0; i < i_mx; i++) {
705 if (strcmp(codec_name, blacklisted_codec[i].codec_name) == 0)
706 return blacklisted_codec[i].reason;
707 }
708 return NULL;
709 }
710
ffmpeg_set_codec_preferred(struct ffmpeg * ffmpeg)711 static int ffmpeg_set_codec_preferred(struct ffmpeg *ffmpeg){
712 size_t codec_name_len = strcspn(ffmpeg->codec_name, ":");
713
714 ffmpeg->codec = NULL;
715 if (ffmpeg->codec_name[codec_name_len]) {
716 const char *blacklist_reason = ffmpeg_codec_is_blacklisted(&ffmpeg->codec_name[codec_name_len+1]);
717 if (blacklist_reason) {
718 MOTION_LOG(WRN, TYPE_ENCODER, NO_ERRNO
719 ,_("Preferred codec %s has been blacklisted: %s")
720 ,&ffmpeg->codec_name[codec_name_len+1], blacklist_reason);
721 } else {
722 ffmpeg->codec = avcodec_find_encoder_by_name(&ffmpeg->codec_name[codec_name_len+1]);
723 if ((ffmpeg->oc->oformat) && (ffmpeg->codec != NULL)) {
724 ffmpeg->oc->oformat->video_codec = ffmpeg->codec->id;
725 } else if (ffmpeg->codec == NULL) {
726 MOTION_LOG(WRN, TYPE_ENCODER, NO_ERRNO
727 ,_("Preferred codec %s not found")
728 ,&ffmpeg->codec_name[codec_name_len+1]);
729 }
730 }
731 }
732 if (!ffmpeg->codec)
733 ffmpeg->codec = avcodec_find_encoder(ffmpeg->oc->oformat->video_codec);
734 if (!ffmpeg->codec) {
735 MOTION_LOG(ERR, TYPE_ENCODER, NO_ERRNO
736 ,_("Codec %s not found"), ffmpeg->codec_name);
737 ffmpeg_free_context(ffmpeg);
738 return -1;
739 }
740
741 if (strcmp(ffmpeg->codec->name, "h264_v4l2m2m") == 0){
742 ffmpeg->preferred_codec = USER_CODEC_V4L2M2M;
743 } else if (strcmp(ffmpeg->codec->name, "h264_omx") == 0){
744 ffmpeg->preferred_codec = USER_CODEC_H264OMX;
745 } else if (strcmp(ffmpeg->codec->name, "mpeg4_omx") == 0){
746 ffmpeg->preferred_codec = USER_CODEC_MPEG4OMX;
747 } else {
748 ffmpeg->preferred_codec = USER_CODEC_DEFAULT;
749 }
750
751 if (ffmpeg->codec_name[codec_name_len])
752 MOTION_LOG(NTC, TYPE_ENCODER, NO_ERRNO,_("Using codec %s"), ffmpeg->codec->name);
753
754 return 0;
755
756 }
757
ffmpeg_set_codec(struct ffmpeg * ffmpeg)758 static int ffmpeg_set_codec(struct ffmpeg *ffmpeg){
759
760 int retcd;
761 char errstr[128];
762 int chkrate;
763
764 retcd = ffmpeg_set_codec_preferred(ffmpeg);
765 if (retcd != 0) return retcd;
766
767 #if (LIBAVFORMAT_VERSION_MAJOR >= 58) || ((LIBAVFORMAT_VERSION_MAJOR == 57) && (LIBAVFORMAT_VERSION_MINOR >= 41))
768 //If we provide the codec to this, it results in a memory leak. ffmpeg ticket: 5714
769 ffmpeg->video_st = avformat_new_stream(ffmpeg->oc, NULL);
770 if (!ffmpeg->video_st) {
771 MOTION_LOG(ERR, TYPE_ENCODER, NO_ERRNO, _("Could not alloc stream"));
772 ffmpeg_free_context(ffmpeg);
773 return -1;
774 }
775 ffmpeg->ctx_codec = avcodec_alloc_context3(ffmpeg->codec);
776 if (ffmpeg->ctx_codec == NULL) {
777 MOTION_LOG(ERR, TYPE_ENCODER, NO_ERRNO, _("Failed to allocate decoder!"));
778 ffmpeg_free_context(ffmpeg);
779 return -1;
780 }
781 #else
782 ffmpeg->video_st = avformat_new_stream(ffmpeg->oc, ffmpeg->codec);
783 if (!ffmpeg->video_st) {
784 MOTION_LOG(ERR, TYPE_ENCODER, NO_ERRNO, _("Could not alloc stream"));
785 ffmpeg_free_context(ffmpeg);
786 return -1;
787 }
788 ffmpeg->ctx_codec = ffmpeg->video_st->codec;
789 #endif
790
791
792 if (ffmpeg->tlapse != TIMELAPSE_NONE) {
793 ffmpeg->ctx_codec->gop_size = 1;
794 } else {
795 if (ffmpeg->fps <= 5){
796 ffmpeg->ctx_codec->gop_size = 1;
797 } else if (ffmpeg->fps > 30){
798 ffmpeg->ctx_codec->gop_size = 15;
799 } else {
800 ffmpeg->ctx_codec->gop_size = (ffmpeg->fps / 2);
801 }
802 ffmpeg->gop_cnt = ffmpeg->ctx_codec->gop_size - 1;
803 }
804
805 /* For certain containers, setting the fps to very low numbers results in
806 ** a very poor quality playback. We can set the FPS to a higher number and
807 ** then let the PTS display the frames correctly.
808 */
809 if ((ffmpeg->tlapse == TIMELAPSE_NONE) && (ffmpeg->fps <= 5)){
810 if ((strcmp(ffmpeg->codec_name, "msmpeg4") == 0) ||
811 (strcmp(ffmpeg->codec_name, "flv") == 0) ||
812 (strcmp(ffmpeg->codec_name, "mov") == 0) ||
813 (strcmp(ffmpeg->codec_name, "mp4") == 0) ||
814 (strcmp(ffmpeg->codec_name, "hevc") == 0) ||
815 (strcmp(ffmpeg->codec_name, "mpeg4") == 0)) {
816 MOTION_LOG(NTC, TYPE_ENCODER, NO_ERRNO, _("Low fps. Encoding %d frames into a %d frames container."), ffmpeg->fps, 10);
817 ffmpeg->fps = 10;
818 }
819 }
820
821 ffmpeg->ctx_codec->codec_id = ffmpeg->oc->oformat->video_codec;
822 ffmpeg->ctx_codec->codec_type = AVMEDIA_TYPE_VIDEO;
823 ffmpeg->ctx_codec->bit_rate = ffmpeg->bps;
824 ffmpeg->ctx_codec->width = ffmpeg->width;
825 ffmpeg->ctx_codec->height = ffmpeg->height;
826 ffmpeg->ctx_codec->time_base.num = 1;
827 ffmpeg->ctx_codec->time_base.den = ffmpeg->fps;
828 if (ffmpeg->preferred_codec == USER_CODEC_V4L2M2M){
829 ffmpeg->ctx_codec->pix_fmt = AV_PIX_FMT_NV21;
830 } else {
831 ffmpeg->ctx_codec->pix_fmt = MY_PIX_FMT_YUV420P;
832 }
833 ffmpeg->ctx_codec->max_b_frames = 0;
834 if (strcmp(ffmpeg->codec_name, "ffv1") == 0){
835 ffmpeg->ctx_codec->strict_std_compliance = -2;
836 ffmpeg->ctx_codec->level = 3;
837 }
838 ffmpeg->ctx_codec->flags |= MY_CODEC_FLAG_GLOBAL_HEADER;
839
840 if ((strcmp(ffmpeg->codec->name, "h264_omx") == 0) ||
841 (strcmp(ffmpeg->codec->name, "mpeg4_omx") == 0)) {
842 /* h264_omx & ffmpeg combination locks up on Raspberry Pi.
843 * To use h264_omx encoder, we need to disable zerocopy.
844 * More information: https://github.com/Motion-Project/motion/issues/433
845 */
846 av_dict_set(&ffmpeg->opts, "zerocopy", "0", 0);
847 }
848
849 retcd = ffmpeg_set_quality(ffmpeg);
850 if (retcd < 0){
851 MOTION_LOG(ERR, TYPE_ENCODER, NO_ERRNO, _("Unable to set quality"));
852 return -1;
853 }
854
855 retcd = avcodec_open2(ffmpeg->ctx_codec, ffmpeg->codec, &ffmpeg->opts);
856 if (retcd < 0) {
857 if (ffmpeg->codec->supported_framerates) {
858 const AVRational *fps = ffmpeg->codec->supported_framerates;
859 while (fps->num) {
860 MOTION_LOG(INF, TYPE_ENCODER, NO_ERRNO
861 ,_("Reported FPS Supported %d/%d"), fps->num, fps->den);
862 fps++;
863 }
864 }
865 chkrate = 1;
866 while ((chkrate < 36) && (retcd != 0)) {
867 ffmpeg->ctx_codec->time_base.den = chkrate;
868 retcd = avcodec_open2(ffmpeg->ctx_codec, ffmpeg->codec, &ffmpeg->opts);
869 chkrate++;
870 }
871 if (retcd < 0){
872 av_strerror(retcd, errstr, sizeof(errstr));
873 MOTION_LOG(ERR, TYPE_ENCODER, NO_ERRNO, _("Could not open codec %s"),errstr);
874 av_dict_free(&ffmpeg->opts);
875 ffmpeg_free_context(ffmpeg);
876 return -1;
877 }
878
879 }
880 av_dict_free(&ffmpeg->opts);
881
882 return 0;
883 }
884
ffmpeg_set_stream(struct ffmpeg * ffmpeg)885 static int ffmpeg_set_stream(struct ffmpeg *ffmpeg){
886
887 #if (LIBAVFORMAT_VERSION_MAJOR >= 58) || ((LIBAVFORMAT_VERSION_MAJOR == 57) && (LIBAVFORMAT_VERSION_MINOR >= 41))
888 int retcd;
889 char errstr[128];
890
891 retcd = avcodec_parameters_from_context(ffmpeg->video_st->codecpar,ffmpeg->ctx_codec);
892 if (retcd < 0) {
893 av_strerror(retcd, errstr, sizeof(errstr));
894 MOTION_LOG(ERR, TYPE_ENCODER, NO_ERRNO
895 ,_("Failed to copy decoder parameters!: %s"), errstr);
896 ffmpeg_free_context(ffmpeg);
897 return -1;
898 }
899 #endif
900
901 ffmpeg->video_st->time_base = (AVRational){1, ffmpeg->fps};
902
903 return 0;
904
905 }
906
907 /*Special allocation of video buffer for v4l2m2m codec*/
ffmpeg_alloc_video_buffer(AVFrame * frame,int align)908 static int ffmpeg_alloc_video_buffer(AVFrame *frame, int align)
909 {
910 const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(frame->format);
911 int ret, i, padded_height;
912 int plane_padding = FFMAX(16 + 16/*STRIDE_ALIGN*/, align);
913
914 if (!desc)
915 return AVERROR(EINVAL);
916
917 if ((ret = av_image_check_size(frame->width, frame->height, 0, NULL)) < 0)
918 return ret;
919
920 if (!frame->linesize[0]) {
921 if (align <= 0)
922 align = 32; /* STRIDE_ALIGN. Should be av_cpu_max_align() */
923
924 for(i=1; i<=align; i+=i) {
925 ret = av_image_fill_linesizes(frame->linesize, frame->format,
926 FFALIGN(frame->width, i));
927 if (ret < 0)
928 return ret;
929 if (!(frame->linesize[0] & (align-1)))
930 break;
931 }
932
933 for (i = 0; i < 4 && frame->linesize[i]; i++)
934 frame->linesize[i] = FFALIGN(frame->linesize[i], align);
935 }
936
937 padded_height = FFALIGN(frame->height, 32);
938 if ((ret = av_image_fill_pointers(frame->data, frame->format, padded_height,
939 NULL, frame->linesize)) < 0)
940 return ret;
941
942 frame->buf[0] = av_buffer_alloc(ret + 4*plane_padding);
943 if (!frame->buf[0]) {
944 ret = AVERROR(ENOMEM);
945 av_frame_unref(frame);
946 return ret;
947 }
948 frame->buf[1] = av_buffer_alloc(ret + 4*plane_padding);
949 if (!frame->buf[1]) {
950 ret = AVERROR(ENOMEM);
951 av_frame_unref(frame);
952 return ret;
953 }
954
955 frame->data[0] = frame->buf[0]->data;
956 frame->data[1] = frame->buf[1]->data;
957 frame->data[2] = frame->data[1] + ((frame->width * padded_height) / 4);
958
959 frame->extended_data = frame->data;
960
961 return 0;
962 }
963
964
ffmpeg_set_picture(struct ffmpeg * ffmpeg)965 static int ffmpeg_set_picture(struct ffmpeg *ffmpeg){
966
967 int retcd;
968 char errstr[128];
969
970 ffmpeg->picture = my_frame_alloc();
971 if (!ffmpeg->picture) {
972 MOTION_LOG(ERR, TYPE_ENCODER, NO_ERRNO, _("could not alloc frame"));
973 ffmpeg_free_context(ffmpeg);
974 return -1;
975 }
976
977 /* Take care of variable bitrate setting. */
978 if (ffmpeg->quality)
979 ffmpeg->picture->quality = ffmpeg->quality;
980
981 ffmpeg->picture->linesize[0] = ffmpeg->ctx_codec->width;
982 ffmpeg->picture->linesize[1] = ffmpeg->ctx_codec->width / 2;
983 ffmpeg->picture->linesize[2] = ffmpeg->ctx_codec->width / 2;
984
985 ffmpeg->picture->format = ffmpeg->ctx_codec->pix_fmt;
986 ffmpeg->picture->width = ffmpeg->ctx_codec->width;
987 ffmpeg->picture->height = ffmpeg->ctx_codec->height;
988
989 if (ffmpeg->preferred_codec == USER_CODEC_V4L2M2M) {
990 retcd = ffmpeg_alloc_video_buffer(ffmpeg->picture, 32);
991 if (retcd) {
992 av_strerror(retcd, errstr, sizeof(errstr));
993 MOTION_LOG(ERR, TYPE_ENCODER, NO_ERRNO, _("could not alloc buffers %s"), errstr);
994 ffmpeg_free_context(ffmpeg);
995 return -1;
996 }
997 }
998
999 return 0;
1000
1001 }
1002
ffmpeg_set_outputfile(struct ffmpeg * ffmpeg)1003 static int ffmpeg_set_outputfile(struct ffmpeg *ffmpeg){
1004
1005 int retcd;
1006 char errstr[128];
1007
1008 #if (LIBAVFORMAT_VERSION_MAJOR < 58)
1009 snprintf(ffmpeg->oc->filename, sizeof(ffmpeg->oc->filename), "%s", ffmpeg->filename);
1010 #endif
1011
1012 /* Open the output file, if needed. */
1013 if ((ffmpeg_timelapse_exists(ffmpeg->filename) == 0) || (ffmpeg->tlapse != TIMELAPSE_APPEND)) {
1014 if (!(ffmpeg->oc->oformat->flags & AVFMT_NOFILE)) {
1015 if (avio_open(&ffmpeg->oc->pb, ffmpeg->filename, MY_FLAG_WRITE) < 0) {
1016 if (errno == ENOENT) {
1017 if (create_path(ffmpeg->filename) == -1) {
1018 ffmpeg_free_context(ffmpeg);
1019 return -1;
1020 }
1021 if (avio_open(&ffmpeg->oc->pb, ffmpeg->filename, MY_FLAG_WRITE) < 0) {
1022 MOTION_LOG(ERR, TYPE_ENCODER, SHOW_ERRNO
1023 ,_("error opening file %s"), ffmpeg->filename);
1024 ffmpeg_free_context(ffmpeg);
1025 return -1;
1026 }
1027 /* Permission denied */
1028 } else if (errno == EACCES) {
1029 MOTION_LOG(ERR, TYPE_ENCODER, SHOW_ERRNO
1030 ,_("Permission denied. %s"),ffmpeg->filename);
1031 ffmpeg_free_context(ffmpeg);
1032 return -1;
1033 } else {
1034 MOTION_LOG(ERR, TYPE_ENCODER, SHOW_ERRNO
1035 ,_("Error opening file %s"), ffmpeg->filename);
1036 ffmpeg_free_context(ffmpeg);
1037 return -1;
1038 }
1039 }
1040 }
1041
1042 /* Write the stream header, For the TIMELAPSE_APPEND
1043 * we write the data via standard file I/O so we close the
1044 * items here
1045 */
1046 retcd = avformat_write_header(ffmpeg->oc, NULL);
1047 if (retcd < 0){
1048 av_strerror(retcd, errstr, sizeof(errstr));
1049 MOTION_LOG(ERR, TYPE_ENCODER, NO_ERRNO
1050 ,_("Could not write ffmpeg header %s"),errstr);
1051 ffmpeg_free_context(ffmpeg);
1052 return -1;
1053 }
1054 if (ffmpeg->tlapse == TIMELAPSE_APPEND) {
1055 av_write_trailer(ffmpeg->oc);
1056 avio_close(ffmpeg->oc->pb);
1057 }
1058
1059 }
1060
1061 return 0;
1062
1063 }
1064
ffmpeg_flush_codec(struct ffmpeg * ffmpeg)1065 static int ffmpeg_flush_codec(struct ffmpeg *ffmpeg){
1066
1067 #if (LIBAVFORMAT_VERSION_MAJOR >= 58) || ((LIBAVFORMAT_VERSION_MAJOR == 57) && (LIBAVFORMAT_VERSION_MINOR >= 41))
1068 //ffmpeg version 3.1 and after
1069
1070 int retcd;
1071 int recv_cd = 0;
1072 char errstr[128];
1073
1074 if (ffmpeg->passthrough){
1075 return 0;
1076 }
1077
1078 retcd = 0;
1079 recv_cd = 0;
1080 if (ffmpeg->tlapse == TIMELAPSE_NONE) {
1081 retcd = avcodec_send_frame(ffmpeg->ctx_codec, NULL);
1082 if (retcd < 0 ){
1083 av_strerror(retcd, errstr, sizeof(errstr));
1084 MOTION_LOG(ERR, TYPE_ENCODER, NO_ERRNO
1085 ,_("Error entering draining mode:%s"),errstr);
1086 return -1;
1087 }
1088 while (recv_cd != AVERROR_EOF){
1089 av_init_packet(&ffmpeg->pkt);
1090 ffmpeg->pkt.data = NULL;
1091 ffmpeg->pkt.size = 0;
1092 recv_cd = avcodec_receive_packet(ffmpeg->ctx_codec, &ffmpeg->pkt);
1093 if (recv_cd != AVERROR_EOF){
1094 if (recv_cd < 0){
1095 av_strerror(recv_cd, errstr, sizeof(errstr));
1096 MOTION_LOG(ERR, TYPE_ENCODER, NO_ERRNO
1097 ,_("Error draining codec:%s"),errstr);
1098 my_packet_unref(ffmpeg->pkt);
1099 return -1;
1100 }
1101 // v4l2_m2m encoder uses pts 0 and size 0 to indicate AVERROR_EOF
1102 if ((ffmpeg->pkt.pts == 0) || (ffmpeg->pkt.size == 0)) {
1103 recv_cd = AVERROR_EOF;
1104 my_packet_unref(ffmpeg->pkt);
1105 continue;
1106 }
1107 retcd = av_write_frame(ffmpeg->oc, &ffmpeg->pkt);
1108 if (retcd < 0) {
1109 MOTION_LOG(ERR, TYPE_ENCODER, NO_ERRNO
1110 ,_("Error writing draining video frame"));
1111 return -1;
1112 }
1113 }
1114 my_packet_unref(ffmpeg->pkt);
1115 }
1116 }
1117 return 0;
1118 #else
1119 /* Dummy to kill warnings. No draining in older ffmpeg versions */
1120 if (ffmpeg) {
1121 return 0;
1122 } else{
1123 return 0;
1124 }
1125 #endif
1126
1127 }
1128
ffmpeg_put_frame(struct ffmpeg * ffmpeg,const struct timeval * tv1)1129 static int ffmpeg_put_frame(struct ffmpeg *ffmpeg, const struct timeval *tv1){
1130 int retcd;
1131
1132 av_init_packet(&ffmpeg->pkt);
1133 ffmpeg->pkt.data = NULL;
1134 ffmpeg->pkt.size = 0;
1135
1136 retcd = ffmpeg_set_pts(ffmpeg, tv1);
1137 if (retcd < 0) {
1138 //If there is an error, it has already been reported.
1139 my_packet_unref(ffmpeg->pkt);
1140 return 0;
1141 }
1142
1143 retcd = ffmpeg_encode_video(ffmpeg);
1144 if (retcd != 0){
1145 if (retcd != -2){
1146 MOTION_LOG(ERR, TYPE_ENCODER, NO_ERRNO, _("Error while encoding picture"));
1147 }
1148 my_packet_unref(ffmpeg->pkt);
1149 return retcd;
1150 }
1151
1152 if (ffmpeg->tlapse == TIMELAPSE_APPEND) {
1153 retcd = ffmpeg_timelapse_append(ffmpeg, ffmpeg->pkt);
1154 } else {
1155 retcd = av_write_frame(ffmpeg->oc, &ffmpeg->pkt);
1156 }
1157 my_packet_unref(ffmpeg->pkt);
1158
1159 if (retcd < 0) {
1160 MOTION_LOG(ERR, TYPE_ENCODER, NO_ERRNO, _("Error while writing video frame"));
1161 return -1;
1162 }
1163 return retcd;
1164
1165 }
1166
ffmpeg_passthru_reset(struct ffmpeg * ffmpeg)1167 static void ffmpeg_passthru_reset(struct ffmpeg *ffmpeg){
1168 /* Reset the written flag at start of each event */
1169 int indx;
1170
1171 pthread_mutex_lock(&ffmpeg->rtsp_data->mutex_pktarray);
1172 for(indx = 0; indx < ffmpeg->rtsp_data->pktarray_size; indx++) {
1173 ffmpeg->rtsp_data->pktarray[indx].iswritten = FALSE;
1174 }
1175 pthread_mutex_unlock(&ffmpeg->rtsp_data->mutex_pktarray);
1176
1177 }
1178
ffmpeg_passthru_write(struct ffmpeg * ffmpeg,int indx)1179 static void ffmpeg_passthru_write(struct ffmpeg *ffmpeg, int indx){
1180 /* Write the packet in the buffer at indx to file */
1181 char errstr[128];
1182 int retcd;
1183
1184 av_init_packet(&ffmpeg->pkt);
1185 ffmpeg->pkt.data = NULL;
1186 ffmpeg->pkt.size = 0;
1187
1188
1189 ffmpeg->rtsp_data->pktarray[indx].iswritten = TRUE;
1190
1191 retcd = my_copy_packet(&ffmpeg->pkt, &ffmpeg->rtsp_data->pktarray[indx].packet);
1192 if (retcd < 0) {
1193 av_strerror(retcd, errstr, sizeof(errstr));
1194 MOTION_LOG(INF, TYPE_ENCODER, NO_ERRNO, _("av_copy_packet: %s"),errstr);
1195 my_packet_unref(ffmpeg->pkt);
1196 return;
1197 }
1198
1199 retcd = ffmpeg_set_pktpts(ffmpeg, &ffmpeg->rtsp_data->pktarray[indx].timestamp_tv);
1200 if (retcd < 0) {
1201 my_packet_unref(ffmpeg->pkt);
1202 return;
1203 }
1204
1205 ffmpeg->pkt.stream_index = 0;
1206
1207 retcd = av_write_frame(ffmpeg->oc, &ffmpeg->pkt);
1208 my_packet_unref(ffmpeg->pkt);
1209 if (retcd < 0) {
1210 av_strerror(retcd, errstr, sizeof(errstr));
1211 MOTION_LOG(ERR, TYPE_ENCODER, NO_ERRNO
1212 ,_("Error while writing video frame: %s"),errstr);
1213 return;
1214 }
1215
1216 }
1217
ffmpeg_passthru_put(struct ffmpeg * ffmpeg,struct image_data * img_data)1218 static int ffmpeg_passthru_put(struct ffmpeg *ffmpeg, struct image_data *img_data){
1219
1220 int idnbr_image, idnbr_lastwritten, idnbr_stop, idnbr_firstkey;
1221 int indx, indx_lastwritten, indx_firstkey;
1222
1223 if (ffmpeg->rtsp_data == NULL) return -1;
1224
1225 if ((ffmpeg->rtsp_data->status == RTSP_NOTCONNECTED ) ||
1226 (ffmpeg->rtsp_data->status == RTSP_RECONNECTING ) ){
1227 return 0;
1228 }
1229
1230 if (ffmpeg->high_resolution){
1231 idnbr_image = img_data->idnbr_high;
1232 } else {
1233 idnbr_image = img_data->idnbr_norm;
1234 }
1235
1236 pthread_mutex_lock(&ffmpeg->rtsp_data->mutex_pktarray);
1237 idnbr_lastwritten = 0;
1238 idnbr_firstkey = idnbr_image;
1239 idnbr_stop = 0;
1240 indx_lastwritten = -1;
1241 indx_firstkey = -1;
1242
1243 for(indx = 0; indx < ffmpeg->rtsp_data->pktarray_size; indx++) {
1244 if ((ffmpeg->rtsp_data->pktarray[indx].iswritten) &&
1245 (ffmpeg->rtsp_data->pktarray[indx].idnbr > idnbr_lastwritten)){
1246 idnbr_lastwritten=ffmpeg->rtsp_data->pktarray[indx].idnbr;
1247 indx_lastwritten = indx;
1248 }
1249 if ((ffmpeg->rtsp_data->pktarray[indx].idnbr > idnbr_stop) &&
1250 (ffmpeg->rtsp_data->pktarray[indx].idnbr <= idnbr_image)){
1251 idnbr_stop=ffmpeg->rtsp_data->pktarray[indx].idnbr;
1252 }
1253 if ((ffmpeg->rtsp_data->pktarray[indx].iskey) &&
1254 (ffmpeg->rtsp_data->pktarray[indx].idnbr <= idnbr_firstkey)){
1255 idnbr_firstkey=ffmpeg->rtsp_data->pktarray[indx].idnbr;
1256 indx_firstkey = indx;
1257 }
1258 }
1259
1260 if (idnbr_stop == 0){
1261 pthread_mutex_unlock(&ffmpeg->rtsp_data->mutex_pktarray);
1262 return 0;
1263 }
1264
1265 if (indx_lastwritten != -1){
1266 indx = indx_lastwritten;
1267 } else if (indx_firstkey != -1) {
1268 indx = indx_firstkey;
1269 } else {
1270 indx = 0;
1271 }
1272
1273 while (TRUE){
1274 if ((!ffmpeg->rtsp_data->pktarray[indx].iswritten) &&
1275 (ffmpeg->rtsp_data->pktarray[indx].packet.size > 0) &&
1276 (ffmpeg->rtsp_data->pktarray[indx].idnbr > idnbr_lastwritten) &&
1277 (ffmpeg->rtsp_data->pktarray[indx].idnbr <= idnbr_image)) {
1278 ffmpeg_passthru_write(ffmpeg, indx);
1279 }
1280 if (ffmpeg->rtsp_data->pktarray[indx].idnbr == idnbr_stop) break;
1281 indx++;
1282 if (indx == ffmpeg->rtsp_data->pktarray_size ) indx = 0;
1283 }
1284 pthread_mutex_unlock(&ffmpeg->rtsp_data->mutex_pktarray);
1285 return 0;
1286 }
1287
ffmpeg_passthru_codec(struct ffmpeg * ffmpeg)1288 static int ffmpeg_passthru_codec(struct ffmpeg *ffmpeg){
1289
1290 int retcd;
1291 AVStream *stream_in;
1292
1293 if (ffmpeg->rtsp_data == NULL){
1294 MOTION_LOG(ERR, TYPE_ENCODER, NO_ERRNO, _("RTSP context not available."));
1295 return -1;
1296 }
1297
1298 pthread_mutex_lock(&ffmpeg->rtsp_data->mutex_transfer);
1299
1300 if ((ffmpeg->rtsp_data->status == RTSP_NOTCONNECTED ) ||
1301 (ffmpeg->rtsp_data->status == RTSP_RECONNECTING ) ){
1302 MOTION_LOG(NTC, TYPE_ENCODER, NO_ERRNO
1303 ,_("rtsp camera not ready for pass-through."));
1304 pthread_mutex_unlock(&ffmpeg->rtsp_data->mutex_transfer);
1305 return -1;
1306 }
1307
1308 if (strcmp(ffmpeg->codec_name, "mp4") != 0){
1309 MOTION_LOG(NTC, TYPE_ENCODER, NO_ERRNO
1310 ,_("pass-through mode enabled. Changing to MP4 container."));
1311 ffmpeg->codec_name = "mp4";
1312 }
1313
1314 retcd = ffmpeg_get_oformat(ffmpeg);
1315 if (retcd < 0 ) {
1316 MOTION_LOG(ERR, TYPE_ENCODER, NO_ERRNO, _("Could not get codec!"));
1317 pthread_mutex_unlock(&ffmpeg->rtsp_data->mutex_transfer);
1318 return -1;
1319 }
1320
1321 #if (LIBAVFORMAT_VERSION_MAJOR >= 58) || ((LIBAVFORMAT_VERSION_MAJOR == 57) && (LIBAVFORMAT_VERSION_MINOR >= 41))
1322 stream_in = ffmpeg->rtsp_data->transfer_format->streams[0];
1323 ffmpeg->oc->oformat->video_codec = stream_in->codecpar->codec_id;
1324
1325 ffmpeg->video_st = avformat_new_stream(ffmpeg->oc, NULL);
1326 if (!ffmpeg->video_st) {
1327 MOTION_LOG(ERR, TYPE_ENCODER, NO_ERRNO, _("Could not alloc stream"));
1328 pthread_mutex_unlock(&ffmpeg->rtsp_data->mutex_transfer);
1329 return -1;
1330 }
1331
1332 retcd = avcodec_parameters_copy(ffmpeg->video_st->codecpar, stream_in->codecpar);
1333 if (retcd < 0){
1334 MOTION_LOG(ERR, TYPE_ENCODER, NO_ERRNO, _("Unable to copy codec parameters"));
1335 pthread_mutex_unlock(&ffmpeg->rtsp_data->mutex_transfer);
1336 return -1;
1337 }
1338 ffmpeg->video_st->codecpar->codec_tag = 0;
1339
1340 #elif (LIBAVFORMAT_VERSION_MAJOR >= 55)
1341
1342 stream_in = ffmpeg->rtsp_data->transfer_format->streams[0];
1343
1344 ffmpeg->video_st = avformat_new_stream(ffmpeg->oc, stream_in->codec->codec);
1345 if (!ffmpeg->video_st) {
1346 MOTION_LOG(ERR, TYPE_ENCODER, NO_ERRNO, _("Could not alloc stream"));
1347 pthread_mutex_unlock(&ffmpeg->rtsp_data->mutex_transfer);
1348 return -1;
1349 }
1350
1351 retcd = avcodec_copy_context(ffmpeg->video_st->codec, stream_in->codec);
1352 if (retcd < 0){
1353 MOTION_LOG(ERR, TYPE_ENCODER, NO_ERRNO, _("Unable to copy codec parameters"));
1354 pthread_mutex_unlock(&ffmpeg->rtsp_data->mutex_transfer);
1355 return -1;
1356 }
1357 ffmpeg->video_st->codec->flags |= MY_CODEC_FLAG_GLOBAL_HEADER;
1358 ffmpeg->video_st->codec->codec_tag = 0;
1359 #else
1360 /* This is disabled in the util_check_passthrough but we need it here for compiling */
1361 pthread_mutex_unlock(&ffmpeg->rtsp_data->mutex_transfer);
1362 MOTION_LOG(INF, TYPE_ENCODER, NO_ERRNO, _("Pass-through disabled. ffmpeg too old"));
1363 return -1;
1364 #endif
1365
1366 ffmpeg->video_st->time_base = stream_in->time_base;
1367 pthread_mutex_unlock(&ffmpeg->rtsp_data->mutex_transfer);
1368 MOTION_LOG(INF, TYPE_ENCODER, NO_ERRNO, _("Pass-through stream opened"));
1369 return 0;
1370
1371 }
1372
ffmpeg_avcodec_log(void * ignoreme ATTRIBUTE_UNUSED,int errno_flag ATTRIBUTE_UNUSED,const char * fmt,va_list vl)1373 void ffmpeg_avcodec_log(void *ignoreme ATTRIBUTE_UNUSED, int errno_flag ATTRIBUTE_UNUSED, const char *fmt, va_list vl){
1374
1375 char buf[1024];
1376 char *end;
1377
1378 /* Valgrind occasionally reports use of uninitialized values in here when we interrupt
1379 * some rtsp functions. The offending value is either fmt or vl and seems to be from a
1380 * debug level of av functions. To address it we flatten the message after we know
1381 * the log level. Now we put the avcodec messages to INF level since their error
1382 * are not necessarily our errors.
1383 */
1384 if (errno_flag <= AV_LOG_WARNING){
1385 /* Flatten the message coming in from avcodec. */
1386 vsnprintf(buf, sizeof(buf), fmt, vl);
1387 end = buf + strlen(buf);
1388 if (end > buf && end[-1] == '\n')
1389 {
1390 *--end = 0;
1391 }
1392
1393 MOTION_LOG(INF, TYPE_ENCODER, NO_ERRNO, "%s", buf);
1394 }
1395 }
1396
ffmpeg_put_pix_nv21(struct ffmpeg * ffmpeg,struct image_data * img_data)1397 static void ffmpeg_put_pix_nv21(struct ffmpeg *ffmpeg, struct image_data *img_data){
1398 unsigned char *image,*imagecr, *imagecb;
1399 int cr_len, x, y;
1400
1401 if (ffmpeg->high_resolution){
1402 image = img_data->image_high;
1403 } else {
1404 image = img_data->image_norm;
1405 }
1406
1407 cr_len = ffmpeg->ctx_codec->width * ffmpeg->ctx_codec->height / 4;
1408 imagecr = image + (ffmpeg->ctx_codec->width * ffmpeg->ctx_codec->height);
1409 imagecb = image + (ffmpeg->ctx_codec->width * ffmpeg->ctx_codec->height) + cr_len;
1410
1411 memcpy(ffmpeg->picture->data[0], image, ffmpeg->ctx_codec->width * ffmpeg->ctx_codec->height);
1412 for (y = 0; y < ffmpeg->ctx_codec->height; y++) {
1413 for (x = 0; x < ffmpeg->ctx_codec->width/4; x++) {
1414 ffmpeg->picture->data[1][y*ffmpeg->ctx_codec->width/2 + x*2] = *imagecb;
1415 ffmpeg->picture->data[1][y*ffmpeg->ctx_codec->width/2 + x*2 + 1] = *imagecr;
1416 imagecb++;
1417 imagecr++;
1418 }
1419 }
1420
1421 }
1422
ffmpeg_put_pix_yuv420(struct ffmpeg * ffmpeg,struct image_data * img_data)1423 static void ffmpeg_put_pix_yuv420(struct ffmpeg *ffmpeg, struct image_data *img_data){
1424 unsigned char *image;
1425
1426 if (ffmpeg->high_resolution){
1427 image = img_data->image_high;
1428 } else {
1429 image = img_data->image_norm;
1430 }
1431
1432 // Usual setup for image pointers
1433 ffmpeg->picture->data[0] = image;
1434 ffmpeg->picture->data[1] = image + (ffmpeg->ctx_codec->width * ffmpeg->ctx_codec->height);
1435 ffmpeg->picture->data[2] = ffmpeg->picture->data[1] + ((ffmpeg->ctx_codec->width * ffmpeg->ctx_codec->height) / 4);
1436
1437 }
1438
1439
1440 #endif /* HAVE_FFMPEG */
1441
1442 /****************************************************************************
1443 ****************************************************************************
1444 ****************************************************************************/
1445
ffmpeg_global_init(void)1446 void ffmpeg_global_init(void){
1447 #ifdef HAVE_FFMPEG
1448
1449
1450 MOTION_LOG(NTC, TYPE_ENCODER, NO_ERRNO
1451 ,_("ffmpeg libavcodec version %d.%d.%d"
1452 " libavformat version %d.%d.%d")
1453 , LIBAVCODEC_VERSION_MAJOR, LIBAVCODEC_VERSION_MINOR, LIBAVCODEC_VERSION_MICRO
1454 , LIBAVFORMAT_VERSION_MAJOR, LIBAVFORMAT_VERSION_MINOR, LIBAVFORMAT_VERSION_MICRO);
1455
1456 #if (LIBAVFORMAT_VERSION_MAJOR < 58)
1457 /* TODO: Determine if this is even needed for older versions */
1458 av_register_all();
1459 avcodec_register_all();
1460 #endif
1461
1462
1463 avformat_network_init();
1464 avdevice_register_all();
1465 av_log_set_callback((void *)ffmpeg_avcodec_log);
1466
1467 #if (LIBAVFORMAT_VERSION_MAJOR < 58)
1468 /* TODO: Determine if this is even needed for older versions */
1469 int ret;
1470 ret = av_lockmgr_register(ffmpeg_lockmgr_cb);
1471 if (ret < 0)
1472 {
1473 MOTION_LOG(EMG, TYPE_ALL, SHOW_ERRNO, _("av_lockmgr_register failed (%d)"), ret);
1474 exit(1);
1475 }
1476 #endif
1477
1478 #else /* No FFMPEG */
1479
1480 MOTION_LOG(NTC, TYPE_ENCODER, NO_ERRNO, _("No ffmpeg functionality included"));
1481
1482 #endif /* HAVE_FFMPEG */
1483 }
1484
ffmpeg_global_deinit(void)1485 void ffmpeg_global_deinit(void) {
1486 #ifdef HAVE_FFMPEG
1487
1488 avformat_network_deinit();
1489
1490 #if (LIBAVFORMAT_VERSION_MAJOR < 58)
1491 /* TODO Determine if this is even needed for old versions */
1492 if (av_lockmgr_register(NULL) < 0)
1493 {
1494 MOTION_LOG(EMG, TYPE_ALL, SHOW_ERRNO
1495 ,_("av_lockmgr_register reset failed on cleanup"));
1496 }
1497 #endif
1498
1499
1500 #else /* No FFMPEG */
1501
1502 MOTION_LOG(NTC, TYPE_ENCODER, NO_ERRNO, _("No ffmpeg functionality included"));
1503
1504 #endif /* HAVE_FFMPEG */
1505 }
1506
ffmpeg_open(struct ffmpeg * ffmpeg)1507 int ffmpeg_open(struct ffmpeg *ffmpeg){
1508
1509 #ifdef HAVE_FFMPEG
1510
1511 int retcd;
1512
1513 ffmpeg->oc = avformat_alloc_context();
1514 if (!ffmpeg->oc) {
1515 MOTION_LOG(ERR, TYPE_ENCODER, NO_ERRNO, _("Could not allocate output context"));
1516 ffmpeg_free_context(ffmpeg);
1517 return -1;
1518 }
1519
1520 if (ffmpeg->passthrough) {
1521 retcd = ffmpeg_passthru_codec(ffmpeg);
1522 if (retcd < 0 ) {
1523 MOTION_LOG(ERR, TYPE_ENCODER, NO_ERRNO, _("Could not setup passthru!"));
1524 ffmpeg_free_context(ffmpeg);
1525 return -1;
1526 }
1527
1528 ffmpeg_passthru_reset(ffmpeg);
1529
1530 } else {
1531 retcd = ffmpeg_get_oformat(ffmpeg);
1532 if (retcd < 0 ) {
1533 MOTION_LOG(ERR, TYPE_ENCODER, NO_ERRNO, _("Could not get codec!"));
1534 ffmpeg_free_context(ffmpeg);
1535 return -1;
1536 }
1537
1538 retcd = ffmpeg_set_codec(ffmpeg);
1539 if (retcd < 0 ) {
1540 MOTION_LOG(ERR, TYPE_ENCODER, NO_ERRNO, _("Failed to allocate codec!"));
1541 return -1;
1542 }
1543
1544 retcd = ffmpeg_set_stream(ffmpeg);
1545 if (retcd < 0){
1546 MOTION_LOG(ERR, TYPE_ENCODER, NO_ERRNO, _("Could not set the stream"));
1547 return -1;
1548 }
1549
1550 retcd = ffmpeg_set_picture(ffmpeg);
1551 if (retcd < 0){
1552 MOTION_LOG(ERR, TYPE_ENCODER, NO_ERRNO, _("Could not set the stream"));
1553 return -1;
1554 }
1555 }
1556
1557
1558
1559 retcd = ffmpeg_set_outputfile(ffmpeg);
1560 if (retcd < 0){
1561 MOTION_LOG(ERR, TYPE_ENCODER, NO_ERRNO, _("Could not set the stream"));
1562 return -1;
1563 }
1564
1565 return 0;
1566
1567 #else /* No FFMPEG */
1568
1569 if (ffmpeg) {
1570 MOTION_LOG(NTC, TYPE_ENCODER, NO_ERRNO, _("No ffmpeg functionality included"));
1571 }
1572 return -1;
1573
1574 #endif /* HAVE_FFMPEG */
1575
1576 }
1577
ffmpeg_close(struct ffmpeg * ffmpeg)1578 void ffmpeg_close(struct ffmpeg *ffmpeg){
1579 #ifdef HAVE_FFMPEG
1580
1581 if (ffmpeg != NULL) {
1582
1583 if (ffmpeg_flush_codec(ffmpeg) < 0){
1584 MOTION_LOG(ERR, TYPE_ENCODER, NO_ERRNO, _("Error flushing codec"));
1585 }
1586 if (ffmpeg->oc->pb != NULL){
1587 if (ffmpeg->tlapse != TIMELAPSE_APPEND) {
1588 av_write_trailer(ffmpeg->oc);
1589 }
1590 if (!(ffmpeg->oc->oformat->flags & AVFMT_NOFILE)) {
1591 if (ffmpeg->tlapse != TIMELAPSE_APPEND) {
1592 avio_close(ffmpeg->oc->pb);
1593 }
1594 }
1595 }
1596 ffmpeg_free_context(ffmpeg);
1597 ffmpeg_free_nal(ffmpeg);
1598 }
1599
1600 #else
1601 if (ffmpeg != NULL) free(ffmpeg);
1602 #endif // HAVE_FFMPEG
1603 }
1604
1605
ffmpeg_put_image(struct ffmpeg * ffmpeg,struct image_data * img_data,const struct timeval * tv1)1606 int ffmpeg_put_image(struct ffmpeg *ffmpeg, struct image_data *img_data, const struct timeval *tv1){
1607 #ifdef HAVE_FFMPEG
1608 int retcd = 0;
1609 int cnt = 0;
1610
1611
1612 if (ffmpeg->passthrough) {
1613 retcd = ffmpeg_passthru_put(ffmpeg, img_data);
1614 return retcd;
1615 }
1616
1617 if (ffmpeg->picture) {
1618
1619 if (ffmpeg->preferred_codec == USER_CODEC_V4L2M2M) {
1620 ffmpeg_put_pix_nv21(ffmpeg, img_data);
1621 } else {
1622 ffmpeg_put_pix_yuv420(ffmpeg, img_data);
1623 }
1624
1625 ffmpeg->gop_cnt ++;
1626 if (ffmpeg->gop_cnt == ffmpeg->ctx_codec->gop_size ){
1627 ffmpeg->picture->pict_type = AV_PICTURE_TYPE_I;
1628 ffmpeg->picture->key_frame = 1;
1629 ffmpeg->gop_cnt = 0;
1630 } else {
1631 ffmpeg->picture->pict_type = AV_PICTURE_TYPE_P;
1632 ffmpeg->picture->key_frame = 0;
1633 }
1634
1635 /* A return code of -2 is thrown by the put_frame
1636 * when a image is buffered. For timelapse, we absolutely
1637 * never want a frame buffered so we keep sending back the
1638 * the same pic until it flushes or fails in a different way
1639 */
1640 retcd = ffmpeg_put_frame(ffmpeg, tv1);
1641 while ((retcd == -2) && (ffmpeg->tlapse != TIMELAPSE_NONE)) {
1642 retcd = ffmpeg_put_frame(ffmpeg, tv1);
1643 cnt++;
1644 if (cnt > 50){
1645 MOTION_LOG(ERR, TYPE_ENCODER, NO_ERRNO
1646 ,_("Excessive attempts to clear buffered packet"));
1647 retcd = -1;
1648 }
1649 }
1650 //non timelapse buffered is ok
1651 if (retcd == -2){
1652 retcd = 0;
1653 MOTION_LOG(DBG, TYPE_ENCODER, NO_ERRNO, _("Buffered packet"));
1654 }
1655 }
1656
1657 return retcd;
1658
1659 #else
1660 if (ffmpeg && img_data && tv1) {
1661 MOTION_LOG(DBG, TYPE_ENCODER, NO_ERRNO, _("No ffmpeg support"));
1662 }
1663 return 0;
1664 #endif // HAVE_FFMPEG
1665 }
1666
ffmpeg_reset_movie_start_time(struct ffmpeg * ffmpeg,const struct timeval * tv1)1667 void ffmpeg_reset_movie_start_time(struct ffmpeg *ffmpeg, const struct timeval *tv1){
1668 #ifdef HAVE_FFMPEG
1669 int64_t one_frame_interval = av_rescale_q(1,(AVRational){1, ffmpeg->fps},ffmpeg->video_st->time_base);
1670 if (one_frame_interval <= 0)
1671 one_frame_interval = 1;
1672 ffmpeg->base_pts = ffmpeg->last_pts + one_frame_interval;
1673
1674 ffmpeg->start_time.tv_sec = tv1->tv_sec;
1675 ffmpeg->start_time.tv_usec = tv1->tv_usec;
1676
1677 #else
1678 if (ffmpeg && tv1) {
1679 MOTION_LOG(DBG, TYPE_ENCODER, NO_ERRNO, _("No ffmpeg support"));
1680 }
1681 #endif // HAVE_FFMPEG
1682 }
1683