static void video_thread_save_shot(struct image_t *img, struct image_t *img_jpeg) { // Search for a file where we can write to char save_name[128]; for (; video_thread.shot_number < 99999; video_thread.shot_number++) { sprintf(save_name, "%s/img_%05d.jpg", STRINGIFY(VIDEO_THREAD_SHOT_PATH), video_thread.shot_number); // Check if file exists or not if (access(save_name, F_OK) == -1) { // Create a high quality image (99% JPEG encoded) jpeg_encode_image(img, img_jpeg, 99, TRUE); #if JPEG_WITH_EXIF_HEADER write_exif_jpeg(save_name, img_jpeg->buf, img_jpeg->buf_size, img_jpeg->w, img_jpeg->h); #else FILE *fp = fopen(save_name, "w"); if (fp == NULL) { printf("[video_thread-thread] Could not write shot %s.\n", save_name); } else { // Save it to the file and close it fwrite(img_jpeg->buf, sizeof(uint8_t), img_jpeg->buf_size, fp); fclose(fp); } #endif // We don't need to seek for a next index anymore break; } } }
static void save_shot_on_disk(struct image_t *img, struct image_t *img_jpeg) { // Search for a file where we can write to char save_name[128]; snprintf(save_name, sizeof(save_name), "%s/img_%05d.jpg", foldername, shotNumber); shotNumber++; // Check if file exists or not if (access(save_name, F_OK) == -1) { // Create a high quality image (99% JPEG encoded) jpeg_encode_image(img, img_jpeg, 99, TRUE); #if VIDEO_USB_LOGGER_JPEG_WITH_EXIF_HEADER write_exif_jpeg(save_name, img_jpeg->buf, img_jpeg->buf_size, img_jpeg->w, img_jpeg->h); #else FILE *fp = fopen(save_name, "w"); if (fp == NULL) { printf("[video_thread-thread] Could not write shot %s.\n", save_name); } else { // Save it to the file and close it fwrite(img_jpeg->buf, sizeof(uint8_t), img_jpeg->buf_size, fp); fclose(fp); printf("Wrote image\n"); } #endif /** Log the values to a csv file */ if (video_usb_logger == NULL) { return; } static uint32_t counter = 0; struct pose_t pose = get_rotation_at_timestamp(img->pprz_ts); struct NedCoor_i *ned = stateGetPositionNed_i(); struct NedCoor_i *accel = stateGetAccelNed_i(); static uint32_t sonar = 0; // Save current information to a file fprintf(video_usb_logger, "%d,%d,%f,%f,%f,%d,%d,%d,%d,%d,%d,%f,%f,%f,%d\n", counter, shotNumber, pose.eulers.phi, pose.eulers.theta, pose.eulers.psi, ned->x, ned->y, ned->z, accel->x, accel->y, accel->z, pose.rates.p, pose.rates.q, pose.rates.r, sonar); counter++; } }
void iV_saveImage_JPEG(const char *fileName, const iV_Image *image) { unsigned char *buffer = NULL; unsigned char *jpeg = NULL; char newfilename[PATH_MAX]; unsigned int currentRow; const unsigned int row_stride = image->width * 3; // 3 bytes per pixel PHYSFS_file* fileHandle; unsigned char *jpeg_end; sstrcpy(newfilename, fileName); memcpy(newfilename + strlen(newfilename) - 4, ".jpg", 4); fileHandle = PHYSFS_openWrite(newfilename); if (fileHandle == NULL) { debug(LOG_ERROR, "pie_JPEGSaveFile: PHYSFS_openWrite failed (while opening file %s) with error: %s\n", fileName, PHYSFS_getLastError()); return; } buffer = (unsigned char *)malloc(sizeof(const char*) * image->height * image->width); // Suspect it should be sizeof(unsigned char)*3 == 3 here, not sizeof(const char *) == 8. if (buffer == NULL) { debug(LOG_ERROR, "pie_JPEGSaveFile: Couldn't allocate memory\n"); return; } // Create an array of scanlines for (currentRow = 0; currentRow < image->height; ++currentRow) { // We're filling the scanline from the bottom up here, // otherwise we'd have a vertically mirrored image. memcpy(buffer + row_stride * currentRow, &image->bmp[row_stride * (image->height - currentRow - 1)], row_stride); } jpeg = (unsigned char *)malloc(sizeof(const char*) * image->height * image->width); // Suspect it should be something else here, but sizeof(const char *) == 8 is hopefully big enough... if (jpeg == NULL) { debug(LOG_ERROR, "pie_JPEGSaveFile: Couldn't allocate memory\n"); free(buffer); return; } jpeg_end = jpeg_encode_image(buffer, jpeg, 1, JPEG_FORMAT_RGB, image->width, image->height); PHYSFS_write(fileHandle, jpeg, jpeg_end - jpeg, 1); free(buffer); free(jpeg); PHYSFS_close(fileHandle); }
void video_capture_save(struct image_t *img) { // Declare storage for image location char save_name[128]; // Simple shot counter to find first available image location for (/* no init */; video_capture_index < 9999; ++video_capture_index) { // Generate image location sprintf(save_name, "%s/img_%05d.jpg", STRINGIFY(VIDEO_CAPTURE_PATH), video_capture_index); // Continue with next number if file exists already if (access(save_name, F_OK) != -1) { continue; } printf("[video_capture] Saving image to %s.\n", save_name); // Open file FILE *fp = fopen(save_name, "w"); if (fp == NULL) { printf("[video_capture] Could not write shot %s.\n", save_name); break; } // Create jpg image from raw frame struct image_t img_jpeg; image_create(&img_jpeg, img->w, img->h, IMAGE_JPEG); jpeg_encode_image(img, &img_jpeg, VIDEO_CAPTURE_JPEG_QUALITY, true); // Save it to the file and close it fwrite(img_jpeg.buf, sizeof(uint8_t), img_jpeg.buf_size, fp); fclose(fp); // Free image image_free(&img_jpeg); // End loop here break; } }
struct image_t *viewvideo_function(struct image_t *img) { // Resize image if needed struct image_t img_small; image_create(&img_small, img->w / viewvideo.downsize_factor, img->h / viewvideo.downsize_factor, IMAGE_YUV422); // Create the JPEG encoded image struct image_t img_jpeg; image_create(&img_jpeg, img_small.w, img_small.h, IMAGE_JPEG); #if VIEWVIDEO_USE_NETCAT char nc_cmd[64]; sprintf(nc_cmd, "nc %s %d 2>/dev/null", STRINGIFY(VIEWVIDEO_HOST), VIEWVIDEO_PORT_OUT); #endif if (viewvideo.is_streaming) { // Only resize when needed if (viewvideo.downsize_factor != 1) { image_yuv422_downsample(img, &img_small, viewvideo.downsize_factor); jpeg_encode_image(&img_small, &img_jpeg, VIEWVIDEO_QUALITY_FACTOR, VIEWVIDEO_USE_NETCAT); } else { jpeg_encode_image(img, &img_jpeg, VIEWVIDEO_QUALITY_FACTOR, VIEWVIDEO_USE_NETCAT); } #if VIEWVIDEO_USE_NETCAT // Open process to send using netcat (in a fork because sometimes kills itself???) pid_t pid = fork(); if (pid < 0) { printf("[viewvideo] Could not create netcat fork.\n"); } else if (pid == 0) { // We are the child and want to send the image FILE *netcat = popen(nc_cmd, "w"); if (netcat != NULL) { fwrite(img_jpeg.buf, sizeof(uint8_t), img_jpeg.buf_size, netcat); pclose(netcat); // Ignore output, because it is too much when not connected } else { printf("[viewvideo] Failed to open netcat process.\n"); } // Exit the program since we don't want to continue after transmitting exit(0); } else { // We want to wait until the child is finished wait(NULL); } #else if (viewvideo.use_rtp) { // Send image with RTP rtp_frame_send( &video_sock, // UDP socket &img_jpeg, 0, // Format 422 VIEWVIDEO_QUALITY_FACTOR, // Jpeg-Quality 0, // DRI Header VIEWVIDEO_RTP_TIME_INC // 90kHz time increment ); // Extra note: when the time increment is set to 0, // it is automaticaly calculated by the send_rtp_frame function // based on gettimeofday value. This seems to introduce some lag or jitter. // An other way is to compute the time increment and set the correct value. // It seems that a lower value is also working (when the frame is received // the timestamp is always "late" so the frame is displayed immediately). // Here, we set the time increment to the lowest possible value // (1 = 1/90000 s) which is probably stupid but is actually working. } #endif } // Free all buffers image_free(&img_jpeg); image_free(&img_small); return NULL; // No new images were created }