Study

Dependencies:   DisplayApp mbed-os-lychee

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 #include "mbed.h"
00002 #include "EasyAttach_CameraAndLCD.h"
00003 #include "JPEG_Converter.h"
00004 #include "dcache-control.h"
00005 #include "DisplayApp.h"
00006 
00007 /**** User Selection *********/
00008 /** JPEG out setting **/
00009 #define JPEG_ENCODE_QUALITY    (75)    /* JPEG encode quality (min:1, max:75 (Considering the size of JpegBuffer, about 75 is the upper limit.)) */
00010 #define VFIELD_INT_SKIP_CNT    (0)     /* A guide for GR-LYCHEE.  0:60fps, 1:30fps, 2:20fps, 3:15fps, 4:12fps, 5:10fps */
00011 /*****************************/
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 DisplayBase Display;
00022 
00023 #if defined(__ICCARM__)
00024 #pragma data_alignment=32
00025 static uint8_t user_frame_buffer0[FRAME_BUFFER_STRIDE * FRAME_BUFFER_HEIGHT]@ ".mirrorram";
00026 #pragma data_alignment=32
00027 static uint8_t JpegBuffer[2][1024 * 64];
00028 static uint8_t JpegBuffer_Send[1024 * 64];
00029 #else
00030 static uint8_t user_frame_buffer0[FRAME_BUFFER_STRIDE * FRAME_BUFFER_HEIGHT]__attribute((section("NC_BSS"),aligned(32)));
00031 static uint8_t JpegBuffer[2][1024 * 64]__attribute((aligned(32)));
00032 static uint8_t JpegBuffer_Send[1024 * 64]__attribute((aligned(32)));
00033 #endif
00034 static size_t jcu_encode_size[2];
00035 static JPEG_Converter Jcu;
00036 static int jcu_buf_index_write = 0;
00037 static int jcu_buf_index_write_done = 0;
00038 static int jcu_buf_index_read = 0;
00039 static volatile int jcu_encoding = 0;
00040 static volatile int image_change = 0;
00041 static DisplayApp  display_app;
00042 static int Vfield_Int_Cnt = 0;
00043 
00044 static void JcuEncodeCallBackFunc(JPEG_Converter::jpeg_conv_error_t err_code) {
00045     if (err_code == JPEG_Converter::JPEG_CONV_OK) {
00046         jcu_buf_index_write_done = jcu_buf_index_write;
00047         image_change = 1;
00048     }
00049     jcu_encoding = 0;
00050 }
00051 
00052 static void snapshot(void) {
00053     //JPEGにエンコード中 or エンコード未完了
00054     while ((jcu_encoding == 1) || (image_change == 0)) {
00055         Thread::wait(1);
00056     }
00057     jcu_buf_index_read = jcu_buf_index_write_done;
00058     //画像データをコピー(JpegBufferは他から書き換えられる可能性があるため)
00059     memcpy(JpegBuffer_Send, JpegBuffer[jcu_buf_index_read],1024 * 64);
00060     image_change = 0;
00061 
00062     //撮影した画像データ(JPEG)をPCにUSBシリアル通信で転送
00063     display_app.SendJpeg(JpegBuffer_Send, (uint32_t)jcu_encode_size[jcu_buf_index_read]);
00064 }
00065 
00066 static void IntCallbackFunc_Vfield(DisplayBase::int_type_t int_type) {
00067     if (Vfield_Int_Cnt < VFIELD_INT_SKIP_CNT) {
00068         Vfield_Int_Cnt++;
00069         return;
00070     }
00071     Vfield_Int_Cnt = 0;
00072 
00073     //Interrupt callback function
00074     if (jcu_encoding == 0) {
00075         JPEG_Converter::bitmap_buff_info_t bitmap_buff_info;
00076         JPEG_Converter::encode_options_t   encode_options;
00077 
00078         bitmap_buff_info.width              = VIDEO_PIXEL_HW;
00079         bitmap_buff_info.height             = VIDEO_PIXEL_VW;
00080         bitmap_buff_info.format             = JPEG_Converter::WR_RD_YCbCr422;
00081         bitmap_buff_info.buffer_address     = (void *)user_frame_buffer0;
00082 
00083         encode_options.encode_buff_size     = sizeof(JpegBuffer[0]);
00084         encode_options.p_EncodeCallBackFunc = &JcuEncodeCallBackFunc;
00085         encode_options.input_swapsetting    = JPEG_Converter::WR_RD_WRSWA_32_16_8BIT;
00086 
00087         jcu_encoding = 1;
00088         if (jcu_buf_index_read == jcu_buf_index_write) {
00089             jcu_buf_index_write ^= 1;  // toggle
00090         }
00091         jcu_encode_size[jcu_buf_index_write] = 0;
00092         dcache_invalid(JpegBuffer[jcu_buf_index_write], sizeof(JpegBuffer[0]));
00093         if (Jcu.encode(&bitmap_buff_info, JpegBuffer[jcu_buf_index_write],
00094             &jcu_encode_size[jcu_buf_index_write], &encode_options) != JPEG_Converter::JPEG_CONV_OK) {
00095             jcu_encode_size[jcu_buf_index_write] = 0;
00096             jcu_encoding = 0;
00097         }
00098     }
00099 }
00100 
00101 static void Start_Video_Camera(void) {
00102     // Initialize the background to black
00103     for (uint32_t i = 0; i < sizeof(user_frame_buffer0); i += 2) {
00104         user_frame_buffer0[i + 0] = 0x10;
00105         user_frame_buffer0[i + 1] = 0x80;
00106     }
00107 
00108     // Interrupt callback function setting (Field end signal for recording function in scaler 0)
00109     Display.Graphics_Irq_Handler_Set(DisplayBase::INT_TYPE_S0_VFIELD, 0, IntCallbackFunc_Vfield);
00110 
00111     // Video capture setting (progressive form fixed)
00112     Display.Video_Write_Setting(
00113         DisplayBase::VIDEO_INPUT_CHANNEL_0,
00114         DisplayBase::COL_SYS_NTSC_358,
00115         (void *)user_frame_buffer0,
00116         FRAME_BUFFER_STRIDE,
00117         DisplayBase::VIDEO_FORMAT_YCBCR422,
00118         DisplayBase::WR_RD_WRSWA_32_16BIT,
00119         VIDEO_PIXEL_VW,
00120         VIDEO_PIXEL_HW
00121     );
00122     EasyAttach_CameraStart(Display, DisplayBase::VIDEO_INPUT_CHANNEL_0);
00123 }
00124 
00125 int main(void) {
00126     Jcu.SetQuality(JPEG_ENCODE_QUALITY);
00127 
00128     EasyAttach_Init(Display);
00129     Start_Video_Camera();
00130 
00131     while (1) {
00132         snapshot();
00133     }
00134 }