title: C++ OpenCV 3.4 / FFMPEG 3.4.1 VideoWriter and MP4 Output File Format
body: <p>I'm running on an ARM BeagleBone X-15 Debian machine with Linux Kernel 4.9.35-ti-r44. In my C++ ( Qt 5 ) application, I want to save my cv::Mat frames to an MP4 format video. I have libx264 installed and compiled from scratch both ffmpeg and OpenCv. I can successfully record and view video with MJPEG with the AVI video container type but not MP4. Whenever I try to write an MP4 video, I get run time errors of the form:</p>
  
  <pre><code>OpenCV: FFMPEG: tag 0x44495658/'XVID' is not supported with codec id 13 and format 'mp4 / MP4 (MPEG-4 Part 14)'
  OpenCV: FFMPEG: fallback to use tag 0x00000020/' ???'
  </code></pre>
  
  <p>I've tried various Google answers but none have worked.</p>
  
  <p>Relevant code:</p>
  
  <pre><code>cv::Size frameSize = frame.size();
  
  qDebug() &lt;&lt; "Initializing Video Recording to save Video file here: " &lt;&lt; destinationFileName;
  
  std::string filename = destinationFileName.toStdString();
  //int fcc =   CV_FOURCC('M','J','P','G');
  //int fcc =   CV_FOURCC('X','2','6','4');
  int fcc = CV_FOURCC('X','V','I','D');
  int fps =   1;
  videoRecorder = new cv::VideoWriter(filename,fcc,fps,frameSize);
  
  ...
  
  videoRecorder-&gt;write(frame);
  </code></pre>
  
  <p>I've downloaded and built the latest OpenCV 3.4 but the problem persists. 
  How can I write to an MP4 File with OpenCV's video writer?</p>
  
  <p>When I try the 'X','2','6','4' format I get the error:</p>
  
  <pre><code>    Initializing Video Recording to save Video file here:  "/tmp/Garage.mp4"
  OpenCV: FFMPEG: tag 0x34363258/'X264' is not supported with codec id 28 and format 'mp4 / MP4 (MPEG-4 Part 14)'
  OpenCV: FFMPEG: fallback to use tag 0x31637661/'avc1'
  [h264_v4l2m2m @ 0x81042020] Could not find a valid device
  [h264_v4l2m2m @ 0x81042020] can't configure encoder
  Could not open codec 'h264_v4l2m2m': Unspecified error
  Starting
  </code></pre>
  
  <p>When I try the 'X','V','I','D' format I get the error:</p>
  
  <pre><code>Initializing Video Recording to save Video file here:  "/tmp/Garage.mp4"
  OpenCV: FFMPEG: tag 0x44495658/'XVID' is not supported with codec id 13 and format 'mp4 / MP4 (MPEG-4 Part 14)'
  OpenCV: FFMPEG: fallback to use tag 0x7634706d/'mp4v'
  Starting
  </code></pre>
  
  <p>When I try the 'M','P','E','G' format I get the error:</p>
  
  <pre><code>Initializing Video Recording to save Video file here:  "/tmp/Garage.mp4"
  OpenCV: FFMPEG: tag 0x4745504d/'MPEG' is not supported with codec id 2 and format 'mp4 / MP4 (MPEG-4 Part 14)'
  OpenCV: FFMPEG: fallback to use tag 0x7634706d/'mp4v'
  Starting
  </code></pre>
  
  <p>When I try the 'H','2','6','4' format I get the error:</p>
  
  <pre><code>OpenCV: FFMPEG: tag 0x34363248/'H264' is not supported with codec id 28 and format 'mp4 / MP4 (MPEG-4 Part 14)'
  OpenCV: FFMPEG: fallback to use tag 0x31637661/'avc1'
  [h264_v4l2m2m @ 0x7fdde340] Could not find a valid device
  [h264_v4l2m2m @ 0x7fdde340] can't configure encoder
  Could not open codec 'h264_v4l2m2m': Unspecified error
  Starting
  </code></pre>
  
  <p>When I try the 'M','P','4','V' format I get the error:</p>
  
  <pre><code>Initializing Video Recording to save Video file here:  "/tmp/Garage.mp4"
  OpenCV: FFMPEG: tag 0x5634504d/'MP4V' is not supported with codec id 13 and format 'mp4 / MP4 (MPEG-4 Part 14)'
  OpenCV: FFMPEG: fallback to use tag 0x7634706d/'mp4v'
  Starting
  </code></pre>
  
  <p>When I try the 'A','V','C','1' format I get the error:</p>
  
  <pre><code>Initializing Video Recording to save Video file here:  "/tmp/Garage.mp4"
  OpenCV: FFMPEG: tag 0x31435641/'AVC1' is not supported with codec id 28 and format 'mp4 / MP4 (MPEG-4 Part 14)'
  OpenCV: FFMPEG: fallback to use tag 0x31637661/'avc1'
  [h264_v4l2m2m @ 0x810f5f50] Could not find a valid device
  [h264_v4l2m2m @ 0x810f5f50] can't configure encoder
  Could not open codec 'h264_v4l2m2m': Unspecified error
  Starting
  </code></pre>
  
  <p>When I try the 'D','I','V','X' format I get the error:</p>
  
  <pre><code>Initializing Video Recording to save Video file here:  "/tmp/Garage.mp4"
  OpenCV: FFMPEG: tag 0x58564944/'DIVX' is not supported with codec id 13 and format 'mp4 / MP4 (MPEG-4 Part 14)'
  OpenCV: FFMPEG: fallback to use tag 0x7634706d/'mp4v'
  Starting
  </code></pre>
  
  <p>When I try the 0x21 format I get the error:</p>
  
  <pre><code>Initializing Video Recording to save Video file here:  "/tmp/Garage.mp4"
  OpenCV: FFMPEG: tag 0x00000021/'!???' is not found (format 'mp4 / MP4 (MPEG-4 Part 14)')'
  Starting
  </code></pre>
  
  <p>Here is my complete class which shows all tried formats:</p>
  
  <pre><code>    #include "downloader.h"
  
  Downloader::Downloader(QString url, QString destinationFile) : downloadUrl(url) , destinationFileName(destinationFile)
  {
  
      didInitializeVideoWriter = false;
  
      qDebug() &lt;&lt; "Initialized Downloader...";
  
  }
  
  Downloader::~Downloader() {
  
      videoRecorder-&gt;release();
      delete videoRecorder;
  
  }
  
  void Downloader::doDownload()
  {
      networkManager = new QNetworkAccessManager(this);
  
      connect(networkManager, SIGNAL(finished(QNetworkReply*)),
              this, SLOT(replyFinished(QNetworkReply*)));
  
      networkManager-&gt;get(QNetworkRequest(QUrl(downloadUrl)));
  }
  
  void Downloader::writeFrame(cv::Mat frame) {
  
      QMutexLocker locker(&amp;videoFrameMutex);
  
      videoRecorder-&gt;write(frame);
  
  }
  
  void Downloader::replyFinished(QNetworkReply *reply)
  {
  
      if(reply-&gt;error())
      {
          qDebug() &lt;&lt; "ERROR!";
          qDebug() &lt;&lt; reply-&gt;errorString();
      }
      else
      {
          //qDebug() &lt;&lt; reply-&gt;header(QNetworkRequest::ContentTypeHeader).toString();
          //qDebug() &lt;&lt; reply-&gt;header(QNetworkRequest::LastModifiedHeader).toDateTime().toString();
          //qDebug() &lt;&lt; reply-&gt;header(QNetworkRequest::ContentLengthHeader).toULongLong();
          qDebug() &lt;&lt; reply-&gt;attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
          qDebug() &lt;&lt; reply-&gt;attribute(QNetworkRequest::HttpReasonPhraseAttribute).toString();
  
          QString tempFileName = destinationFileName;
          QString jpegTempFilename = QString("%1").arg(tempFileName.replace("mp4","jpeg"));
  
          qDebug() &lt;&lt; "Overwriting: " &lt;&lt; jpegTempFilename;
          QFile *file = new QFile(jpegTempFilename);
          if(file-&gt;open(QFile::WriteOnly))
          {
              file-&gt;write(reply-&gt;readAll());
              file-&gt;flush();
              file-&gt;close();
          }
          delete file;
  
          cv::Mat frame = imread(jpegTempFilename.toStdString(), CV_LOAD_IMAGE_COLOR);   // CV_LOAD_IMAGE_COLOR (&gt;0) loads the image in the BGR format
          cv::cvtColor(frame,frame,CV_BGR2RGB);
  
          // Now lazy load the recorder
          if ( !didInitializeVideoWriter ) {
  
              cv::Size frameSize = frame.size();
  
              qDebug() &lt;&lt; "Initializing Video Recording to save Video file here: " &lt;&lt; destinationFileName;
  
              std::string filename = destinationFileName.toStdString();
              //int fcc =   CV_FOURCC('M','J','P','G');
              int fcc =   CV_FOURCC('X','2','6','4');
              //int fcc = CV_FOURCC('X','V','I','D');
              //int fcc = CV_FOURCC('M','P','E','G');
              //int fcc = CV_FOURCC('H','2','6','4');
              //int fcc = CV_FOURCC('M','P','4','V');
              //int fcc = CV_FOURCC('A','V','C','1');
              //int fcc = CV_FOURCC('D','I','V','X');
              //int fcc = 0x21;
              //int fcc = 0x00000021;
              int fps =   1;
              videoRecorder = new cv::VideoWriter(filename,fcc,fps,frameSize);
  
              qDebug() &lt;&lt; "Starting";
              frameCounter = 1;
              performanceTimer.start();
  
              didInitializeVideoWriter = true;
  
          }
  
          cv::putText(frame,"[REC]",cv::Point(50,50),5,1,cv::Scalar(0,0,225));
  
          QFuture&lt;void&gt; backgroundRun = QtConcurrent::run(this, &amp;Downloader::writeFrame, frame);
          //backgroundRun.waitForFinished();
  
      }
  
      reply-&gt;deleteLater();
  
      qDebug() &lt;&lt; "RequestTimer: " &lt;&lt; performanceTimer.elapsed() &lt;&lt; frameCounter;
  
      // Requests Again
      networkManager-&gt;get(QNetworkRequest(QUrl(downloadUrl)));
  
      frameCounter++;
  
      performanceTimer.restart();
  
  
  }
  </code></pre>
  
  <p>Update - I tried 'a','v','c','1' and unfortunately that also does not work:</p>
  
  <pre><code>Initializing Video Recording to save Video file here:  "/tmp/Garage.mp4"
  [h264_v4l2m2m @ 0x810f6aa0] Could not find a valid device
  [h264_v4l2m2m @ 0x810f6aa0] can't configure encoder
  Could not open codec 'h264_v4l2m2m': Unspecified error
  
  (qt-downloader:6234): GStreamer-CRITICAL **: gst_element_make_from_uri: assertion 'gst_uri_is_valid (uri)' failed
  OpenCV Error: Unspecified error (GStreamer: cannot link elements
  ) in CvVideoWriter_GStreamer::open, file /media/usb/opencv/modules/videoio/src/cap_gstreamer.cpp, line 1635
  VIDEOIO(cvCreateVideoWriter_GStreamer (filename, fourcc, fps, frameSize, is_color)): raised OpenCV exception:
  
  /media/usb/opencv/modules/videoio/src/cap_gstreamer.cpp:1635: error: (-2) GStreamer: cannot link elements
   in function CvVideoWriter_GStreamer::open
  </code></pre>
  
  <p>When I try the X264 FOURCC, the mp4 file is 48 bytes and never grows:</p>
  
  <pre><code>Initializing Video Recording to save Video file here:  "/tmp/Garage.mp4"
  OpenCV: FFMPEG: tag 0x34363258/'X264' is not supported with codec id 27 and format 'mp4 / MP4 (MPEG-4 Part 14)'
  OpenCV: FFMPEG: fallback to use tag 0x31637661/'avc1'
  </code></pre>
  
  <p>Static Size:</p>
  
  <pre><code>debian@BeagleBoard-X15:/tmp$ ls -lrt Garage.*
  -rw-r--r-- 1 debian debian     48 Dec 24 21:13 Garage.mp4
  -rw-r--r-- 1 debian debian 100424 Dec 24 21:14 Garage.jpeg
  debian@BeagleBoard-X15:/tmp$ hexdump Garage.mp4 
  0000000 0000 2000 7466 7079 7369 6d6f 0000 0002
  0000010 7369 6d6f 7369 326f 7661 3163 706d 3134
  0000020 0000 0800 7266 6565 0000 0000 646d 7461
  0000030
  </code></pre>
  
  <p>Here is my ffmpeg build conf:</p>
  
  <pre><code>debian@BeagleBoard-X15:/tmp$ ffmpeg -buildconf
  ffmpeg version N-89524-g74f408cc8e Copyright (c) 2000-2017 the FFmpeg developers
    built with gcc 6.3.0 (Debian 6.3.0-18) 20170516
    configuration: --enable-gpl --enable-libx264 --enable-pthreads --enable-static --extra-cflags=-I./x264/include --extra-ldflags=-L./x264/lib --extra-libs=-ldl
    libavutil      56.  6.100 / 56.  6.100
    libavcodec     58.  8.100 / 58.  8.100
    libavformat    58.  3.100 / 58.  3.100
    libavdevice    58.  0.100 / 58.  0.100
    libavfilter     7.  7.100 /  7.  7.100
    libswscale      5.  0.101 /  5.  0.101
    libswresample   3.  0.101 /  3.  0.101
    libpostproc    55.  0.100 / 55.  0.100
  
    configuration:
      --enable-gpl
      --enable-libx264
      --enable-pthreads
      --enable-static
      --extra-cflags=-I./x264/include
      --extra-ldflags=-L./x264/lib
      --extra-libs=-ldl
  </code></pre>