Camera in sample for GR-PEACH. This sample works on GR-LYCHEE besides GR-PEACH.
Video Links on how to setup and run Camera_in Application:
Your video will be live at: https://youtu.be/XNH8jLhjeS4 Part1 of 1
Camera in sample for GR-PEACH or GR-LYCHEE. While USER_BUTTON0 is pressed, it will save the camera image(default is jpeg fotmat) to USB memory or SD card.
If both USB and SD are inserted, GR-PEACH or GR-LYCHEE connect to the previously detected device.
The default setting of serial communication (baud rate etc.) in mbed is shown the following link.
Please refer to the link and change the settings of your PC terminal software.
The default value of baud rate in mbed is 9600, and this application uses baud rate 9600.
https://developer.mbed.org/teams/Renesas/wiki/GR-PEACH-Getting-Started#install-the-usb-serial-communication
Please refer to following link about Audio/Camera Shield.
https://developer.mbed.org/teams/Renesas/wiki/Audio_Camera-shield
You can configure this sample application via the following definitions. If you set to 1, it will save the video file as a AVI format:
main.cpp
/**** User Selection *********/ #define SAVE_FILE_TYPE (0) /* Select 0(Image(.jpg)) or 1(Movie(.avi)) */ /*****************************/
- USB channel available in this sample program
By default, the GR-PEACH's USB connector (USB0) is configured to be used. When using USB0, please close GR-PEACH's JP3.
Or, you can use the Audio/Camera Shield's USB connector (USB1). When using USB1, you need to close JP1 of Audio/Camera Shield.
- Specify each configuration
To specify camera and LCD, add camera-type and lcd-type to mbed_app.json.
For details, please refer to mbed-gr-libs / README.md.
mbed_app.json
{ "config": { "camera":{ "help": "0:disable 1:enable", "value": "1" }, "camera-type":{ "help": "Please see mbed-gr-libs/README.md", "value": "CAMERA_CVBS" }, "lcd":{ "help": "0:disable 1:enable", "value": "0" }, "lcd-type":{ "help": "Please see mbed-gr-libs/README.md", "value": "GR_PEACH_4_3INCH_SHIELD" }, "usb-host-ch":{ "help": "(for GR-PEACH) 0:ch0 1:ch1", "value": "1" }, "audio-camera-shield":{ "help": "(for GR-PEACH) 0:not use 1:use", "value": "1" } } }
main.cpp@3:2c8f1cf3333b, 2018-12-26 (annotated)
- Committer:
- 1050186
- Date:
- Wed Dec 26 05:29:18 2018 +0000
- Revision:
- 3:2c8f1cf3333b
- Parent:
- 2:9d98159fa9c9
- Child:
- 4:6c5869e28c94
Support Mbed OS 5.10, replace Renesas libraries to mbed-gr-libs and optimize main.cpp and related files for supporting GR-LYCHEE too.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
dkato | 0:2f1caf4ce924 | 1 | #include "mbed.h" |
1050186 | 3:2c8f1cf3333b | 2 | #include "EasyAttach_CameraAndLCD.h" |
1050186 | 3:2c8f1cf3333b | 3 | #include "SdUsbConnect.h" |
1050186 | 3:2c8f1cf3333b | 4 | #include "JPEG_Converter.h" |
1050186 | 3:2c8f1cf3333b | 5 | #include "dcache-control.h" |
dkato | 0:2f1caf4ce924 | 6 | |
dkato | 0:2f1caf4ce924 | 7 | /**** User Selection *********/ |
1050186 | 3:2c8f1cf3333b | 8 | #define SAVA_FILE_TYPE (0) /* Select 0(Image(.jpg)) or 1(Movie(.avi)) */ |
dkato | 0:2f1caf4ce924 | 9 | /*****************************/ |
dkato | 0:2f1caf4ce924 | 10 | |
1050186 | 3:2c8f1cf3333b | 11 | #define MOUNT_NAME "storage" |
dkato | 0:2f1caf4ce924 | 12 | |
dkato | 0:2f1caf4ce924 | 13 | /*! Frame buffer stride: Frame buffer stride should be set to a multiple of 32 or 128 |
dkato | 0:2f1caf4ce924 | 14 | in accordance with the frame buffer burst transfer mode. */ |
1050186 | 3:2c8f1cf3333b | 15 | #define VIDEO_PIXEL_HW (640u) /* VGA */ |
1050186 | 3:2c8f1cf3333b | 16 | #define VIDEO_PIXEL_VW (480u) /* VGA */ |
dkato | 0:2f1caf4ce924 | 17 | |
1050186 | 3:2c8f1cf3333b | 18 | #define FRAME_BUFFER_STRIDE (((VIDEO_PIXEL_HW * 2) + 31u) & ~31u) |
1050186 | 3:2c8f1cf3333b | 19 | #define FRAME_BUFFER_HEIGHT (VIDEO_PIXEL_VW) |
dkato | 0:2f1caf4ce924 | 20 | |
dkato | 1:aaa4b3e0f03c | 21 | #if defined(__ICCARM__) |
1050186 | 3:2c8f1cf3333b | 22 | #pragma data_alignment=32 |
1050186 | 3:2c8f1cf3333b | 23 | static uint8_t user_frame_buffer0[FRAME_BUFFER_STRIDE * FRAME_BUFFER_HEIGHT]@ ".mirrorram"; |
dkato | 1:aaa4b3e0f03c | 24 | #else |
1050186 | 3:2c8f1cf3333b | 25 | static uint8_t user_frame_buffer0[FRAME_BUFFER_STRIDE * FRAME_BUFFER_HEIGHT]__attribute((section("NC_BSS"),aligned(32))); |
dkato | 1:aaa4b3e0f03c | 26 | #endif |
1050186 | 3:2c8f1cf3333b | 27 | static int file_name_index = 1; |
1050186 | 3:2c8f1cf3333b | 28 | static volatile int Vfield_Int_Cnt = 0; |
1050186 | 3:2c8f1cf3333b | 29 | /* jpeg convert */ |
1050186 | 3:2c8f1cf3333b | 30 | static JPEG_Converter Jcu; |
1050186 | 3:2c8f1cf3333b | 31 | #if defined(__ICCARM__) |
1050186 | 3:2c8f1cf3333b | 32 | #pragma data_alignment=32 |
1050186 | 3:2c8f1cf3333b | 33 | static uint8_t JpegBuffer[1024 * 63]; |
1050186 | 3:2c8f1cf3333b | 34 | #else |
1050186 | 3:2c8f1cf3333b | 35 | static uint8_t JpegBuffer[1024 * 63]__attribute((aligned(32))); |
1050186 | 3:2c8f1cf3333b | 36 | #endif |
dkato | 0:2f1caf4ce924 | 37 | |
1050186 | 3:2c8f1cf3333b | 38 | DisplayBase Display; |
1050186 | 3:2c8f1cf3333b | 39 | DigitalIn button0(USER_BUTTON0); |
1050186 | 3:2c8f1cf3333b | 40 | DigitalOut led1(LED1); |
1050186 | 3:2c8f1cf3333b | 41 | |
1050186 | 3:2c8f1cf3333b | 42 | static void IntCallbackFunc_Vfield(DisplayBase::int_type_t int_type) { |
1050186 | 3:2c8f1cf3333b | 43 | if (Vfield_Int_Cnt > 0) { |
1050186 | 3:2c8f1cf3333b | 44 | Vfield_Int_Cnt--; |
dkato | 0:2f1caf4ce924 | 45 | } |
dkato | 0:2f1caf4ce924 | 46 | } |
dkato | 0:2f1caf4ce924 | 47 | |
1050186 | 3:2c8f1cf3333b | 48 | static void wait_new_image(void) { |
1050186 | 3:2c8f1cf3333b | 49 | Vfield_Int_Cnt = 1; |
1050186 | 3:2c8f1cf3333b | 50 | while (Vfield_Int_Cnt > 0) { |
1050186 | 3:2c8f1cf3333b | 51 | ThisThread::sleep_for(1); |
dkato | 0:2f1caf4ce924 | 52 | } |
dkato | 0:2f1caf4ce924 | 53 | } |
dkato | 0:2f1caf4ce924 | 54 | |
1050186 | 3:2c8f1cf3333b | 55 | static void Start_Video_Camera(void) { |
1050186 | 3:2c8f1cf3333b | 56 | // Initialize the background to black |
1050186 | 3:2c8f1cf3333b | 57 | for (uint32_t i = 0; i < sizeof(user_frame_buffer0); i += 2) { |
1050186 | 3:2c8f1cf3333b | 58 | user_frame_buffer0[i + 0] = 0x10; |
1050186 | 3:2c8f1cf3333b | 59 | user_frame_buffer0[i + 1] = 0x80; |
dkato | 0:2f1caf4ce924 | 60 | } |
dkato | 0:2f1caf4ce924 | 61 | |
1050186 | 3:2c8f1cf3333b | 62 | // Field end signal for recording function in scaler 0 |
1050186 | 3:2c8f1cf3333b | 63 | Display.Graphics_Irq_Handler_Set(DisplayBase::INT_TYPE_S0_VFIELD, 0, IntCallbackFunc_Vfield); |
1050186 | 3:2c8f1cf3333b | 64 | |
1050186 | 3:2c8f1cf3333b | 65 | // Video capture setting (progressive form fixed) |
1050186 | 3:2c8f1cf3333b | 66 | Display.Video_Write_Setting( |
1050186 | 3:2c8f1cf3333b | 67 | DisplayBase::VIDEO_INPUT_CHANNEL_0, |
1050186 | 3:2c8f1cf3333b | 68 | DisplayBase::COL_SYS_NTSC_358, |
1050186 | 3:2c8f1cf3333b | 69 | (void *)user_frame_buffer0, |
1050186 | 3:2c8f1cf3333b | 70 | FRAME_BUFFER_STRIDE, |
1050186 | 3:2c8f1cf3333b | 71 | DisplayBase::VIDEO_FORMAT_YCBCR422, |
1050186 | 3:2c8f1cf3333b | 72 | DisplayBase::WR_RD_WRSWA_32_16BIT, |
1050186 | 3:2c8f1cf3333b | 73 | VIDEO_PIXEL_VW, |
1050186 | 3:2c8f1cf3333b | 74 | VIDEO_PIXEL_HW |
1050186 | 3:2c8f1cf3333b | 75 | ); |
1050186 | 3:2c8f1cf3333b | 76 | EasyAttach_CameraStart(Display, DisplayBase::VIDEO_INPUT_CHANNEL_0); |
1050186 | 3:2c8f1cf3333b | 77 | } |
dkato | 0:2f1caf4ce924 | 78 | |
1050186 | 3:2c8f1cf3333b | 79 | #if MBED_CONF_APP_LCD |
1050186 | 3:2c8f1cf3333b | 80 | static void Start_LCD_Display(void) { |
1050186 | 3:2c8f1cf3333b | 81 | DisplayBase::rect_t rect; |
dkato | 0:2f1caf4ce924 | 82 | |
1050186 | 3:2c8f1cf3333b | 83 | rect.vs = 0; |
1050186 | 3:2c8f1cf3333b | 84 | rect.vw = VIDEO_PIXEL_VW; |
1050186 | 3:2c8f1cf3333b | 85 | rect.hs = 0; |
1050186 | 3:2c8f1cf3333b | 86 | rect.hw = VIDEO_PIXEL_HW; |
1050186 | 3:2c8f1cf3333b | 87 | Display.Graphics_Read_Setting( |
1050186 | 3:2c8f1cf3333b | 88 | DisplayBase::GRAPHICS_LAYER_0, |
1050186 | 3:2c8f1cf3333b | 89 | (void *)user_frame_buffer0, |
1050186 | 3:2c8f1cf3333b | 90 | FRAME_BUFFER_STRIDE, |
1050186 | 3:2c8f1cf3333b | 91 | DisplayBase::GRAPHICS_FORMAT_YCBCR422, |
1050186 | 3:2c8f1cf3333b | 92 | DisplayBase::WR_RD_WRSWA_32_16BIT, |
1050186 | 3:2c8f1cf3333b | 93 | &rect |
1050186 | 3:2c8f1cf3333b | 94 | ); |
1050186 | 3:2c8f1cf3333b | 95 | Display.Graphics_Start(DisplayBase::GRAPHICS_LAYER_0); |
1050186 | 3:2c8f1cf3333b | 96 | |
1050186 | 3:2c8f1cf3333b | 97 | ThisThread::sleep_for(50); |
1050186 | 3:2c8f1cf3333b | 98 | EasyAttach_LcdBacklight(true); |
1050186 | 3:2c8f1cf3333b | 99 | } |
dkato | 0:2f1caf4ce924 | 100 | #endif |
dkato | 0:2f1caf4ce924 | 101 | |
1050186 | 3:2c8f1cf3333b | 102 | #if (SAVA_FILE_TYPE == 0) |
1050186 | 3:2c8f1cf3333b | 103 | static void save_image_jpg(void) { |
1050186 | 3:2c8f1cf3333b | 104 | size_t jcu_encode_size = 0; |
1050186 | 3:2c8f1cf3333b | 105 | JPEG_Converter::bitmap_buff_info_t bitmap_buff_info; |
1050186 | 3:2c8f1cf3333b | 106 | JPEG_Converter::encode_options_t encode_options; |
1050186 | 3:2c8f1cf3333b | 107 | |
1050186 | 3:2c8f1cf3333b | 108 | bitmap_buff_info.width = VIDEO_PIXEL_HW; |
1050186 | 3:2c8f1cf3333b | 109 | bitmap_buff_info.height = VIDEO_PIXEL_VW; |
1050186 | 3:2c8f1cf3333b | 110 | bitmap_buff_info.format = JPEG_Converter::WR_RD_YCbCr422; |
1050186 | 3:2c8f1cf3333b | 111 | bitmap_buff_info.buffer_address = (void *)user_frame_buffer0; |
dkato | 0:2f1caf4ce924 | 112 | |
1050186 | 3:2c8f1cf3333b | 113 | encode_options.encode_buff_size = sizeof(JpegBuffer); |
1050186 | 3:2c8f1cf3333b | 114 | encode_options.p_EncodeCallBackFunc = NULL; |
1050186 | 3:2c8f1cf3333b | 115 | encode_options.input_swapsetting = JPEG_Converter::WR_RD_WRSWA_32_16_8BIT; |
1050186 | 3:2c8f1cf3333b | 116 | |
1050186 | 3:2c8f1cf3333b | 117 | dcache_invalid(JpegBuffer, sizeof(JpegBuffer)); |
1050186 | 3:2c8f1cf3333b | 118 | if (Jcu.encode(&bitmap_buff_info, JpegBuffer, &jcu_encode_size, &encode_options) == JPEG_Converter::JPEG_CONV_OK) { |
1050186 | 3:2c8f1cf3333b | 119 | char file_name[32]; |
1050186 | 3:2c8f1cf3333b | 120 | sprintf(file_name, "/"MOUNT_NAME"/img_%d.jpg", file_name_index++); |
1050186 | 3:2c8f1cf3333b | 121 | FILE * fp = fopen(file_name, "w"); |
1050186 | 3:2c8f1cf3333b | 122 | if (fp != NULL) { |
1050186 | 3:2c8f1cf3333b | 123 | setvbuf(fp, NULL, _IONBF, 0); // unbuffered |
1050186 | 3:2c8f1cf3333b | 124 | fwrite(JpegBuffer, sizeof(char), (int)jcu_encode_size, fp); |
1050186 | 3:2c8f1cf3333b | 125 | fclose(fp); |
1050186 | 3:2c8f1cf3333b | 126 | } |
1050186 | 3:2c8f1cf3333b | 127 | printf("Saved file %s\r\n", file_name); |
dkato | 0:2f1caf4ce924 | 128 | } |
1050186 | 3:2c8f1cf3333b | 129 | } |
dkato | 0:2f1caf4ce924 | 130 | |
1050186 | 3:2c8f1cf3333b | 131 | int main() { |
1050186 | 3:2c8f1cf3333b | 132 | EasyAttach_Init(Display); |
1050186 | 3:2c8f1cf3333b | 133 | Start_Video_Camera(); |
1050186 | 3:2c8f1cf3333b | 134 | #if MBED_CONF_APP_LCD |
1050186 | 3:2c8f1cf3333b | 135 | Start_LCD_Display(); |
dkato | 0:2f1caf4ce924 | 136 | #endif |
1050186 | 3:2c8f1cf3333b | 137 | SdUsbConnect storage(MOUNT_NAME); |
dkato | 0:2f1caf4ce924 | 138 | |
dkato | 0:2f1caf4ce924 | 139 | while (1) { |
1050186 | 3:2c8f1cf3333b | 140 | storage.wait_connect(); |
1050186 | 3:2c8f1cf3333b | 141 | if (button0 == 0) { |
1050186 | 3:2c8f1cf3333b | 142 | wait_new_image(); // wait for image input |
dkato | 0:2f1caf4ce924 | 143 | led1 = 1; |
1050186 | 3:2c8f1cf3333b | 144 | save_image_jpg(); // save as jpeg |
dkato | 0:2f1caf4ce924 | 145 | led1 = 0; |
dkato | 0:2f1caf4ce924 | 146 | } |
dkato | 0:2f1caf4ce924 | 147 | } |
dkato | 0:2f1caf4ce924 | 148 | } |
1050186 | 3:2c8f1cf3333b | 149 | |
1050186 | 3:2c8f1cf3333b | 150 | #else |
1050186 | 3:2c8f1cf3333b | 151 | |
1050186 | 3:2c8f1cf3333b | 152 | #define MAX_FRAME_NUM 1024 |
1050186 | 3:2c8f1cf3333b | 153 | #define VIDEO_BUFF_SIZE (VIDEO_PIXEL_HW * VIDEO_PIXEL_VW * 2) |
1050186 | 3:2c8f1cf3333b | 154 | |
1050186 | 3:2c8f1cf3333b | 155 | static uint32_t mjpg_index[MAX_FRAME_NUM]; |
1050186 | 3:2c8f1cf3333b | 156 | static uint32_t mjpg_size[MAX_FRAME_NUM]; |
1050186 | 3:2c8f1cf3333b | 157 | static uint8_t work_buf[256]; |
1050186 | 3:2c8f1cf3333b | 158 | |
1050186 | 3:2c8f1cf3333b | 159 | static const uint8_t MJpegHeader[224] = { |
1050186 | 3:2c8f1cf3333b | 160 | 0x52, 0x49, 0x46, 0x46, // "RIFF" |
1050186 | 3:2c8f1cf3333b | 161 | 0xF0, 0xFF, 0xFF, 0x7F, // [Temporary] Total data size (File size - 8) |
1050186 | 3:2c8f1cf3333b | 162 | 0x41, 0x56, 0x49, 0x20, // "AVI " |
1050186 | 3:2c8f1cf3333b | 163 | 0x4C, 0x49, 0x53, 0x54, // "LIST" |
1050186 | 3:2c8f1cf3333b | 164 | 0xC0, 0x00, 0x00, 0x00, // Size of the list |
1050186 | 3:2c8f1cf3333b | 165 | 0x68, 0x64, 0x72, 0x6C, // "hdrl" |
1050186 | 3:2c8f1cf3333b | 166 | 0x61, 0x76, 0x69, 0x68, // "avih" |
1050186 | 3:2c8f1cf3333b | 167 | 0x38, 0x00, 0x00, 0x00, // avih chunk size |
1050186 | 3:2c8f1cf3333b | 168 | 0x35, 0x82, 0x00, 0x00, // [Temporary] Frame interval (microseconds) |
1050186 | 3:2c8f1cf3333b | 169 | 0x00, 0xCC, 0x00, 0x00, // Approximate maximum data rate |
1050186 | 3:2c8f1cf3333b | 170 | 0x00, 0x00, 0x00, 0x00, // Padding unit |
1050186 | 3:2c8f1cf3333b | 171 | 0x10, 0x00, 0x00, 0x00, // With index information |
1050186 | 3:2c8f1cf3333b | 172 | 0x00, 0x48, 0x00, 0x00, // [Temporary] Total number of frames |
1050186 | 3:2c8f1cf3333b | 173 | 0x00, 0x00, 0x00, 0x00, // dummy |
1050186 | 3:2c8f1cf3333b | 174 | 0x01, 0x00, 0x00, 0x00, // Number of streams |
1050186 | 3:2c8f1cf3333b | 175 | 0x00, 0x00, 0x10, 0x00, // Required buffer size (estimate) |
1050186 | 3:2c8f1cf3333b | 176 | ((VIDEO_PIXEL_HW >> 0) & 0xFF), ((VIDEO_PIXEL_HW >> 8) & 0xFF), ((VIDEO_PIXEL_HW >> 16) & 0xFF), ((VIDEO_PIXEL_HW >> 24) & 0xFF), // width |
1050186 | 3:2c8f1cf3333b | 177 | ((VIDEO_PIXEL_VW >> 0) & 0xFF), ((VIDEO_PIXEL_VW >> 8) & 0xFF), ((VIDEO_PIXEL_VW >> 16) & 0xFF), ((VIDEO_PIXEL_VW >> 24) & 0xFF), // height |
1050186 | 3:2c8f1cf3333b | 178 | 0x00, 0x00, 0x00, 0x00, // not use |
1050186 | 3:2c8f1cf3333b | 179 | 0x00, 0x00, 0x00, 0x00, // not use |
1050186 | 3:2c8f1cf3333b | 180 | 0x00, 0x00, 0x00, 0x00, // not use |
1050186 | 3:2c8f1cf3333b | 181 | 0x00, 0x00, 0x00, 0x00, // not use |
1050186 | 3:2c8f1cf3333b | 182 | 0x4C, 0x49, 0x53, 0x54, // "LIST" |
1050186 | 3:2c8f1cf3333b | 183 | 0x74, 0x00, 0x00, 0x00, // Size of the list |
1050186 | 3:2c8f1cf3333b | 184 | 0x73, 0x74, 0x72, 0x6C, // "strl" |
1050186 | 3:2c8f1cf3333b | 185 | 0x73, 0x74, 0x72, 0x68, // "strh" |
1050186 | 3:2c8f1cf3333b | 186 | 0x38, 0x00, 0x00, 0x00, // strl chunk size |
1050186 | 3:2c8f1cf3333b | 187 | 0x76, 0x69, 0x64, 0x73, // "vids" |
1050186 | 3:2c8f1cf3333b | 188 | 0x4D, 0x4A, 0x50, 0x47, // "MJPG" |
1050186 | 3:2c8f1cf3333b | 189 | 0x00, 0x00, 0x00, 0x00, // Stream handling is normal |
1050186 | 3:2c8f1cf3333b | 190 | 0x00, 0x00, 0x00, 0x00, // Stream priority 0, no language setting |
1050186 | 3:2c8f1cf3333b | 191 | 0x00, 0x00, 0x00, 0x00, // Audio first frame: None |
1050186 | 3:2c8f1cf3333b | 192 | 0x01, 0x00, 0x00, 0x00, // Number of frames per second (denominator) |
1050186 | 3:2c8f1cf3333b | 193 | 0x1E, 0x00, 0x00, 0x00, // [Temporary] Number of frames per second (numerator) |
1050186 | 3:2c8f1cf3333b | 194 | 0x00, 0x00, 0x00, 0x00, // Stream start size |
1050186 | 3:2c8f1cf3333b | 195 | 0x00, 0x48, 0x00, 0x00, // [Temporary] Stream length |
1050186 | 3:2c8f1cf3333b | 196 | 0x00, 0x00, 0x00, 0x00, // Buffer size: unknown |
1050186 | 3:2c8f1cf3333b | 197 | 0xFF, 0xFF, 0xFF, 0xFF, // Default quality |
1050186 | 3:2c8f1cf3333b | 198 | 0x00, 0x00, 0x00, 0x00, // Size per sample (change) |
1050186 | 3:2c8f1cf3333b | 199 | 0x00, 0x00, 0x00, 0x00, // Display coordinates (x, y in upper left) |
1050186 | 3:2c8f1cf3333b | 200 | ((VIDEO_PIXEL_HW)& 0xFF), ((VIDEO_PIXEL_HW >> 8) & 0xFF), ((VIDEO_PIXEL_VW)& 0xFF), ((VIDEO_PIXEL_VW >> 8) & 0xFF), //[Temporary] Display coordinates (x, y in lower right) |
1050186 | 3:2c8f1cf3333b | 201 | 0x73, 0x74, 0x72, 0x66, // "strf" |
1050186 | 3:2c8f1cf3333b | 202 | 0x28, 0x00, 0x00, 0x00, // strf chunk size |
1050186 | 3:2c8f1cf3333b | 203 | 0x28, 0x00, 0x00, 0x00, // Chunk body size |
1050186 | 3:2c8f1cf3333b | 204 | ((VIDEO_PIXEL_HW >> 0) & 0xFF), ((VIDEO_PIXEL_HW >> 8) & 0xFF), ((VIDEO_PIXEL_HW >> 16) & 0xFF), ((VIDEO_PIXEL_HW >> 24) & 0xFF), // width |
1050186 | 3:2c8f1cf3333b | 205 | ((VIDEO_PIXEL_VW >> 0) & 0xFF), ((VIDEO_PIXEL_VW >> 8) & 0xFF), ((VIDEO_PIXEL_VW >> 16) & 0xFF), ((VIDEO_PIXEL_VW >> 24) & 0xFF), // height |
1050186 | 3:2c8f1cf3333b | 206 | 0x01, 0x00, 0x10, 0x00, // Number of faces and bpp |
1050186 | 3:2c8f1cf3333b | 207 | 0x4D, 0x4A, 0x50, 0x47, // "MJPG" |
1050186 | 3:2c8f1cf3333b | 208 | ((VIDEO_BUFF_SIZE >> 0) & 0xFF), ((VIDEO_BUFF_SIZE >> 8) & 0xFF), ((VIDEO_BUFF_SIZE >> 16) & 0xFF), ((VIDEO_BUFF_SIZE >> 24) & 0xFF), // Buffer size (width x height x 2) |
1050186 | 3:2c8f1cf3333b | 209 | 0x00, 0x00, 0x00, 0x00, // Horizontal resolution |
1050186 | 3:2c8f1cf3333b | 210 | 0x00, 0x00, 0x00, 0x00, // Vertical resolution |
1050186 | 3:2c8f1cf3333b | 211 | 0x00, 0x00, 0x00, 0x00, // Number of color index |
1050186 | 3:2c8f1cf3333b | 212 | 0x00, 0x00, 0x00, 0x00, // Important color index number |
1050186 | 3:2c8f1cf3333b | 213 | 0x4C, 0x49, 0x53, 0x54, // "LIST" |
1050186 | 3:2c8f1cf3333b | 214 | 0xF0, 0xFF, 0xFF, 0x7F, // [Temporary] List size (index address - 0xDC) |
1050186 | 3:2c8f1cf3333b | 215 | 0x6D, 0x6F, 0x76, 0x69 // "movi" |
1050186 | 3:2c8f1cf3333b | 216 | }; |
1050186 | 3:2c8f1cf3333b | 217 | |
1050186 | 3:2c8f1cf3333b | 218 | static void set_data(uint8_t * buf, uint32_t data) { |
1050186 | 3:2c8f1cf3333b | 219 | if (buf != NULL) { |
1050186 | 3:2c8f1cf3333b | 220 | buf[0] = ((data >> 0) & 0xFF); |
1050186 | 3:2c8f1cf3333b | 221 | buf[1] = ((data >> 8) & 0xFF); |
1050186 | 3:2c8f1cf3333b | 222 | buf[2] = ((data >> 16) & 0xFF); |
1050186 | 3:2c8f1cf3333b | 223 | buf[3] = ((data >> 24) & 0xFF); |
1050186 | 3:2c8f1cf3333b | 224 | } |
1050186 | 3:2c8f1cf3333b | 225 | } |
1050186 | 3:2c8f1cf3333b | 226 | |
1050186 | 3:2c8f1cf3333b | 227 | int main() { |
1050186 | 3:2c8f1cf3333b | 228 | EasyAttach_Init(Display); |
1050186 | 3:2c8f1cf3333b | 229 | Start_Video_Camera(); |
1050186 | 3:2c8f1cf3333b | 230 | #if MBED_CONF_APP_LCD |
1050186 | 3:2c8f1cf3333b | 231 | Start_LCD_Display(); |
1050186 | 3:2c8f1cf3333b | 232 | #endif |
1050186 | 3:2c8f1cf3333b | 233 | SdUsbConnect storage(MOUNT_NAME); |
1050186 | 3:2c8f1cf3333b | 234 | FILE * fp; |
1050186 | 3:2c8f1cf3333b | 235 | char file_name[32]; |
1050186 | 3:2c8f1cf3333b | 236 | int mjpg_pointer = 0; |
1050186 | 3:2c8f1cf3333b | 237 | int mjpg_frame = 0; |
1050186 | 3:2c8f1cf3333b | 238 | uint32_t fps; |
1050186 | 3:2c8f1cf3333b | 239 | Timer t; |
1050186 | 3:2c8f1cf3333b | 240 | |
1050186 | 3:2c8f1cf3333b | 241 | while (1) { |
1050186 | 3:2c8f1cf3333b | 242 | storage.wait_connect(); |
1050186 | 3:2c8f1cf3333b | 243 | |
1050186 | 3:2c8f1cf3333b | 244 | if (led1 == 0) { |
1050186 | 3:2c8f1cf3333b | 245 | if (button0 == 0) { |
1050186 | 3:2c8f1cf3333b | 246 | led1 = 1; |
1050186 | 3:2c8f1cf3333b | 247 | sprintf(file_name, "/"MOUNT_NAME"/movie_%d.avi", file_name_index++); |
1050186 | 3:2c8f1cf3333b | 248 | fp = fopen(file_name, "w"); |
1050186 | 3:2c8f1cf3333b | 249 | if (fp != NULL) { |
1050186 | 3:2c8f1cf3333b | 250 | setvbuf(fp, NULL, _IONBF, 0); // unbuffered |
1050186 | 3:2c8f1cf3333b | 251 | mjpg_frame = 0; |
1050186 | 3:2c8f1cf3333b | 252 | mjpg_pointer = sizeof(MJpegHeader); |
1050186 | 3:2c8f1cf3333b | 253 | fseek(fp, mjpg_pointer, SEEK_SET); |
1050186 | 3:2c8f1cf3333b | 254 | t.reset(); |
1050186 | 3:2c8f1cf3333b | 255 | t.start(); |
1050186 | 3:2c8f1cf3333b | 256 | } else { |
1050186 | 3:2c8f1cf3333b | 257 | led1 = 0; |
1050186 | 3:2c8f1cf3333b | 258 | } |
1050186 | 3:2c8f1cf3333b | 259 | } |
1050186 | 3:2c8f1cf3333b | 260 | } |
1050186 | 3:2c8f1cf3333b | 261 | if (led1 == 1) { |
1050186 | 3:2c8f1cf3333b | 262 | if ((button0 == 0) && (mjpg_frame < MAX_FRAME_NUM)) { |
1050186 | 3:2c8f1cf3333b | 263 | size_t jcu_encode_size = 0; |
1050186 | 3:2c8f1cf3333b | 264 | JPEG_Converter::bitmap_buff_info_t bitmap_buff_info; |
1050186 | 3:2c8f1cf3333b | 265 | JPEG_Converter::encode_options_t encode_options; |
1050186 | 3:2c8f1cf3333b | 266 | |
1050186 | 3:2c8f1cf3333b | 267 | wait_new_image(); // wait for image input |
1050186 | 3:2c8f1cf3333b | 268 | |
1050186 | 3:2c8f1cf3333b | 269 | bitmap_buff_info.width = VIDEO_PIXEL_HW; |
1050186 | 3:2c8f1cf3333b | 270 | bitmap_buff_info.height = VIDEO_PIXEL_VW; |
1050186 | 3:2c8f1cf3333b | 271 | bitmap_buff_info.format = JPEG_Converter::WR_RD_YCbCr422; |
1050186 | 3:2c8f1cf3333b | 272 | bitmap_buff_info.buffer_address = (void *)user_frame_buffer0; |
1050186 | 3:2c8f1cf3333b | 273 | |
1050186 | 3:2c8f1cf3333b | 274 | encode_options.encode_buff_size = sizeof(JpegBuffer); |
1050186 | 3:2c8f1cf3333b | 275 | encode_options.p_EncodeCallBackFunc = NULL; |
1050186 | 3:2c8f1cf3333b | 276 | encode_options.input_swapsetting = JPEG_Converter::WR_RD_WRSWA_32_16_8BIT; |
1050186 | 3:2c8f1cf3333b | 277 | |
1050186 | 3:2c8f1cf3333b | 278 | dcache_invalid(JpegBuffer, sizeof(JpegBuffer)); |
1050186 | 3:2c8f1cf3333b | 279 | if (Jcu.encode(&bitmap_buff_info, JpegBuffer, &jcu_encode_size, &encode_options) == JPEG_Converter::JPEG_CONV_OK) { |
1050186 | 3:2c8f1cf3333b | 280 | if ((jcu_encode_size & 0x1) != 0) { |
1050186 | 3:2c8f1cf3333b | 281 | JpegBuffer[jcu_encode_size] = 0; |
1050186 | 3:2c8f1cf3333b | 282 | jcu_encode_size++; |
1050186 | 3:2c8f1cf3333b | 283 | } |
1050186 | 3:2c8f1cf3333b | 284 | memcpy(&work_buf[0], "00dc", 4); |
1050186 | 3:2c8f1cf3333b | 285 | set_data(&work_buf[4], jcu_encode_size); |
1050186 | 3:2c8f1cf3333b | 286 | fwrite(work_buf, sizeof(char), (int)8, fp); |
1050186 | 3:2c8f1cf3333b | 287 | fwrite(JpegBuffer, sizeof(char), (int)jcu_encode_size, fp); |
1050186 | 3:2c8f1cf3333b | 288 | mjpg_index[mjpg_frame] = mjpg_pointer + 4 - sizeof(MJpegHeader); |
1050186 | 3:2c8f1cf3333b | 289 | mjpg_size[mjpg_frame] = jcu_encode_size; |
1050186 | 3:2c8f1cf3333b | 290 | mjpg_frame++; |
1050186 | 3:2c8f1cf3333b | 291 | mjpg_pointer += (jcu_encode_size + 8); |
1050186 | 3:2c8f1cf3333b | 292 | } |
1050186 | 3:2c8f1cf3333b | 293 | } else { |
1050186 | 3:2c8f1cf3333b | 294 | t.stop(); |
1050186 | 3:2c8f1cf3333b | 295 | fps = mjpg_frame * 1000 / t.read_ms(); |
1050186 | 3:2c8f1cf3333b | 296 | |
1050186 | 3:2c8f1cf3333b | 297 | memcpy(work_buf, MJpegHeader, sizeof(MJpegHeader)); |
1050186 | 3:2c8f1cf3333b | 298 | set_data(&work_buf[4], mjpg_pointer + 16 + (mjpg_frame * 8) - 8); |
1050186 | 3:2c8f1cf3333b | 299 | set_data(&work_buf[32], 1000000.0 / fps); |
1050186 | 3:2c8f1cf3333b | 300 | set_data(&work_buf[48], mjpg_frame); |
1050186 | 3:2c8f1cf3333b | 301 | set_data(&work_buf[132], fps); |
1050186 | 3:2c8f1cf3333b | 302 | set_data(&work_buf[140], mjpg_frame); |
1050186 | 3:2c8f1cf3333b | 303 | if (mjpg_pointer > 0xDC){ |
1050186 | 3:2c8f1cf3333b | 304 | set_data(&work_buf[216], mjpg_pointer - 0xDC); |
1050186 | 3:2c8f1cf3333b | 305 | } else { |
1050186 | 3:2c8f1cf3333b | 306 | set_data(&work_buf[216],0); |
1050186 | 3:2c8f1cf3333b | 307 | } |
1050186 | 3:2c8f1cf3333b | 308 | fseek(fp, 0, SEEK_SET); |
1050186 | 3:2c8f1cf3333b | 309 | fwrite(work_buf, sizeof(char), sizeof(MJpegHeader), fp); |
1050186 | 3:2c8f1cf3333b | 310 | |
1050186 | 3:2c8f1cf3333b | 311 | memcpy(&work_buf[0], "idx1", 4); |
1050186 | 3:2c8f1cf3333b | 312 | set_data(&work_buf[4], mjpg_frame * 16); |
1050186 | 3:2c8f1cf3333b | 313 | fseek(fp, mjpg_pointer, SEEK_SET); |
1050186 | 3:2c8f1cf3333b | 314 | fwrite(work_buf, sizeof(char), 8, fp); |
1050186 | 3:2c8f1cf3333b | 315 | |
1050186 | 3:2c8f1cf3333b | 316 | for (int i = 0; i < mjpg_frame; i++){ |
1050186 | 3:2c8f1cf3333b | 317 | memcpy(&work_buf[0], "00dc", 4); |
1050186 | 3:2c8f1cf3333b | 318 | set_data(&work_buf[4], 16); |
1050186 | 3:2c8f1cf3333b | 319 | set_data(&work_buf[8], mjpg_index[i]); |
1050186 | 3:2c8f1cf3333b | 320 | set_data(&work_buf[12], mjpg_size[i]); |
1050186 | 3:2c8f1cf3333b | 321 | fwrite(work_buf, sizeof(char), 16, fp); |
1050186 | 3:2c8f1cf3333b | 322 | } |
1050186 | 3:2c8f1cf3333b | 323 | |
1050186 | 3:2c8f1cf3333b | 324 | fclose(fp); |
1050186 | 3:2c8f1cf3333b | 325 | printf("Saved file %s , %dfps\r\n", file_name, fps); |
1050186 | 3:2c8f1cf3333b | 326 | led1 = 0; |
1050186 | 3:2c8f1cf3333b | 327 | } |
1050186 | 3:2c8f1cf3333b | 328 | } |
1050186 | 3:2c8f1cf3333b | 329 | } |
1050186 | 3:2c8f1cf3333b | 330 | } |
1050186 | 3:2c8f1cf3333b | 331 | #endif |