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