{"id":91,"date":"2014-01-18T16:45:14","date_gmt":"2014-01-18T16:45:14","guid":{"rendered":"http:\/\/ceptimus.co.uk\/?p=91"},"modified":"2014-01-18T16:45:14","modified_gmt":"2014-01-18T16:45:14","slug":"controlling-the-raspberry-pi-camera-from-c","status":"publish","type":"post","link":"https:\/\/ceptimus.co.uk\/index.php\/2014\/01\/18\/controlling-the-raspberry-pi-camera-from-c\/","title":{"rendered":"Controlling the Raspberry Pi camera from C"},"content":{"rendered":"<p>I wanted to be able to stop and start the camera driven by events instead of just calling raspivid to record for a preset time.<\/p>\n<p>My code is really just a simple wrapper around raspivid using the SIGUSR1 option to stop the video under program control rather than after a preset time.<\/p>\n<p>The example main() function starts the video, sleeps for five seconds and then stops it.\u00a0 For demo purposes I included the options for black and white inverted video.\u00a0 To record with the normal raspivid defaults you just call startVideo with an empty options string:<\/p>\n<p>startVideo(&#8220;filename.h264&#8221;, &#8220;&#8221;);<\/p>\n<p>Obviously you can put any of the normal raspivid options in the string &#8211; but you should avoid -t, -n, -o, and -s as the code fills those in for you.\u00a0 If you want to enable preview\/monitoring then make the obvious change to remove the -n (no preview) option.<\/p>\n<p>Save code as, say, video.c and compile with gcc -o video video.c<\/p>\n<pre>#include &lt;signal.h&gt;\n#include &lt;unistd.h&gt;\n#include &lt;stdio.h&gt;\n#include &lt;stdlib.h&gt;\n#include &lt;string.h&gt;\n\nstatic pid_t pid = 0;\n\nvoid startVideo(char *filename, char *options) {\n    if ((pid = fork()) == 0) {\n        char **cmd;\n\n        \/\/ count tokens in options string\n        int count = 0;\n        char *copy;\n        copy = strdup(options);\n        if (strtok(copy, \" \\t\") != NULL) {\n            count = 1;\n            while (strtok(NULL, \" \\t\") != NULL)\n                count++;\n        }\n\n        cmd = malloc((count + 8) * sizeof(char **));\n        free(copy);\n\n        \/\/ if any tokens in options, \n        \/\/ copy them to cmd starting at positon[1]\n        if (count) {\n            int i;\n            copy = strdup(options);\n            cmd[1] = strtok(copy, \" \\t\");\n            for (i = 2; i &lt;= count; i++)\n                cmd[i] = strtok(NULL, \" \\t\");\n        }\n\n        \/\/ add default options\n        cmd[0] = \"raspivid\"; \/\/ executable name\n        cmd[count + 1] = \"-n\"; \/\/ no preview\n        cmd[count + 2] = \"-t\"; \/\/ default time (overridden by -s)\n                               \/\/ but needed for clean exit\n        cmd[count + 3] = \"10\"; \/\/ 10 millisecond (minimum) time for -t\n        cmd[count + 4] = \"-s\"; \/\/ enable USR1 signal to stop recording\n        cmd[count + 5] = \"-o\"; \/\/ output file specifer\n        cmd[count + 6] = filename;\n        cmd[count + 7] = (char *)0; \/\/ terminator\n        execv(\"\/usr\/bin\/raspivid\", cmd);\n    }\n}\n\nvoid stopVideo(void) {\n    if (pid) {\n        kill(pid, 10); \/\/ seems to stop with two signals separated\n                       \/\/ by 1 second if started with -t 10 parameter\n        sleep(1);\n        kill(pid, 10);\n    }\n}\n\nint main(int argc, char **argv) {\n    printf(\"Recording video for 5 secs...\");\n    \/\/ example options give an upside-down black and white video\n    startVideo(\"temp.h264\", \"-cfx 128:128 -rot 180\"); \n    fflush(stdout);\n    sleep(5);\n    stopVideo();\n    printf(\"\\nVideo stopped - exiting in 2 secs.\\n\");\n    sleep(2);\n    return 0;\n}<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>I wanted to be able to stop and start the camera driven by events instead of just calling raspivid to record for a preset time. My code is really just a simple wrapper around raspivid using the SIGUSR1 option to stop the video under program control rather than after a preset time. The example main() [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4],"tags":[],"class_list":["post-91","post","type-post","status-publish","format-standard","hentry","category-programming"],"_links":{"self":[{"href":"https:\/\/ceptimus.co.uk\/index.php\/wp-json\/wp\/v2\/posts\/91","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/ceptimus.co.uk\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/ceptimus.co.uk\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/ceptimus.co.uk\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/ceptimus.co.uk\/index.php\/wp-json\/wp\/v2\/comments?post=91"}],"version-history":[{"count":0,"href":"https:\/\/ceptimus.co.uk\/index.php\/wp-json\/wp\/v2\/posts\/91\/revisions"}],"wp:attachment":[{"href":"https:\/\/ceptimus.co.uk\/index.php\/wp-json\/wp\/v2\/media?parent=91"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/ceptimus.co.uk\/index.php\/wp-json\/wp\/v2\/categories?post=91"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/ceptimus.co.uk\/index.php\/wp-json\/wp\/v2\/tags?post=91"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}