Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
main.cpp
00001 #include "mbed.h" 00002 #include "EasyAttach_CameraAndLCD.h" 00003 #include "SdUsbConnect.h" 00004 #include "JPEG_Converter.h" 00005 #include "dcache-control.h" 00006 00007 /**** User Selection *********/ 00008 #define SAVE_FILE_TYPE (0) /* Select 0(Image(.jpg)) or 1(Movie(.avi)) */ 00009 /*****************************/ 00010 00011 #define MOUNT_NAME "storage" 00012 00013 /*! Frame buffer stride: Frame buffer stride should be set to a multiple of 32 or 128 00014 in accordance with the frame buffer burst transfer mode. */ 00015 #define VIDEO_PIXEL_HW (640u) /* VGA */ 00016 #define VIDEO_PIXEL_VW (480u) /* VGA */ 00017 00018 #define FRAME_BUFFER_STRIDE (((VIDEO_PIXEL_HW * 2) + 31u) & ~31u) 00019 #define FRAME_BUFFER_HEIGHT (VIDEO_PIXEL_VW) 00020 00021 #if defined(__ICCARM__) 00022 #pragma data_alignment=32 00023 static uint8_t user_frame_buffer0[FRAME_BUFFER_STRIDE * FRAME_BUFFER_HEIGHT]@ ".mirrorram"; 00024 #else 00025 static uint8_t user_frame_buffer0[FRAME_BUFFER_STRIDE * FRAME_BUFFER_HEIGHT]__attribute((section("NC_BSS"),aligned(32))); 00026 #endif 00027 static int file_name_index = 1; 00028 static volatile int Vfield_Int_Cnt = 0; 00029 /* jpeg convert */ 00030 static JPEG_Converter Jcu; 00031 #if defined(__ICCARM__) 00032 #pragma data_alignment=32 00033 static uint8_t JpegBuffer[1024 * 63]; 00034 #else 00035 static uint8_t JpegBuffer[1024 * 63]__attribute((aligned(32))); 00036 #endif 00037 00038 DisplayBase Display; 00039 DigitalIn button0(USER_BUTTON0); 00040 DigitalOut led1(LED1); 00041 00042 static void IntCallbackFunc_Vfield(DisplayBase::int_type_t int_type) { 00043 if (Vfield_Int_Cnt > 0) { 00044 Vfield_Int_Cnt--; 00045 } 00046 } 00047 00048 static void wait_new_image(void) { 00049 Vfield_Int_Cnt = 1; 00050 while (Vfield_Int_Cnt > 0) { 00051 ThisThread::sleep_for(1); 00052 } 00053 } 00054 00055 static void Start_Video_Camera(void) { 00056 // Initialize the background to black 00057 for (uint32_t i = 0; i < sizeof(user_frame_buffer0); i += 2) { 00058 user_frame_buffer0[i + 0] = 0x10; 00059 user_frame_buffer0[i + 1] = 0x80; 00060 } 00061 00062 // Field end signal for recording function in scaler 0 00063 Display.Graphics_Irq_Handler_Set(DisplayBase::INT_TYPE_S0_VFIELD, 0, IntCallbackFunc_Vfield); 00064 00065 // Video capture setting (progressive form fixed) 00066 Display.Video_Write_Setting( 00067 DisplayBase::VIDEO_INPUT_CHANNEL_0, 00068 DisplayBase::COL_SYS_NTSC_358, 00069 (void *)user_frame_buffer0, 00070 FRAME_BUFFER_STRIDE, 00071 DisplayBase::VIDEO_FORMAT_YCBCR422, 00072 DisplayBase::WR_RD_WRSWA_32_16BIT, 00073 VIDEO_PIXEL_VW, 00074 VIDEO_PIXEL_HW 00075 ); 00076 EasyAttach_CameraStart(Display, DisplayBase::VIDEO_INPUT_CHANNEL_0); 00077 } 00078 00079 #if MBED_CONF_APP_LCD 00080 static void Start_LCD_Display(void) { 00081 DisplayBase::rect_t rect; 00082 00083 rect.vs = 0; 00084 rect.vw = VIDEO_PIXEL_VW; 00085 rect.hs = 0; 00086 rect.hw = VIDEO_PIXEL_HW; 00087 Display.Graphics_Read_Setting( 00088 DisplayBase::GRAPHICS_LAYER_0, 00089 (void *)user_frame_buffer0, 00090 FRAME_BUFFER_STRIDE, 00091 DisplayBase::GRAPHICS_FORMAT_YCBCR422, 00092 DisplayBase::WR_RD_WRSWA_32_16BIT, 00093 &rect 00094 ); 00095 Display.Graphics_Start(DisplayBase::GRAPHICS_LAYER_0); 00096 00097 ThisThread::sleep_for(50); 00098 EasyAttach_LcdBacklight(true); 00099 } 00100 #endif 00101 00102 #if (SAVE_FILE_TYPE == 0) 00103 static void save_image_jpg(void) { 00104 size_t jcu_encode_size = 0; 00105 JPEG_Converter::bitmap_buff_info_t bitmap_buff_info; 00106 JPEG_Converter::encode_options_t encode_options; 00107 00108 bitmap_buff_info.width = VIDEO_PIXEL_HW; 00109 bitmap_buff_info.height = VIDEO_PIXEL_VW; 00110 bitmap_buff_info.format = JPEG_Converter::WR_RD_YCbCr422; 00111 bitmap_buff_info.buffer_address = (void *)user_frame_buffer0; 00112 00113 encode_options.encode_buff_size = sizeof(JpegBuffer); 00114 encode_options.p_EncodeCallBackFunc = NULL; 00115 encode_options.input_swapsetting = JPEG_Converter::WR_RD_WRSWA_32_16_8BIT; 00116 00117 dcache_invalid(JpegBuffer, sizeof(JpegBuffer)); 00118 if (Jcu.encode(&bitmap_buff_info, JpegBuffer, &jcu_encode_size, &encode_options) == JPEG_Converter::JPEG_CONV_OK) { 00119 char file_name[32]; 00120 sprintf(file_name, "/"MOUNT_NAME"/img_%d.jpg", file_name_index++); 00121 FILE * fp = fopen(file_name, "w"); 00122 if (fp != NULL) { 00123 setvbuf(fp, NULL, _IONBF, 0); // unbuffered 00124 fwrite(JpegBuffer, sizeof(char), (int)jcu_encode_size, fp); 00125 fclose(fp); 00126 } 00127 printf("Saved file %s\r\n", file_name); 00128 } 00129 } 00130 00131 int main() { 00132 EasyAttach_Init(Display); 00133 Start_Video_Camera(); 00134 #if MBED_CONF_APP_LCD 00135 Start_LCD_Display(); 00136 #endif 00137 SdUsbConnect storage(MOUNT_NAME); 00138 00139 while (1) { 00140 storage.wait_connect(); 00141 if (button0 == 0) { 00142 wait_new_image(); // wait for image input 00143 led1 = 1; 00144 save_image_jpg(); // save as jpeg 00145 led1 = 0; 00146 } 00147 } 00148 } 00149 00150 #else 00151 00152 #define MAX_FRAME_NUM 1024 00153 #define VIDEO_BUFF_SIZE (VIDEO_PIXEL_HW * VIDEO_PIXEL_VW * 2) 00154 00155 static uint32_t mjpg_index[MAX_FRAME_NUM]; 00156 static uint32_t mjpg_size[MAX_FRAME_NUM]; 00157 static uint8_t work_buf[256]; 00158 00159 static const uint8_t MJpegHeader[224] = { 00160 0x52, 0x49, 0x46, 0x46, // "RIFF" 00161 0xF0, 0xFF, 0xFF, 0x7F, // [Temporary] Total data size (File size - 8) 00162 0x41, 0x56, 0x49, 0x20, // "AVI " 00163 0x4C, 0x49, 0x53, 0x54, // "LIST" 00164 0xC0, 0x00, 0x00, 0x00, // Size of the list 00165 0x68, 0x64, 0x72, 0x6C, // "hdrl" 00166 0x61, 0x76, 0x69, 0x68, // "avih" 00167 0x38, 0x00, 0x00, 0x00, // avih chunk size 00168 0x35, 0x82, 0x00, 0x00, // [Temporary] Frame interval (microseconds) 00169 0x00, 0xCC, 0x00, 0x00, // Approximate maximum data rate 00170 0x00, 0x00, 0x00, 0x00, // Padding unit 00171 0x10, 0x00, 0x00, 0x00, // With index information 00172 0x00, 0x48, 0x00, 0x00, // [Temporary] Total number of frames 00173 0x00, 0x00, 0x00, 0x00, // dummy 00174 0x01, 0x00, 0x00, 0x00, // Number of streams 00175 0x00, 0x00, 0x10, 0x00, // Required buffer size (estimate) 00176 ((VIDEO_PIXEL_HW >> 0) & 0xFF), ((VIDEO_PIXEL_HW >> 8) & 0xFF), ((VIDEO_PIXEL_HW >> 16) & 0xFF), ((VIDEO_PIXEL_HW >> 24) & 0xFF), // width 00177 ((VIDEO_PIXEL_VW >> 0) & 0xFF), ((VIDEO_PIXEL_VW >> 8) & 0xFF), ((VIDEO_PIXEL_VW >> 16) & 0xFF), ((VIDEO_PIXEL_VW >> 24) & 0xFF), // height 00178 0x00, 0x00, 0x00, 0x00, // not use 00179 0x00, 0x00, 0x00, 0x00, // not use 00180 0x00, 0x00, 0x00, 0x00, // not use 00181 0x00, 0x00, 0x00, 0x00, // not use 00182 0x4C, 0x49, 0x53, 0x54, // "LIST" 00183 0x74, 0x00, 0x00, 0x00, // Size of the list 00184 0x73, 0x74, 0x72, 0x6C, // "strl" 00185 0x73, 0x74, 0x72, 0x68, // "strh" 00186 0x38, 0x00, 0x00, 0x00, // strl chunk size 00187 0x76, 0x69, 0x64, 0x73, // "vids" 00188 0x4D, 0x4A, 0x50, 0x47, // "MJPG" 00189 0x00, 0x00, 0x00, 0x00, // Stream handling is normal 00190 0x00, 0x00, 0x00, 0x00, // Stream priority 0, no language setting 00191 0x00, 0x00, 0x00, 0x00, // Audio first frame: None 00192 0x01, 0x00, 0x00, 0x00, // Number of frames per second (denominator) 00193 0x1E, 0x00, 0x00, 0x00, // [Temporary] Number of frames per second (numerator) 00194 0x00, 0x00, 0x00, 0x00, // Stream start size 00195 0x00, 0x48, 0x00, 0x00, // [Temporary] Stream length 00196 0x00, 0x00, 0x00, 0x00, // Buffer size: unknown 00197 0xFF, 0xFF, 0xFF, 0xFF, // Default quality 00198 0x00, 0x00, 0x00, 0x00, // Size per sample (change) 00199 0x00, 0x00, 0x00, 0x00, // Display coordinates (x, y in upper left) 00200 ((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) 00201 0x73, 0x74, 0x72, 0x66, // "strf" 00202 0x28, 0x00, 0x00, 0x00, // strf chunk size 00203 0x28, 0x00, 0x00, 0x00, // Chunk body size 00204 ((VIDEO_PIXEL_HW >> 0) & 0xFF), ((VIDEO_PIXEL_HW >> 8) & 0xFF), ((VIDEO_PIXEL_HW >> 16) & 0xFF), ((VIDEO_PIXEL_HW >> 24) & 0xFF), // width 00205 ((VIDEO_PIXEL_VW >> 0) & 0xFF), ((VIDEO_PIXEL_VW >> 8) & 0xFF), ((VIDEO_PIXEL_VW >> 16) & 0xFF), ((VIDEO_PIXEL_VW >> 24) & 0xFF), // height 00206 0x01, 0x00, 0x10, 0x00, // Number of faces and bpp 00207 0x4D, 0x4A, 0x50, 0x47, // "MJPG" 00208 ((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) 00209 0x00, 0x00, 0x00, 0x00, // Horizontal resolution 00210 0x00, 0x00, 0x00, 0x00, // Vertical resolution 00211 0x00, 0x00, 0x00, 0x00, // Number of color index 00212 0x00, 0x00, 0x00, 0x00, // Important color index number 00213 0x4C, 0x49, 0x53, 0x54, // "LIST" 00214 0xF0, 0xFF, 0xFF, 0x7F, // [Temporary] List size (index address - 0xDC) 00215 0x6D, 0x6F, 0x76, 0x69 // "movi" 00216 }; 00217 00218 static void set_data(uint8_t * buf, uint32_t data) { 00219 if (buf != NULL) { 00220 buf[0] = ((data >> 0) & 0xFF); 00221 buf[1] = ((data >> 8) & 0xFF); 00222 buf[2] = ((data >> 16) & 0xFF); 00223 buf[3] = ((data >> 24) & 0xFF); 00224 } 00225 } 00226 00227 int main() { 00228 EasyAttach_Init(Display); 00229 Start_Video_Camera(); 00230 #if MBED_CONF_APP_LCD 00231 Start_LCD_Display(); 00232 #endif 00233 SdUsbConnect storage(MOUNT_NAME); 00234 FILE * fp; 00235 char file_name[32]; 00236 int mjpg_pointer = 0; 00237 int mjpg_frame = 0; 00238 uint32_t fps; 00239 Timer t; 00240 00241 while (1) { 00242 storage.wait_connect(); 00243 00244 if (led1 == 0) { 00245 if (button0 == 0) { 00246 led1 = 1; 00247 sprintf(file_name, "/"MOUNT_NAME"/movie_%d.avi", file_name_index++); 00248 fp = fopen(file_name, "w"); 00249 if (fp != NULL) { 00250 setvbuf(fp, NULL, _IONBF, 0); // unbuffered 00251 mjpg_frame = 0; 00252 mjpg_pointer = sizeof(MJpegHeader); 00253 fseek(fp, mjpg_pointer, SEEK_SET); 00254 t.reset(); 00255 t.start(); 00256 } else { 00257 led1 = 0; 00258 } 00259 } 00260 } 00261 if (led1 == 1) { 00262 if ((button0 == 0) && (mjpg_frame < MAX_FRAME_NUM)) { 00263 size_t jcu_encode_size = 0; 00264 JPEG_Converter::bitmap_buff_info_t bitmap_buff_info; 00265 JPEG_Converter::encode_options_t encode_options; 00266 00267 wait_new_image(); // wait for image input 00268 00269 bitmap_buff_info.width = VIDEO_PIXEL_HW; 00270 bitmap_buff_info.height = VIDEO_PIXEL_VW; 00271 bitmap_buff_info.format = JPEG_Converter::WR_RD_YCbCr422; 00272 bitmap_buff_info.buffer_address = (void *)user_frame_buffer0; 00273 00274 encode_options.encode_buff_size = sizeof(JpegBuffer); 00275 encode_options.p_EncodeCallBackFunc = NULL; 00276 encode_options.input_swapsetting = JPEG_Converter::WR_RD_WRSWA_32_16_8BIT; 00277 00278 dcache_invalid(JpegBuffer, sizeof(JpegBuffer)); 00279 if (Jcu.encode(&bitmap_buff_info, JpegBuffer, &jcu_encode_size, &encode_options) == JPEG_Converter::JPEG_CONV_OK) { 00280 if ((jcu_encode_size & 0x1) != 0) { 00281 JpegBuffer[jcu_encode_size] = 0; 00282 jcu_encode_size++; 00283 } 00284 memcpy(&work_buf[0], "00dc", 4); 00285 set_data(&work_buf[4], jcu_encode_size); 00286 fwrite(work_buf, sizeof(char), (int)8, fp); 00287 fwrite(JpegBuffer, sizeof(char), (int)jcu_encode_size, fp); 00288 mjpg_index[mjpg_frame] = mjpg_pointer + 4 - sizeof(MJpegHeader); 00289 mjpg_size[mjpg_frame] = jcu_encode_size; 00290 mjpg_frame++; 00291 mjpg_pointer += (jcu_encode_size + 8); 00292 } 00293 } else { 00294 t.stop(); 00295 fps = mjpg_frame * 1000 / t.read_ms(); 00296 00297 memcpy(work_buf, MJpegHeader, sizeof(MJpegHeader)); 00298 set_data(&work_buf[4], mjpg_pointer + 16 + (mjpg_frame * 8) - 8); 00299 set_data(&work_buf[32], 1000000.0 / fps); 00300 set_data(&work_buf[48], mjpg_frame); 00301 set_data(&work_buf[132], fps); 00302 set_data(&work_buf[140], mjpg_frame); 00303 if (mjpg_pointer > 0xDC){ 00304 set_data(&work_buf[216], mjpg_pointer - 0xDC); 00305 } else { 00306 set_data(&work_buf[216],0); 00307 } 00308 fseek(fp, 0, SEEK_SET); 00309 fwrite(work_buf, sizeof(char), sizeof(MJpegHeader), fp); 00310 00311 memcpy(&work_buf[0], "idx1", 4); 00312 set_data(&work_buf[4], mjpg_frame * 16); 00313 fseek(fp, mjpg_pointer, SEEK_SET); 00314 fwrite(work_buf, sizeof(char), 8, fp); 00315 00316 for (int i = 0; i < mjpg_frame; i++){ 00317 memcpy(&work_buf[0], "00dc", 4); 00318 set_data(&work_buf[4], 16); 00319 set_data(&work_buf[8], mjpg_index[i]); 00320 set_data(&work_buf[12], mjpg_size[i]); 00321 fwrite(work_buf, sizeof(char), 16, fp); 00322 } 00323 00324 fclose(fp); 00325 printf("Saved file %s , %dfps\r\n", file_name, fps); 00326 led1 = 0; 00327 } 00328 } 00329 } 00330 } 00331 #endif
Generated on Wed Jul 13 2022 23:03:09 by
1.7.2