"Fossies" - the Fresh Open Source Software Archive

Member "motion-Release-4.3.0/src/ffmpeg.c" (14 Jan 2020, 57168 Bytes) of package /linux/misc/motion-Release-4.3.0.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "ffmpeg.c" see the Fossies "Dox" file reference documentation.

    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 /*********************************************/
   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 /*********************************************/
   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 /*********************************************/
  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 /*********************************************/
  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 /*********************************************/
  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 /*********************************************/
  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 /*********************************************/
  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 /*********************************************/
  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 /*********************************************/
  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 
  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 
  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 
  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  */
  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 
  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 
  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 
  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 
  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 
  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 
  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 
  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;
  701 
  702     for (i = 0; i < sizeof(blacklisted_codec)/sizeof(blacklisted_codec[0]); i++) {
  703         if (strcmp(codec_name, blacklisted_codec[i].codec_name) == 0)
  704             return blacklisted_codec[i].reason;
  705     }
  706     return NULL;
  707 }
  708 
  709 static int ffmpeg_set_codec_preferred(struct ffmpeg *ffmpeg){
  710     size_t codec_name_len = strcspn(ffmpeg->codec_name, ":");
  711 
  712     ffmpeg->codec = NULL;
  713     if (ffmpeg->codec_name[codec_name_len]) {
  714         const char *blacklist_reason = ffmpeg_codec_is_blacklisted(&ffmpeg->codec_name[codec_name_len+1]);
  715         if (blacklist_reason) {
  716             MOTION_LOG(WRN, TYPE_ENCODER, NO_ERRNO
  717                 ,_("Preferred codec %s has been blacklisted: %s")
  718                 ,&ffmpeg->codec_name[codec_name_len+1], blacklist_reason);
  719         } else {
  720             ffmpeg->codec = avcodec_find_encoder_by_name(&ffmpeg->codec_name[codec_name_len+1]);
  721             if ((ffmpeg->oc->oformat) && (ffmpeg->codec != NULL)) {
  722                     ffmpeg->oc->oformat->video_codec = ffmpeg->codec->id;
  723             } else if (ffmpeg->codec == NULL) {
  724                 MOTION_LOG(WRN, TYPE_ENCODER, NO_ERRNO
  725                     ,_("Preferred codec %s not found")
  726                     ,&ffmpeg->codec_name[codec_name_len+1]);
  727             }
  728         }
  729     }
  730     if (!ffmpeg->codec)
  731         ffmpeg->codec = avcodec_find_encoder(ffmpeg->oc->oformat->video_codec);
  732     if (!ffmpeg->codec) {
  733         MOTION_LOG(ERR, TYPE_ENCODER, NO_ERRNO
  734             ,_("Codec %s not found"), ffmpeg->codec_name);
  735         ffmpeg_free_context(ffmpeg);
  736         return -1;
  737     }
  738 
  739     if (strcmp(ffmpeg->codec->name, "h264_v4l2m2m") == 0){
  740         ffmpeg->preferred_codec = USER_CODEC_V4L2M2M;
  741     } else if (strcmp(ffmpeg->codec->name, "h264_omx") == 0){
  742         ffmpeg->preferred_codec = USER_CODEC_H264OMX;
  743     } else if (strcmp(ffmpeg->codec->name, "mpeg4_omx") == 0){
  744         ffmpeg->preferred_codec = USER_CODEC_MPEG4OMX;
  745     } else {
  746         ffmpeg->preferred_codec = USER_CODEC_DEFAULT;
  747     }
  748 
  749     if (ffmpeg->codec_name[codec_name_len])
  750         MOTION_LOG(NTC, TYPE_ENCODER, NO_ERRNO,_("Using codec %s"), ffmpeg->codec->name);
  751 
  752     return 0;
  753 
  754 }
  755 
  756 static int ffmpeg_set_codec(struct ffmpeg *ffmpeg){
  757 
  758     int retcd;
  759     char errstr[128];
  760     int chkrate;
  761 
  762     retcd = ffmpeg_set_codec_preferred(ffmpeg);
  763     if (retcd != 0) return retcd;
  764 
  765 #if (LIBAVFORMAT_VERSION_MAJOR >= 58) || ((LIBAVFORMAT_VERSION_MAJOR == 57) && (LIBAVFORMAT_VERSION_MINOR >= 41))
  766     //If we provide the codec to this, it results in a memory leak.  ffmpeg ticket: 5714
  767     ffmpeg->video_st = avformat_new_stream(ffmpeg->oc, NULL);
  768     if (!ffmpeg->video_st) {
  769         MOTION_LOG(ERR, TYPE_ENCODER, NO_ERRNO, _("Could not alloc stream"));
  770         ffmpeg_free_context(ffmpeg);
  771         return -1;
  772     }
  773     ffmpeg->ctx_codec = avcodec_alloc_context3(ffmpeg->codec);
  774     if (ffmpeg->ctx_codec == NULL) {
  775         MOTION_LOG(ERR, TYPE_ENCODER, NO_ERRNO, _("Failed to allocate decoder!"));
  776         ffmpeg_free_context(ffmpeg);
  777         return -1;
  778     }
  779 #else
  780     ffmpeg->video_st = avformat_new_stream(ffmpeg->oc, ffmpeg->codec);
  781     if (!ffmpeg->video_st) {
  782         MOTION_LOG(ERR, TYPE_ENCODER, NO_ERRNO, _("Could not alloc stream"));
  783         ffmpeg_free_context(ffmpeg);
  784         return -1;
  785     }
  786     ffmpeg->ctx_codec = ffmpeg->video_st->codec;
  787 #endif
  788 
  789 
  790     if (ffmpeg->tlapse != TIMELAPSE_NONE) {
  791         ffmpeg->ctx_codec->gop_size = 1;
  792     } else {
  793         if (ffmpeg->fps <= 5){
  794             ffmpeg->ctx_codec->gop_size = 1;
  795         } else if (ffmpeg->fps > 30){
  796             ffmpeg->ctx_codec->gop_size = 15;
  797         } else {
  798             ffmpeg->ctx_codec->gop_size = (ffmpeg->fps / 2);
  799         }
  800         ffmpeg->gop_cnt = ffmpeg->ctx_codec->gop_size - 1;
  801     }
  802 
  803     /*  For certain containers, setting the fps to very low numbers results in
  804     **  a very poor quality playback.  We can set the FPS to a higher number and
  805     **  then let the PTS display the frames correctly.
  806     */
  807     if ((ffmpeg->tlapse == TIMELAPSE_NONE) && (ffmpeg->fps <= 5)){
  808         if ((strcmp(ffmpeg->codec_name, "msmpeg4") == 0) ||
  809             (strcmp(ffmpeg->codec_name, "flv")     == 0) ||
  810             (strcmp(ffmpeg->codec_name, "mov") == 0) ||
  811             (strcmp(ffmpeg->codec_name, "mp4") == 0) ||
  812             (strcmp(ffmpeg->codec_name, "hevc") == 0) ||
  813             (strcmp(ffmpeg->codec_name, "mpeg4")   == 0)) {
  814             MOTION_LOG(NTC, TYPE_ENCODER, NO_ERRNO, _("Low fps. Encoding %d frames into a %d frames container."), ffmpeg->fps, 10);
  815             ffmpeg->fps = 10;
  816         }
  817     }
  818 
  819     ffmpeg->ctx_codec->codec_id      = ffmpeg->oc->oformat->video_codec;
  820     ffmpeg->ctx_codec->codec_type    = AVMEDIA_TYPE_VIDEO;
  821     ffmpeg->ctx_codec->bit_rate      = ffmpeg->bps;
  822     ffmpeg->ctx_codec->width         = ffmpeg->width;
  823     ffmpeg->ctx_codec->height        = ffmpeg->height;
  824     ffmpeg->ctx_codec->time_base.num = 1;
  825     ffmpeg->ctx_codec->time_base.den = ffmpeg->fps;
  826     if (ffmpeg->preferred_codec == USER_CODEC_V4L2M2M){
  827         ffmpeg->ctx_codec->pix_fmt   = AV_PIX_FMT_NV21;
  828     } else {
  829         ffmpeg->ctx_codec->pix_fmt   = MY_PIX_FMT_YUV420P;
  830     }
  831     ffmpeg->ctx_codec->max_b_frames  = 0;
  832     if (strcmp(ffmpeg->codec_name, "ffv1") == 0){
  833       ffmpeg->ctx_codec->strict_std_compliance = -2;
  834       ffmpeg->ctx_codec->level = 3;
  835     }
  836     ffmpeg->ctx_codec->flags |= MY_CODEC_FLAG_GLOBAL_HEADER;
  837 
  838     if ((strcmp(ffmpeg->codec->name, "h264_omx") == 0) ||
  839         (strcmp(ffmpeg->codec->name, "mpeg4_omx") == 0)) {
  840         /* h264_omx & ffmpeg combination locks up on Raspberry Pi.
  841          * To use h264_omx encoder, we need to disable zerocopy.
  842          * More information: https://github.com/Motion-Project/motion/issues/433
  843          */
  844         av_dict_set(&ffmpeg->opts, "zerocopy", "0", 0);
  845     }
  846 
  847     retcd = ffmpeg_set_quality(ffmpeg);
  848     if (retcd < 0){
  849         MOTION_LOG(ERR, TYPE_ENCODER, NO_ERRNO, _("Unable to set quality"));
  850         return -1;
  851     }
  852 
  853     retcd = avcodec_open2(ffmpeg->ctx_codec, ffmpeg->codec, &ffmpeg->opts);
  854     if (retcd < 0) {
  855         if (ffmpeg->codec->supported_framerates) {
  856             const AVRational *fps = ffmpeg->codec->supported_framerates;
  857             while (fps->num) {
  858                 MOTION_LOG(INF, TYPE_ENCODER, NO_ERRNO
  859                     ,_("Reported FPS Supported %d/%d"), fps->num, fps->den);
  860                 fps++;
  861             }
  862         }
  863         chkrate = 1;
  864         while ((chkrate < 36) && (retcd != 0)) {
  865             ffmpeg->ctx_codec->time_base.den = chkrate;
  866             retcd = avcodec_open2(ffmpeg->ctx_codec, ffmpeg->codec, &ffmpeg->opts);
  867             chkrate++;
  868         }
  869         if (retcd < 0){
  870             av_strerror(retcd, errstr, sizeof(errstr));
  871             MOTION_LOG(ERR, TYPE_ENCODER, NO_ERRNO, _("Could not open codec %s"),errstr);
  872             av_dict_free(&ffmpeg->opts);
  873             ffmpeg_free_context(ffmpeg);
  874             return -1;
  875         }
  876 
  877     }
  878     av_dict_free(&ffmpeg->opts);
  879 
  880     return 0;
  881 }
  882 
  883 static int ffmpeg_set_stream(struct ffmpeg *ffmpeg){
  884 
  885 #if (LIBAVFORMAT_VERSION_MAJOR >= 58) || ((LIBAVFORMAT_VERSION_MAJOR == 57) && (LIBAVFORMAT_VERSION_MINOR >= 41))
  886     int retcd;
  887     char errstr[128];
  888 
  889     retcd = avcodec_parameters_from_context(ffmpeg->video_st->codecpar,ffmpeg->ctx_codec);
  890     if (retcd < 0) {
  891         av_strerror(retcd, errstr, sizeof(errstr));
  892         MOTION_LOG(ERR, TYPE_ENCODER, NO_ERRNO
  893             ,_("Failed to copy decoder parameters!: %s"), errstr);
  894         ffmpeg_free_context(ffmpeg);
  895         return -1;
  896     }
  897 #endif
  898 
  899     ffmpeg->video_st->time_base = (AVRational){1, ffmpeg->fps};
  900 
  901     return 0;
  902 
  903 }
  904 
  905 /*Special allocation of video buffer for v4l2m2m codec*/
  906 static int ffmpeg_alloc_video_buffer(AVFrame *frame, int align)
  907 {
  908     const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(frame->format);
  909     int ret, i, padded_height;
  910     int plane_padding = FFMAX(16 + 16/*STRIDE_ALIGN*/, align);
  911 
  912     if (!desc)
  913         return AVERROR(EINVAL);
  914 
  915     if ((ret = av_image_check_size(frame->width, frame->height, 0, NULL)) < 0)
  916         return ret;
  917 
  918     if (!frame->linesize[0]) {
  919         if (align <= 0)
  920             align = 32; /* STRIDE_ALIGN. Should be av_cpu_max_align() */
  921 
  922         for(i=1; i<=align; i+=i) {
  923             ret = av_image_fill_linesizes(frame->linesize, frame->format,
  924                                           FFALIGN(frame->width, i));
  925             if (ret < 0)
  926                 return ret;
  927             if (!(frame->linesize[0] & (align-1)))
  928                 break;
  929         }
  930 
  931         for (i = 0; i < 4 && frame->linesize[i]; i++)
  932             frame->linesize[i] = FFALIGN(frame->linesize[i], align);
  933     }
  934 
  935     padded_height = FFALIGN(frame->height, 32);
  936     if ((ret = av_image_fill_pointers(frame->data, frame->format, padded_height,
  937                                       NULL, frame->linesize)) < 0)
  938         return ret;
  939 
  940     frame->buf[0] = av_buffer_alloc(ret + 4*plane_padding);
  941     if (!frame->buf[0]) {
  942         ret = AVERROR(ENOMEM);
  943         av_frame_unref(frame);
  944         return ret;
  945     }
  946     frame->buf[1] = av_buffer_alloc(ret + 4*plane_padding);
  947     if (!frame->buf[1]) {
  948         ret = AVERROR(ENOMEM);
  949         av_frame_unref(frame);
  950         return ret;
  951     }
  952 
  953     frame->data[0] = frame->buf[0]->data;
  954     frame->data[1] = frame->buf[1]->data;
  955     frame->data[2] = frame->data[1] + ((frame->width * padded_height) / 4);
  956 
  957     frame->extended_data = frame->data;
  958 
  959     return 0;
  960 }
  961 
  962 
  963 static int ffmpeg_set_picture(struct ffmpeg *ffmpeg){
  964 
  965     int retcd;
  966     char errstr[128];
  967 
  968     ffmpeg->picture = my_frame_alloc();
  969     if (!ffmpeg->picture) {
  970         MOTION_LOG(ERR, TYPE_ENCODER, NO_ERRNO, _("could not alloc frame"));
  971         ffmpeg_free_context(ffmpeg);
  972         return -1;
  973     }
  974 
  975     /* Take care of variable bitrate setting. */
  976     if (ffmpeg->quality)
  977         ffmpeg->picture->quality = ffmpeg->quality;
  978 
  979     ffmpeg->picture->linesize[0] = ffmpeg->ctx_codec->width;
  980     ffmpeg->picture->linesize[1] = ffmpeg->ctx_codec->width / 2;
  981     ffmpeg->picture->linesize[2] = ffmpeg->ctx_codec->width / 2;
  982 
  983     ffmpeg->picture->format = ffmpeg->ctx_codec->pix_fmt;
  984     ffmpeg->picture->width  = ffmpeg->ctx_codec->width;
  985     ffmpeg->picture->height = ffmpeg->ctx_codec->height;
  986 
  987     if (ffmpeg->preferred_codec == USER_CODEC_V4L2M2M) {
  988         retcd = ffmpeg_alloc_video_buffer(ffmpeg->picture, 32);
  989         if (retcd) {
  990             av_strerror(retcd, errstr, sizeof(errstr));
  991             MOTION_LOG(ERR, TYPE_ENCODER, NO_ERRNO, _("could not alloc buffers %s"), errstr);
  992             ffmpeg_free_context(ffmpeg);
  993             return -1;
  994         }
  995     }
  996 
  997     return 0;
  998 
  999 }
 1000 
 1001 static int ffmpeg_set_outputfile(struct ffmpeg *ffmpeg){
 1002 
 1003     int retcd;
 1004     char errstr[128];
 1005 
 1006 #if (LIBAVFORMAT_VERSION_MAJOR < 58)
 1007     snprintf(ffmpeg->oc->filename, sizeof(ffmpeg->oc->filename), "%s", ffmpeg->filename);
 1008 #endif
 1009 
 1010     /* Open the output file, if needed. */
 1011     if ((ffmpeg_timelapse_exists(ffmpeg->filename) == 0) || (ffmpeg->tlapse != TIMELAPSE_APPEND)) {
 1012         if (!(ffmpeg->oc->oformat->flags & AVFMT_NOFILE)) {
 1013             if (avio_open(&ffmpeg->oc->pb, ffmpeg->filename, MY_FLAG_WRITE) < 0) {
 1014                 if (errno == ENOENT) {
 1015                     if (create_path(ffmpeg->filename) == -1) {
 1016                         ffmpeg_free_context(ffmpeg);
 1017                         return -1;
 1018                     }
 1019                     if (avio_open(&ffmpeg->oc->pb, ffmpeg->filename, MY_FLAG_WRITE) < 0) {
 1020                         MOTION_LOG(ERR, TYPE_ENCODER, SHOW_ERRNO
 1021                             ,_("error opening file %s"), ffmpeg->filename);
 1022                         ffmpeg_free_context(ffmpeg);
 1023                         return -1;
 1024                     }
 1025                     /* Permission denied */
 1026                 } else if (errno ==  EACCES) {
 1027                     MOTION_LOG(ERR, TYPE_ENCODER, SHOW_ERRNO
 1028                         ,_("Permission denied. %s"),ffmpeg->filename);
 1029                     ffmpeg_free_context(ffmpeg);
 1030                     return -1;
 1031                 } else {
 1032                     MOTION_LOG(ERR, TYPE_ENCODER, SHOW_ERRNO
 1033                         ,_("Error opening file %s"), ffmpeg->filename);
 1034                     ffmpeg_free_context(ffmpeg);
 1035                     return -1;
 1036                 }
 1037             }
 1038         }
 1039 
 1040         /* Write the stream header,  For the TIMELAPSE_APPEND
 1041          * we write the data via standard file I/O so we close the
 1042          * items here
 1043          */
 1044         retcd = avformat_write_header(ffmpeg->oc, NULL);
 1045         if (retcd < 0){
 1046             av_strerror(retcd, errstr, sizeof(errstr));
 1047             MOTION_LOG(ERR, TYPE_ENCODER, NO_ERRNO
 1048                 ,_("Could not write ffmpeg header %s"),errstr);
 1049             ffmpeg_free_context(ffmpeg);
 1050             return -1;
 1051         }
 1052         if (ffmpeg->tlapse == TIMELAPSE_APPEND) {
 1053             av_write_trailer(ffmpeg->oc);
 1054             avio_close(ffmpeg->oc->pb);
 1055         }
 1056 
 1057     }
 1058 
 1059     return 0;
 1060 
 1061 }
 1062 
 1063 static int ffmpeg_flush_codec(struct ffmpeg *ffmpeg){
 1064 
 1065 #if (LIBAVFORMAT_VERSION_MAJOR >= 58) || ((LIBAVFORMAT_VERSION_MAJOR == 57) && (LIBAVFORMAT_VERSION_MINOR >= 41))
 1066     //ffmpeg version 3.1 and after
 1067 
 1068     int retcd;
 1069     int recv_cd = 0;
 1070     char errstr[128];
 1071 
 1072     if (ffmpeg->passthrough){
 1073         return 0;
 1074     }
 1075 
 1076     retcd = 0;
 1077     recv_cd = 0;
 1078     if (ffmpeg->tlapse == TIMELAPSE_NONE) {
 1079         retcd = avcodec_send_frame(ffmpeg->ctx_codec, NULL);
 1080         if (retcd < 0 ){
 1081             av_strerror(retcd, errstr, sizeof(errstr));
 1082             MOTION_LOG(ERR, TYPE_ENCODER, NO_ERRNO
 1083                 ,_("Error entering draining mode:%s"),errstr);
 1084             return -1;
 1085         }
 1086         while (recv_cd != AVERROR_EOF){
 1087             av_init_packet(&ffmpeg->pkt);
 1088             ffmpeg->pkt.data = NULL;
 1089             ffmpeg->pkt.size = 0;
 1090             recv_cd = avcodec_receive_packet(ffmpeg->ctx_codec, &ffmpeg->pkt);
 1091             if (recv_cd != AVERROR_EOF){
 1092                 if (recv_cd < 0){
 1093                     av_strerror(recv_cd, errstr, sizeof(errstr));
 1094                     MOTION_LOG(ERR, TYPE_ENCODER, NO_ERRNO
 1095                         ,_("Error draining codec:%s"),errstr);
 1096                     my_packet_unref(ffmpeg->pkt);
 1097                     return -1;
 1098                 }
 1099                 // v4l2_m2m encoder uses pts 0 and size 0 to indicate AVERROR_EOF
 1100                 if ((ffmpeg->pkt.pts == 0) || (ffmpeg->pkt.size == 0)) {
 1101                     recv_cd = AVERROR_EOF;
 1102                     my_packet_unref(ffmpeg->pkt);
 1103                     continue;
 1104                 }
 1105                 retcd = av_write_frame(ffmpeg->oc, &ffmpeg->pkt);
 1106                 if (retcd < 0) {
 1107                     MOTION_LOG(ERR, TYPE_ENCODER, NO_ERRNO
 1108                         ,_("Error writing draining video frame"));
 1109                     return -1;
 1110                 }
 1111             }
 1112             my_packet_unref(ffmpeg->pkt);
 1113         }
 1114     }
 1115     return 0;
 1116 #else
 1117     /* Dummy to kill warnings.  No draining in older ffmpeg versions */
 1118     if (ffmpeg) {
 1119         return 0;
 1120     } else{
 1121         return 0;
 1122     }
 1123 #endif
 1124 
 1125 }
 1126 
 1127 static int ffmpeg_put_frame(struct ffmpeg *ffmpeg, const struct timeval *tv1){
 1128     int retcd;
 1129 
 1130     av_init_packet(&ffmpeg->pkt);
 1131     ffmpeg->pkt.data = NULL;
 1132     ffmpeg->pkt.size = 0;
 1133 
 1134     retcd = ffmpeg_set_pts(ffmpeg, tv1);
 1135     if (retcd < 0) {
 1136         //If there is an error, it has already been reported.
 1137         my_packet_unref(ffmpeg->pkt);
 1138         return 0;
 1139     }
 1140 
 1141     retcd = ffmpeg_encode_video(ffmpeg);
 1142     if (retcd != 0){
 1143         if (retcd != -2){
 1144             MOTION_LOG(ERR, TYPE_ENCODER, NO_ERRNO, _("Error while encoding picture"));
 1145         }
 1146         my_packet_unref(ffmpeg->pkt);
 1147         return retcd;
 1148     }
 1149 
 1150     if (ffmpeg->tlapse == TIMELAPSE_APPEND) {
 1151         retcd = ffmpeg_timelapse_append(ffmpeg, ffmpeg->pkt);
 1152     } else {
 1153         retcd = av_write_frame(ffmpeg->oc, &ffmpeg->pkt);
 1154     }
 1155     my_packet_unref(ffmpeg->pkt);
 1156 
 1157     if (retcd < 0) {
 1158         MOTION_LOG(ERR, TYPE_ENCODER, NO_ERRNO, _("Error while writing video frame"));
 1159         return -1;
 1160     }
 1161     return retcd;
 1162 
 1163 }
 1164 
 1165 static void ffmpeg_passthru_reset(struct ffmpeg *ffmpeg){
 1166     /* Reset the written flag at start of each event */
 1167     int indx;
 1168 
 1169     pthread_mutex_lock(&ffmpeg->rtsp_data->mutex_pktarray);
 1170         for(indx = 0; indx < ffmpeg->rtsp_data->pktarray_size; indx++) {
 1171             ffmpeg->rtsp_data->pktarray[indx].iswritten = FALSE;
 1172         }
 1173     pthread_mutex_unlock(&ffmpeg->rtsp_data->mutex_pktarray);
 1174 
 1175 }
 1176 
 1177 static void ffmpeg_passthru_write(struct ffmpeg *ffmpeg, int indx){
 1178     /* Write the packet in the buffer at indx to file */
 1179     char errstr[128];
 1180     int retcd;
 1181 
 1182     av_init_packet(&ffmpeg->pkt);
 1183     ffmpeg->pkt.data = NULL;
 1184     ffmpeg->pkt.size = 0;
 1185 
 1186 
 1187     ffmpeg->rtsp_data->pktarray[indx].iswritten = TRUE;
 1188 
 1189     retcd = my_copy_packet(&ffmpeg->pkt, &ffmpeg->rtsp_data->pktarray[indx].packet);
 1190     if (retcd < 0) {
 1191         av_strerror(retcd, errstr, sizeof(errstr));
 1192         MOTION_LOG(INF, TYPE_ENCODER, NO_ERRNO, _("av_copy_packet: %s"),errstr);
 1193         my_packet_unref(ffmpeg->pkt);
 1194         return;
 1195     }
 1196 
 1197     retcd = ffmpeg_set_pktpts(ffmpeg, &ffmpeg->rtsp_data->pktarray[indx].timestamp_tv);
 1198     if (retcd < 0) {
 1199         my_packet_unref(ffmpeg->pkt);
 1200         return;
 1201     }
 1202 
 1203     ffmpeg->pkt.stream_index = 0;
 1204 
 1205     retcd = av_write_frame(ffmpeg->oc, &ffmpeg->pkt);
 1206     my_packet_unref(ffmpeg->pkt);
 1207     if (retcd < 0) {
 1208         av_strerror(retcd, errstr, sizeof(errstr));
 1209         MOTION_LOG(ERR, TYPE_ENCODER, NO_ERRNO
 1210             ,_("Error while writing video frame: %s"),errstr);
 1211         return;
 1212     }
 1213 
 1214 }
 1215 
 1216 static int ffmpeg_passthru_put(struct ffmpeg *ffmpeg, struct image_data *img_data){
 1217 
 1218     int idnbr_image, idnbr_lastwritten, idnbr_stop, idnbr_firstkey;
 1219     int indx, indx_lastwritten, indx_firstkey;
 1220 
 1221     if (ffmpeg->rtsp_data == NULL) return -1;
 1222 
 1223     if ((ffmpeg->rtsp_data->status == RTSP_NOTCONNECTED  ) ||
 1224         (ffmpeg->rtsp_data->status == RTSP_RECONNECTING  ) ){
 1225         return 0;
 1226     }
 1227 
 1228     if (ffmpeg->high_resolution){
 1229         idnbr_image = img_data->idnbr_high;
 1230     } else {
 1231         idnbr_image = img_data->idnbr_norm;
 1232     }
 1233 
 1234     pthread_mutex_lock(&ffmpeg->rtsp_data->mutex_pktarray);
 1235         idnbr_lastwritten = 0;
 1236         idnbr_firstkey = idnbr_image;
 1237         idnbr_stop = 0;
 1238         indx_lastwritten = -1;
 1239         indx_firstkey = -1;
 1240 
 1241         for(indx = 0; indx < ffmpeg->rtsp_data->pktarray_size; indx++) {
 1242             if ((ffmpeg->rtsp_data->pktarray[indx].iswritten) &&
 1243                 (ffmpeg->rtsp_data->pktarray[indx].idnbr > idnbr_lastwritten)){
 1244                 idnbr_lastwritten=ffmpeg->rtsp_data->pktarray[indx].idnbr;
 1245                 indx_lastwritten = indx;
 1246             }
 1247             if ((ffmpeg->rtsp_data->pktarray[indx].idnbr >  idnbr_stop) &&
 1248                 (ffmpeg->rtsp_data->pktarray[indx].idnbr <= idnbr_image)){
 1249                 idnbr_stop=ffmpeg->rtsp_data->pktarray[indx].idnbr;
 1250             }
 1251             if ((ffmpeg->rtsp_data->pktarray[indx].iskey) &&
 1252                 (ffmpeg->rtsp_data->pktarray[indx].idnbr <= idnbr_firstkey)){
 1253                     idnbr_firstkey=ffmpeg->rtsp_data->pktarray[indx].idnbr;
 1254                     indx_firstkey = indx;
 1255             }
 1256         }
 1257 
 1258         if (idnbr_stop == 0){
 1259             pthread_mutex_unlock(&ffmpeg->rtsp_data->mutex_pktarray);
 1260             return 0;
 1261         }
 1262 
 1263         if (indx_lastwritten != -1){
 1264             indx = indx_lastwritten;
 1265         } else if (indx_firstkey != -1) {
 1266             indx = indx_firstkey;
 1267         } else {
 1268             indx = 0;
 1269         }
 1270 
 1271         while (TRUE){
 1272             if ((!ffmpeg->rtsp_data->pktarray[indx].iswritten) &&
 1273                 (ffmpeg->rtsp_data->pktarray[indx].packet.size > 0) &&
 1274                 (ffmpeg->rtsp_data->pktarray[indx].idnbr >  idnbr_lastwritten) &&
 1275                 (ffmpeg->rtsp_data->pktarray[indx].idnbr <= idnbr_image)) {
 1276                 ffmpeg_passthru_write(ffmpeg, indx);
 1277             }
 1278             if (ffmpeg->rtsp_data->pktarray[indx].idnbr == idnbr_stop) break;
 1279             indx++;
 1280             if (indx == ffmpeg->rtsp_data->pktarray_size ) indx = 0;
 1281         }
 1282     pthread_mutex_unlock(&ffmpeg->rtsp_data->mutex_pktarray);
 1283     return 0;
 1284 }
 1285 
 1286 static int ffmpeg_passthru_codec(struct ffmpeg *ffmpeg){
 1287 
 1288     int retcd;
 1289     AVStream    *stream_in;
 1290 
 1291     if (ffmpeg->rtsp_data == NULL){
 1292         MOTION_LOG(ERR, TYPE_ENCODER, NO_ERRNO, _("RTSP context not available."));
 1293         return -1;
 1294     }
 1295 
 1296     pthread_mutex_lock(&ffmpeg->rtsp_data->mutex_transfer);
 1297 
 1298         if ((ffmpeg->rtsp_data->status == RTSP_NOTCONNECTED  ) ||
 1299             (ffmpeg->rtsp_data->status == RTSP_RECONNECTING  ) ){
 1300             MOTION_LOG(NTC, TYPE_ENCODER, NO_ERRNO
 1301                 ,_("rtsp camera not ready for pass-through."));
 1302             pthread_mutex_unlock(&ffmpeg->rtsp_data->mutex_transfer);
 1303             return -1;
 1304         }
 1305 
 1306         if (strcmp(ffmpeg->codec_name, "mp4") != 0){
 1307             MOTION_LOG(NTC, TYPE_ENCODER, NO_ERRNO
 1308                 ,_("pass-through mode enabled.  Changing to MP4 container."));
 1309             ffmpeg->codec_name = "mp4";
 1310         }
 1311 
 1312         retcd = ffmpeg_get_oformat(ffmpeg);
 1313         if (retcd < 0 ) {
 1314             MOTION_LOG(ERR, TYPE_ENCODER, NO_ERRNO, _("Could not get codec!"));
 1315             pthread_mutex_unlock(&ffmpeg->rtsp_data->mutex_transfer);
 1316             return -1;
 1317         }
 1318 
 1319 #if (LIBAVFORMAT_VERSION_MAJOR >= 58) || ((LIBAVFORMAT_VERSION_MAJOR == 57) && (LIBAVFORMAT_VERSION_MINOR >= 41))
 1320         stream_in = ffmpeg->rtsp_data->transfer_format->streams[0];
 1321         ffmpeg->oc->oformat->video_codec = stream_in->codecpar->codec_id;
 1322 
 1323         ffmpeg->video_st = avformat_new_stream(ffmpeg->oc, NULL);
 1324         if (!ffmpeg->video_st) {
 1325             MOTION_LOG(ERR, TYPE_ENCODER, NO_ERRNO, _("Could not alloc stream"));
 1326             pthread_mutex_unlock(&ffmpeg->rtsp_data->mutex_transfer);
 1327             return -1;
 1328         }
 1329 
 1330         retcd = avcodec_parameters_copy(ffmpeg->video_st->codecpar, stream_in->codecpar);
 1331         if (retcd < 0){
 1332             MOTION_LOG(ERR, TYPE_ENCODER, NO_ERRNO, _("Unable to copy codec parameters"));
 1333             pthread_mutex_unlock(&ffmpeg->rtsp_data->mutex_transfer);
 1334             return -1;
 1335         }
 1336         ffmpeg->video_st->codecpar->codec_tag  = 0;
 1337 
 1338 #elif (LIBAVFORMAT_VERSION_MAJOR >= 55)
 1339 
 1340         stream_in = ffmpeg->rtsp_data->transfer_format->streams[0];
 1341 
 1342         ffmpeg->video_st = avformat_new_stream(ffmpeg->oc, stream_in->codec->codec);
 1343         if (!ffmpeg->video_st) {
 1344             MOTION_LOG(ERR, TYPE_ENCODER, NO_ERRNO, _("Could not alloc stream"));
 1345             pthread_mutex_unlock(&ffmpeg->rtsp_data->mutex_transfer);
 1346             return -1;
 1347         }
 1348 
 1349         retcd = avcodec_copy_context(ffmpeg->video_st->codec, stream_in->codec);
 1350         if (retcd < 0){
 1351             MOTION_LOG(ERR, TYPE_ENCODER, NO_ERRNO, _("Unable to copy codec parameters"));
 1352             pthread_mutex_unlock(&ffmpeg->rtsp_data->mutex_transfer);
 1353             return -1;
 1354         }
 1355         ffmpeg->video_st->codec->flags     |= MY_CODEC_FLAG_GLOBAL_HEADER;
 1356         ffmpeg->video_st->codec->codec_tag  = 0;
 1357 #else
 1358         /* This is disabled in the util_check_passthrough but we need it here for compiling */
 1359         pthread_mutex_unlock(&ffmpeg->rtsp_data->mutex_transfer);
 1360         MOTION_LOG(INF, TYPE_ENCODER, NO_ERRNO, _("Pass-through disabled.  ffmpeg too old"));
 1361         return -1;
 1362 #endif
 1363 
 1364         ffmpeg->video_st->time_base         = stream_in->time_base;
 1365     pthread_mutex_unlock(&ffmpeg->rtsp_data->mutex_transfer);
 1366     MOTION_LOG(INF, TYPE_ENCODER, NO_ERRNO, _("Pass-through stream opened"));
 1367     return 0;
 1368 
 1369 }
 1370 
 1371 void ffmpeg_avcodec_log(void *ignoreme ATTRIBUTE_UNUSED, int errno_flag ATTRIBUTE_UNUSED, const char *fmt, va_list vl){
 1372 
 1373     char buf[1024];
 1374     char *end;
 1375 
 1376     /* Valgrind occasionally reports use of uninitialized values in here when we interrupt
 1377      * some rtsp functions.  The offending value is either fmt or vl and seems to be from a
 1378      * debug level of av functions.  To address it we flatten the message after we know
 1379      * the log level.  Now we put the avcodec messages to INF level since their error
 1380      * are not necessarily our errors.
 1381      */
 1382     if (errno_flag <= AV_LOG_WARNING){
 1383         /* Flatten the message coming in from avcodec. */
 1384         vsnprintf(buf, sizeof(buf), fmt, vl);
 1385         end = buf + strlen(buf);
 1386         if (end > buf && end[-1] == '\n')
 1387         {
 1388             *--end = 0;
 1389         }
 1390 
 1391         MOTION_LOG(INF, TYPE_ENCODER, NO_ERRNO, "%s", buf);
 1392     }
 1393 }
 1394 
 1395 static void ffmpeg_put_pix_nv21(struct ffmpeg *ffmpeg, struct image_data *img_data){
 1396     unsigned char *image,*imagecr, *imagecb;
 1397     int cr_len, x, y;
 1398 
 1399     if (ffmpeg->high_resolution){
 1400         image = img_data->image_high;
 1401     } else {
 1402         image = img_data->image_norm;
 1403     }
 1404 
 1405     cr_len = ffmpeg->ctx_codec->width * ffmpeg->ctx_codec->height / 4;
 1406     imagecr = image + (ffmpeg->ctx_codec->width * ffmpeg->ctx_codec->height);
 1407     imagecb = image + (ffmpeg->ctx_codec->width * ffmpeg->ctx_codec->height) + cr_len;
 1408 
 1409     memcpy(ffmpeg->picture->data[0], image, ffmpeg->ctx_codec->width * ffmpeg->ctx_codec->height);
 1410     for (y = 0; y < ffmpeg->ctx_codec->height; y++) {
 1411         for (x = 0; x < ffmpeg->ctx_codec->width/4; x++) {
 1412             ffmpeg->picture->data[1][y*ffmpeg->ctx_codec->width/2 + x*2] = *imagecb;
 1413             ffmpeg->picture->data[1][y*ffmpeg->ctx_codec->width/2 + x*2 + 1] = *imagecr;
 1414             imagecb++;
 1415             imagecr++;
 1416         }
 1417     }
 1418 
 1419 }
 1420 
 1421 static void ffmpeg_put_pix_yuv420(struct ffmpeg *ffmpeg, struct image_data *img_data){
 1422     unsigned char *image;
 1423 
 1424     if (ffmpeg->high_resolution){
 1425         image = img_data->image_high;
 1426     } else {
 1427         image = img_data->image_norm;
 1428     }
 1429 
 1430     // Usual setup for image pointers
 1431     ffmpeg->picture->data[0] = image;
 1432     ffmpeg->picture->data[1] = image + (ffmpeg->ctx_codec->width * ffmpeg->ctx_codec->height);
 1433     ffmpeg->picture->data[2] = ffmpeg->picture->data[1] + ((ffmpeg->ctx_codec->width * ffmpeg->ctx_codec->height) / 4);
 1434 
 1435 }
 1436 
 1437 
 1438 #endif /* HAVE_FFMPEG */
 1439 
 1440 /****************************************************************************
 1441  ****************************************************************************
 1442  ****************************************************************************/
 1443 
 1444 void ffmpeg_global_init(void){
 1445 #ifdef HAVE_FFMPEG
 1446 
 1447 
 1448     MOTION_LOG(NTC, TYPE_ENCODER, NO_ERRNO
 1449         ,_("ffmpeg libavcodec version %d.%d.%d"
 1450         " libavformat version %d.%d.%d")
 1451         , LIBAVCODEC_VERSION_MAJOR, LIBAVCODEC_VERSION_MINOR, LIBAVCODEC_VERSION_MICRO
 1452         , LIBAVFORMAT_VERSION_MAJOR, LIBAVFORMAT_VERSION_MINOR, LIBAVFORMAT_VERSION_MICRO);
 1453 
 1454 #if (LIBAVFORMAT_VERSION_MAJOR < 58)
 1455     /* TODO: Determine if this is even needed for older versions */
 1456     av_register_all();
 1457     avcodec_register_all();
 1458 #endif
 1459 
 1460 
 1461     avformat_network_init();
 1462     avdevice_register_all();
 1463     av_log_set_callback((void *)ffmpeg_avcodec_log);
 1464 
 1465 #if (LIBAVFORMAT_VERSION_MAJOR < 58)
 1466     /* TODO: Determine if this is even needed for older versions */
 1467     int ret;
 1468     ret = av_lockmgr_register(ffmpeg_lockmgr_cb);
 1469     if (ret < 0)
 1470     {
 1471         MOTION_LOG(EMG, TYPE_ALL, SHOW_ERRNO, _("av_lockmgr_register failed (%d)"), ret);
 1472         exit(1);
 1473     }
 1474 #endif
 1475 
 1476 #else /* No FFMPEG */
 1477 
 1478     MOTION_LOG(NTC, TYPE_ENCODER, NO_ERRNO, _("No ffmpeg functionality included"));
 1479 
 1480 #endif /* HAVE_FFMPEG */
 1481 }
 1482 
 1483 void ffmpeg_global_deinit(void) {
 1484 #ifdef HAVE_FFMPEG
 1485 
 1486     avformat_network_deinit();
 1487 
 1488 #if (LIBAVFORMAT_VERSION_MAJOR < 58)
 1489     /* TODO Determine if this is even needed for old versions */
 1490     if (av_lockmgr_register(NULL) < 0)
 1491     {
 1492         MOTION_LOG(EMG, TYPE_ALL, SHOW_ERRNO
 1493             ,_("av_lockmgr_register reset failed on cleanup"));
 1494     }
 1495 #endif
 1496 
 1497 
 1498 #else /* No FFMPEG */
 1499 
 1500     MOTION_LOG(NTC, TYPE_ENCODER, NO_ERRNO, _("No ffmpeg functionality included"));
 1501 
 1502 #endif /* HAVE_FFMPEG */
 1503 }
 1504 
 1505 int ffmpeg_open(struct ffmpeg *ffmpeg){
 1506 
 1507 #ifdef HAVE_FFMPEG
 1508 
 1509     int retcd;
 1510 
 1511     ffmpeg->oc = avformat_alloc_context();
 1512     if (!ffmpeg->oc) {
 1513         MOTION_LOG(ERR, TYPE_ENCODER, NO_ERRNO, _("Could not allocate output context"));
 1514         ffmpeg_free_context(ffmpeg);
 1515         return -1;
 1516     }
 1517 
 1518     if (ffmpeg->passthrough) {
 1519         retcd = ffmpeg_passthru_codec(ffmpeg);
 1520         if (retcd < 0 ) {
 1521             MOTION_LOG(ERR, TYPE_ENCODER, NO_ERRNO, _("Could not setup passthru!"));
 1522             ffmpeg_free_context(ffmpeg);
 1523             return -1;
 1524         }
 1525 
 1526         ffmpeg_passthru_reset(ffmpeg);
 1527 
 1528     } else {
 1529         retcd = ffmpeg_get_oformat(ffmpeg);
 1530         if (retcd < 0 ) {
 1531             MOTION_LOG(ERR, TYPE_ENCODER, NO_ERRNO, _("Could not get codec!"));
 1532             ffmpeg_free_context(ffmpeg);
 1533             return -1;
 1534         }
 1535 
 1536         retcd = ffmpeg_set_codec(ffmpeg);
 1537         if (retcd < 0 ) {
 1538             MOTION_LOG(ERR, TYPE_ENCODER, NO_ERRNO, _("Failed to allocate codec!"));
 1539             return -1;
 1540         }
 1541 
 1542         retcd = ffmpeg_set_stream(ffmpeg);
 1543         if (retcd < 0){
 1544             MOTION_LOG(ERR, TYPE_ENCODER, NO_ERRNO, _("Could not set the stream"));
 1545             return -1;
 1546         }
 1547 
 1548         retcd = ffmpeg_set_picture(ffmpeg);
 1549         if (retcd < 0){
 1550             MOTION_LOG(ERR, TYPE_ENCODER, NO_ERRNO, _("Could not set the stream"));
 1551             return -1;
 1552         }
 1553     }
 1554 
 1555 
 1556 
 1557     retcd = ffmpeg_set_outputfile(ffmpeg);
 1558     if (retcd < 0){
 1559         MOTION_LOG(ERR, TYPE_ENCODER, NO_ERRNO, _("Could not set the stream"));
 1560         return -1;
 1561     }
 1562 
 1563     return 0;
 1564 
 1565 #else /* No FFMPEG */
 1566 
 1567     if (ffmpeg) {
 1568         MOTION_LOG(NTC, TYPE_ENCODER, NO_ERRNO, _("No ffmpeg functionality included"));
 1569     }
 1570     return -1;
 1571 
 1572 #endif /* HAVE_FFMPEG */
 1573 
 1574 }
 1575 
 1576 void ffmpeg_close(struct ffmpeg *ffmpeg){
 1577 #ifdef HAVE_FFMPEG
 1578 
 1579     if (ffmpeg != NULL) {
 1580 
 1581         if (ffmpeg_flush_codec(ffmpeg) < 0){
 1582             MOTION_LOG(ERR, TYPE_ENCODER, NO_ERRNO, _("Error flushing codec"));
 1583         }
 1584         if (ffmpeg->oc->pb != NULL){
 1585             if (ffmpeg->tlapse != TIMELAPSE_APPEND) {
 1586                 av_write_trailer(ffmpeg->oc);
 1587             }
 1588             if (!(ffmpeg->oc->oformat->flags & AVFMT_NOFILE)) {
 1589                 if (ffmpeg->tlapse != TIMELAPSE_APPEND) {
 1590                     avio_close(ffmpeg->oc->pb);
 1591                 }
 1592             }
 1593         }
 1594         ffmpeg_free_context(ffmpeg);
 1595         ffmpeg_free_nal(ffmpeg);
 1596     }
 1597 
 1598 #else
 1599     if (ffmpeg != NULL) free(ffmpeg);
 1600 #endif // HAVE_FFMPEG
 1601 }
 1602 
 1603 
 1604 int ffmpeg_put_image(struct ffmpeg *ffmpeg, struct image_data *img_data, const struct timeval *tv1){
 1605 #ifdef HAVE_FFMPEG
 1606     int retcd = 0;
 1607     int cnt = 0;
 1608 
 1609 
 1610     if (ffmpeg->passthrough) {
 1611         retcd = ffmpeg_passthru_put(ffmpeg, img_data);
 1612         return retcd;
 1613     }
 1614 
 1615     if (ffmpeg->picture) {
 1616 
 1617         if (ffmpeg->preferred_codec == USER_CODEC_V4L2M2M) {
 1618             ffmpeg_put_pix_nv21(ffmpeg, img_data);
 1619         } else {
 1620             ffmpeg_put_pix_yuv420(ffmpeg, img_data);
 1621         }
 1622 
 1623         ffmpeg->gop_cnt ++;
 1624         if (ffmpeg->gop_cnt == ffmpeg->ctx_codec->gop_size ){
 1625             ffmpeg->picture->pict_type = AV_PICTURE_TYPE_I;
 1626             ffmpeg->picture->key_frame = 1;
 1627             ffmpeg->gop_cnt = 0;
 1628         } else {
 1629             ffmpeg->picture->pict_type = AV_PICTURE_TYPE_P;
 1630             ffmpeg->picture->key_frame = 0;
 1631         }
 1632 
 1633         /* A return code of -2 is thrown by the put_frame
 1634          * when a image is buffered.  For timelapse, we absolutely
 1635          * never want a frame buffered so we keep sending back the
 1636          * the same pic until it flushes or fails in a different way
 1637          */
 1638         retcd = ffmpeg_put_frame(ffmpeg, tv1);
 1639         while ((retcd == -2) && (ffmpeg->tlapse != TIMELAPSE_NONE)) {
 1640             retcd = ffmpeg_put_frame(ffmpeg, tv1);
 1641             cnt++;
 1642             if (cnt > 50){
 1643                 MOTION_LOG(ERR, TYPE_ENCODER, NO_ERRNO
 1644                     ,_("Excessive attempts to clear buffered packet"));
 1645                 retcd = -1;
 1646             }
 1647         }
 1648         //non timelapse buffered is ok
 1649         if (retcd == -2){
 1650             retcd = 0;
 1651             MOTION_LOG(DBG, TYPE_ENCODER, NO_ERRNO, _("Buffered packet"));
 1652         }
 1653     }
 1654 
 1655     return retcd;
 1656 
 1657 #else
 1658     if (ffmpeg && img_data && tv1) {
 1659         MOTION_LOG(DBG, TYPE_ENCODER, NO_ERRNO, _("No ffmpeg support"));
 1660     }
 1661     return 0;
 1662 #endif // HAVE_FFMPEG
 1663 }
 1664 
 1665 void ffmpeg_reset_movie_start_time(struct ffmpeg *ffmpeg, const struct timeval *tv1){
 1666 #ifdef HAVE_FFMPEG
 1667     int64_t one_frame_interval = av_rescale_q(1,(AVRational){1, ffmpeg->fps},ffmpeg->video_st->time_base);
 1668     if (one_frame_interval <= 0)
 1669         one_frame_interval = 1;
 1670     ffmpeg->base_pts = ffmpeg->last_pts + one_frame_interval;
 1671 
 1672     ffmpeg->start_time.tv_sec = tv1->tv_sec;
 1673     ffmpeg->start_time.tv_usec = tv1->tv_usec;
 1674 
 1675 #else
 1676     if (ffmpeg && tv1) {
 1677         MOTION_LOG(DBG, TYPE_ENCODER, NO_ERRNO, _("No ffmpeg support"));
 1678     }
 1679 #endif // HAVE_FFMPEG
 1680 }