I've been working on a project whereby I need to record video at a resolution of 1280x720, with at least 10 frames per second (the higher the better).

I've tried to do this using both a standard USB webcam (A Logitech C270) and the Raspberry Pi camera.

With the Logitech C270 it seems that the Pi can read a maximum of 10-12 Frames per second. However, when I try to write these frames to file it can only write at around 3 FPS.

I thought I would try the Raspberry Pi Camera module to record the video. I plugged it in and ran Raspivid. Without recording the video looked really good and responsive, certainly more than 10 FPS. I then tried recording it; when I played back the recording I got a number of error messages relating to the h264 codec and I was unable to view the video.

I then tried two further methods with the Pi Cam. Firstly I tried using a driver which makes the Pi Cam appear as a webcam, mounted at /dev/video0. This meant I could use my previous code to record the video, which I did. The results were the same, a limit of 3 FPS.

The next method I used was to adapt my code to use MMAL to grab frames directly from the Pi Cam. I still only got 3 FPS!

I have tried both the Pi 2 and the Pi 3, and have noticed little difference between either, although the Pi 3 is maybe 3.5 FPS.

The SD card I'm writing to is a Class 10, which I believe should be able to achieve the required write speeds.

I've also tried writing the video to a network socket for another machine to record, but I still only receive 3 Frames per second!

Is there anything I can do to get this to work? I've ordered an Odroid C2 to try, but I'd prefer to use a Pi. Is there an underlying reason for this 3 frames per second limit?

Incidentally I can run the same code on a Desktop machine and record at 30 FPS.

Here is the snippet of code I use to record the USB webcam:

    VideoCapture cap(0); // open the default camera
    cap.set(CV_CAP_PROP_FPS, fps);
    cap.set(CV_CAP_PROP_FRAME_WIDTH, 1280);
    cap.set(CV_CAP_PROP_FRAME_HEIGHT, 720);
    if(!cap.isOpened())  // check if we succeeded
        return -1;

    VideoWriter writer(filename, CV_FOURCC('M','P','4','2'), fps, Size(1280, 720), true);

    int count = 0; 
        std::cout > frame; // get a new frame from camera
        struct timeval tp;
        gettimeofday(&tp, NULL);
        unsigned long ms = tp.tv_sec * 1000 + tp.tv_usec / 1000;
        embed_timestamp(frame, ms);

        char str[64];
        sprintf(str, "%ul", ms);
        cv::putText(frame, str, cv::Point(50, 50), CV_FONT_HERSHEY_SIMPLEX, 0.5, cv::Scalar(0, 0, 255));


    return 0;

And this is the snippet of code that I use with the raspicam:

#include <ctime>
#include <iostream>
#include <raspicam/raspicam_cv.h>
#include <cstdio>

using namespace std; 

int main ( int argc,char **argv ) {

    time_t timer_begin,timer_end;
    raspicam::RaspiCam_Cv Camera;
    cv::Mat image;
    int nCount=100;

    cout<<"Opening Camera..."<<endl;
    if (!Camera.open()) {cerr<<"Error opening the camera"<<endl;return -1;}
    //Start capture
    cout<<"Capturing "<<nCount<<" frames ...."<<endl;
    time ( &timer_begin );

     cv::VideoWriter writer("Avideo.avi", CV_FOURCC('M', 'J', 'P', 'G'), 30, cv::Size(1280,960), true);

 for ( int i=0; i<nCount; i++ ) {
    char name[32] = {0};
        Camera.retrieve ( image);

    cout<<"Stop camera..."<<endl;
    //show time statistics
    time ( &timer_end ); /* get current time; same as: timer = time(NULL)  */
    double secondsElapsed = difftime ( timer_end,timer_begin );
    cout<< secondsElapsed<<" seconds for "<< nCount<<"  frames : FPS = "<<  ( float ) ( ( float ) ( nCount ) /secondsElapsed ) <<endl;


  • What is the colour depth/format you are using? I suppose you may be able to sacrifice some of the colour data to get the frame rate up - if someone can say how. I'm not an expert in this area but are you running a GUI at the same time (I'm guessing it might be more performant not to) and how much memory is put aside for the GPU? – SlySven Apr 16 '16 at 0:05
  • Something's wrong if you can't record a reasonable frame rate at 1280x720 using the Pi camera and raspivid. It's capable of 1920x1080 at 30fps. It would be helpful if you could post the commands you used to record and play back the video. Per SlySven's comment it's plausible that you haven't allocated enough memory to the GPU. Check your memory split. – goobering Apr 16 '16 at 16:07
  • The code itself does not display a GUI, I have tried running from the command line at start up, and running after startx and there is not much difference. I just left the memory split of the GPU as the default value. I don't have the Pi to hand but the command was something like raspivid -n -t 10000 -o video.avi, followed by mplayer video.avi which gave errors. That method is not ideal though, because I'd like to timestamp the frames. – James Apr 18 '16 at 8:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.