/**************************************************************************** * apps/system/nxcamera/nxcamera_main.c * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. The * ASF licenses this file to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance with the * License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations * under the License. * ****************************************************************************/ /**************************************************************************** * Included Files ****************************************************************************/ #include #include #include #include #include #include #include #include #include #include #include #include /**************************************************************************** * Pre-processor Definitions ****************************************************************************/ #define NXCAMERA_VER "1.00" #ifdef CONFIG_NXCAMERA_INCLUDE_HELP # define NXCAMERA_HELP_TEXT(x) x #else # define NXCAMERA_HELP_TEXT(x) #endif /**************************************************************************** * Private Type Declarations ****************************************************************************/ typedef CODE int (*nxcamera_func)(FAR struct nxcamera_s *cam, FAR char *arg); struct nxcamera_cmd_s { FAR const char *cmd; /* The command text */ FAR const char *arghelp; /* Text describing the args */ nxcamera_func pfunc; /* Pointer to command handler */ FAR const char *help; /* The help text */ }; /**************************************************************************** * Private Function Prototypes ****************************************************************************/ static int nxcamera_cmd_quit(FAR struct nxcamera_s *pcam, FAR char *parg); static int nxcamera_cmd_stream(FAR struct nxcamera_s *pcam, FAR char *parg); static int nxcamera_cmd_input(FAR struct nxcamera_s *pcam, FAR char *parg); static int nxcamera_cmd_output(FAR struct nxcamera_s *pcam, FAR char *parg); static int nxcamera_cmd_stop(FAR struct nxcamera_s *pcam, FAR char *parg); #ifdef CONFIG_NXCAMERA_INCLUDE_HELP static int nxcamera_cmd_help(FAR struct nxcamera_s *pcam, FAR char *parg); #endif /**************************************************************************** * Private Data ****************************************************************************/ static const struct nxcamera_cmd_s g_nxcamera_cmds[] = { { "input", "videodev", nxcamera_cmd_input, NXCAMERA_HELP_TEXT("Specify a preferred capture device") }, { "output", "fbdev|filename", nxcamera_cmd_output, NXCAMERA_HELP_TEXT("Specify a display device or filename") }, #ifdef CONFIG_NXCAMERA_INCLUDE_HELP { "h", "", nxcamera_cmd_help, NXCAMERA_HELP_TEXT("Display help for commands") }, { "help", "", nxcamera_cmd_help, NXCAMERA_HELP_TEXT("Display help for commands") }, #endif { "stream", "width height framerate format", nxcamera_cmd_stream, NXCAMERA_HELP_TEXT("Video stream test (format is fourcc)") }, { "stop", "", nxcamera_cmd_stop, NXCAMERA_HELP_TEXT("Stop stream") }, { "q", "", nxcamera_cmd_quit, NXCAMERA_HELP_TEXT("Exit NxCamera") }, { "quit", "", nxcamera_cmd_quit, NXCAMERA_HELP_TEXT("Exit NxCamera") } }; static const int g_nxcamera_cmd_count = sizeof(g_nxcamera_cmds) / sizeof(struct nxcamera_cmd_s); /**************************************************************************** * Name: nxcamera_cmd_stream * * nxcamera_cmd_loop() play and record the raw data file using the nxcamera * context. * ****************************************************************************/ static int nxcamera_cmd_stream(FAR struct nxcamera_s *pcam, FAR char *parg) { uint16_t width = 0; uint16_t height = 0; uint32_t framerate = 0; uint32_t format = 0; int ret; char cc[5] = { 0 }; sscanf(parg, "%hd %hd %d %4s", &width, &height, &framerate, cc); format = v4l2_fourcc(cc[0], cc[1], cc[2], cc[3]); /* Try to stream raw data with settings specified */ ret = nxcamera_stream(pcam, width, height, framerate, format); /* nxcamera_stream returned values: * * OK Stream is being run * -EBUSY The media device is busy * -ENOSYS The video format is not unsupported * -ENODEV No video device suitable to capture media */ switch (ret) { case OK: break; case -ENODEV: printf("No suitable Video Device found\n"); break; case -EBUSY: printf("Video device busy\n"); break; case -ENOSYS: printf("Unknown video format\n"); break; default: printf("Error stream test: %d\n", ret); break; } return ret; } /**************************************************************************** * Name: nxcamera_cmd_stop * * nxcamera_cmd_stop() stops stream context. * ****************************************************************************/ static int nxcamera_cmd_stop(FAR struct nxcamera_s *pcam, FAR char *parg) { /* Stop the stream */ return nxcamera_stop(pcam); } /**************************************************************************** * Name: nxcamera_cmd_input * * nxcamera_cmd_input() sets the preferred capture device for stream. * ****************************************************************************/ static int nxcamera_cmd_input(FAR struct nxcamera_s *pcam, FAR char *parg) { int ret; char path[PATH_MAX]; /* First try to open the file directly */ ret = nxcamera_setdevice(pcam, parg); if (ret < 0) { /* Append the /dev path and try again */ snprintf(path, sizeof(path), "/dev/%s", parg); ret = nxcamera_setdevice(pcam, path); } /* Test if the device file exists */ if (ret == -ENOENT) { /* Device doesn't exit. Report error */ printf("Device %s not found\n", parg); } else if (ret == -ENODEV) { /* Test if is is an video device */ printf("Device %s is not an video device\n", parg); } /* Return error value */ return ret; } /**************************************************************************** * Name: nxcamera_cmd_output * * nxcamera_cmd_device() sets the output device/file for display/save. * ****************************************************************************/ static int nxcamera_cmd_output(FAR struct nxcamera_s *pcam, FAR char *parg) { int ret; char path[PATH_MAX]; FAR char *ext; bool isimage = false; /* First try to open the device directly */ ret = nxcamera_setfb(pcam, parg); if (ret < 0) { /* Append the /dev path and try again */ snprintf(path, sizeof(path), "/dev/%s", parg); ret = nxcamera_setfb(pcam, path); } /* Device doesn't exist or is not a video device. Treat as file */ if (ret < 0) { if (ret == -ENODEV) { printf("Device %s is not an video device\n", parg); return ret; } ext = strrchr(parg, '.'); if (ext && (ext != parg)) { ext++; isimage = strncmp(ext, "jpg", sizeof("jpg")) == 0 || strncmp(ext, "jpeg", sizeof("jpeg")) == 0; } ret = nxcamera_setfile(pcam, parg, isimage); } if (ret < 0) { /* Create file error. Report error */ printf("Error outputting to %s\n", parg); } /* Output device or file set successfully */ return ret; } /**************************************************************************** * Name: nxcamera_cmd_quit * * nxcamera_cmd_quit() terminates the application. * ****************************************************************************/ static int nxcamera_cmd_quit(FAR struct nxcamera_s *pcam, FAR char *parg) { /* Stop the stream if any */ return nxcamera_stop(pcam); } /**************************************************************************** * Name: nxcamera_cmd_help * * nxcamera_cmd_help() displays the application's help information on * supported commands and command syntax. * ****************************************************************************/ #ifdef CONFIG_NXCAMERA_INCLUDE_HELP static int nxcamera_cmd_help(FAR struct nxcamera_s *pcam, FAR char *parg) { int len; int maxlen = 0; int x; int c; /* Calculate length of longest cmd + arghelp */ for (x = 0; x < g_nxcamera_cmd_count; x++) { len = strlen(g_nxcamera_cmds[x].cmd) + strlen(g_nxcamera_cmds[x].arghelp); if (len > maxlen) { maxlen = len; } } printf("NxCamera commands\n================\n"); for (x = 0; x < g_nxcamera_cmd_count; x++) { /* Print the command and it's arguments */ printf(" %s %s", g_nxcamera_cmds[x].cmd, g_nxcamera_cmds[x].arghelp); /* Calculate number of spaces to print before the help text */ len = maxlen - (strlen(g_nxcamera_cmds[x].cmd) + strlen(g_nxcamera_cmds[x].arghelp)); for (c = 0; c < len; c++) { printf(" "); } printf(" : %s\n", g_nxcamera_cmds[x].help); } return OK; } #endif /**************************************************************************** * Public Functions ****************************************************************************/ /**************************************************************************** * Name: nxcamera * * nxcamera reads in commands from the console using the readline * system add-in and impalements a command-line based media loop * tester that uses the NuttX video system to capture and then display * or save video from the lower video driver. Commands are provided for * setting width, height, framerate, pixel format and other video controls, * as well as for stopping the test. * ****************************************************************************/ int main(int argc, FAR char *argv[]) { char buffer[CONFIG_NSH_LINELEN]; int len; int x; bool running = true; FAR char *cmd; FAR char *arg; FAR struct nxcamera_s *pcam; printf("NxCamera version " NXCAMERA_VER "\n"); printf("h for commands, q to exit\n"); #ifndef CONFIG_LIBYUV printf("Libyuv is not enabled, won't output to RGB framebuffer\n"); #endif printf("\n"); /* Initialize our NxCamera context */ pcam = nxcamera_create(); if (pcam == NULL) { printf("Error: Out of RAM\n"); return -ENOMEM; } /* Loop until the user exits */ while (running) { /* Print a prompt */ printf("nxcamera> "); fflush(stdout); /* Read a line from the terminal */ len = readline(buffer, sizeof(buffer), stdin, stdout); if (len > 0) { buffer[len] = '\0'; if (strncmp(buffer, "!", 1) != 0) { /* nxcamera command */ if (buffer[len - 1] == '\n') { buffer[len - 1] = '\0'; } /* Parse the command from the argument */ cmd = strtok_r(buffer, " \n", &arg); if (cmd == NULL) { continue; } /* Find the command in our cmd array */ for (x = 0; x < g_nxcamera_cmd_count; x++) { if (strcmp(cmd, g_nxcamera_cmds[x].cmd) == 0) { /* Command found. Call it's handler if not NULL */ if (g_nxcamera_cmds[x].pfunc != NULL) { g_nxcamera_cmds[x].pfunc(pcam, arg); } /* Test if it is a quit command */ if (g_nxcamera_cmds[x].pfunc == nxcamera_cmd_quit) { running = false; } break; } } } else { #ifdef CONFIG_SYSTEM_SYSTEM /* Transfer nuttx shell */ system(buffer + 1); #else printf("%s: unknown nxcamera command\n", buffer); #endif } } } /* Release the NxCamera context */ nxcamera_release(pcam); return OK; }