michael kosinski / Mbed OS RGA-MJPEG_VideoDemo

Dependencies:   GR-PEACH_video GraphicsFramework LCD_shield_config R_BSP SDBlockDevice_GR_PEACH TLV320_RBSP USBHost_custom

Fork of RGA_HelloWorld by Renesas

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 /*
00002 Permission is hereby granted, free of charge, to any person obtaining a copy
00003 of this software and associated documentation files (the "Software"), to deal
00004 in the Software without restriction, including without limitation the rights
00005 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
00006 copies of the Software, and to permit persons to whom the Software is
00007 furnished to do so, subject to the following conditions:
00008  
00009 The above copyright notice and this permission notice shall be included in
00010 all copies or substantial portions of the Software.
00011  
00012 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00013 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00014 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
00015 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00016 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
00017 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
00018 THE SOFTWARE.
00019 */
00020 
00021 #include "mbed.h"
00022 #include "rga_func.h"
00023 #include "DisplayBace.h"
00024 #include "rtos.h"
00025 #include "TLV320_RBSP.h"
00026 #include "LCD_shield_config_7_1inch.h"
00027 #include "FATFileSystem.h"
00028 #include "SDBlockDevice_GR_PEACH.h"
00029 #include "USBHostMSD.h"
00030 #include "dec_wav.h"
00031 
00032 #define GRAPHICS_FORMAT                     (DisplayBase::GRAPHICS_FORMAT_RGB565)
00033 #define WR_RD_WRSWA                         (DisplayBase::WR_RD_WRSWA_32_16BIT)
00034 #define TOUCH_NUM                           (1u)
00035 
00036 /* FRAME BUFFER Parameter */
00037 #define FRAME_BUFFER_BYTE_PER_PIXEL         (2)
00038 #define FRAME_BUFFER_STRIDE                 (((LCD_PIXEL_WIDTH * FRAME_BUFFER_BYTE_PER_PIXEL) + 31u) & ~31u)
00039 
00040 #define DRAW_RECTANGLE_CNT_MAX              (4)
00041 
00042 #define FILE_NAME_LEN          (64)
00043 #define FLD_PATH               "/usb/"
00044 #define TEXT_SIZE              (64 + 1) //null-terminated
00045 
00046 #define MJPEG_DIV       2
00047 #define AUDIO_WRITE_BUFF_SIZE  (7056 * MJPEG_DIV)
00048 #define AUDIO_WRITE_BUFF_NUM   (9)
00049 
00050 // Testing
00051 DigitalOut TestPin0(D0); // Video File Read
00052 DigitalOut TestPin1(D1); // Audio File Read
00053 DigitalOut TestPin2(D6); // Update Display
00054 DigitalOut TestPin3(D7); // Sync
00055 
00056 typedef enum {
00057     RGA_FUNC_NON,
00058     RGA_FUNC_DRAW_RECTANGLE,
00059     RGA_FUNC_DRAW_IMAGE,
00060     RGA_FUNC_VIDEO_PLAYER,
00061     RGA_FUNC_VIDEO_PLAY,
00062     RGA_FUNC_VIDEO_STOP,
00063     RGA_FUNC_VIDEO_FWD,
00064     RGA_FUNC_VIDEO_REV,
00065     RGA_FUNC_DISSOLVE,
00066     RGA_FUNC_SCROLL,
00067     RGA_FUNC_ZOOM,
00068     RGA_FUNC_ROTATION,
00069     RGA_FUNC_ACCELERATE,
00070     RGA_FUNC_ANIME_EASE,
00071     RGA_FUNC_ANIME_LINEAR,
00072     RGA_FUNC_ANIME_EASE_IN,
00073     RGA_FUNC_ANIME_EASE_OUT,
00074     RGA_FUNC_ANIME_EASE_IN_OUT,
00075     RGA_FUNC_RETURN,
00076     RGA_FUNC_END
00077 } func_code_t;
00078 
00079 DigitalOut  lcd_pwon(P7_15);
00080 DigitalOut  lcd_blon(P8_1);
00081 PwmOut      lcd_cntrst(P8_15);
00082 DisplayBase Display;
00083 
00084 typedef struct {
00085     uint32_t pic_pos_x;             /* X position of the key picture. */
00086     uint32_t pic_pos_y;             /* Y position of the key picture. */
00087     uint32_t pic_width;             /* Width of the key picture. */
00088     uint32_t pic_height;            /* Height of the key picture. */
00089     func_code_t func_code;          /* func code of the key picture. */
00090 } key_pic_info_t;
00091 
00092 #if defined(__ICCARM__)
00093 #pragma data_alignment=32
00094 static uint8_t user_frame_buffer1[FRAME_BUFFER_STRIDE * LCD_PIXEL_HEIGHT];
00095 #pragma data_alignment=32
00096 static uint8_t user_frame_buffer2[FRAME_BUFFER_STRIDE * LCD_PIXEL_HEIGHT];
00097 #else
00098 static uint8_t user_frame_buffer1[FRAME_BUFFER_STRIDE * LCD_PIXEL_HEIGHT]__attribute((aligned(32))); /* 32 bytes aligned */
00099 static uint8_t user_frame_buffer2[FRAME_BUFFER_STRIDE * LCD_PIXEL_HEIGHT]__attribute((aligned(32))); /* 32 bytes aligned */
00100 static uint8_t jpeg_frame_buffer1[FRAME_BUFFER_STRIDE * LCD_PIXEL_HEIGHT]__attribute((aligned(32))); /* 32 bytes aligned */
00101 static uint8_t jpeg_frame_buffer2[FRAME_BUFFER_STRIDE * LCD_PIXEL_HEIGHT]__attribute((aligned(32))); /* 32 bytes aligned */
00102 static uint8_t audio_write_buff[AUDIO_WRITE_BUFF_NUM][AUDIO_WRITE_BUFF_SIZE] __attribute((section("NC_BSS"),aligned(4)));
00103 #endif
00104 static frame_buffer_t frame_buffer_info;
00105 static volatile int32_t vsync_count = 0;
00106 
00107 // Audio Tag buffers
00108 static uint8_t title_buf[TEXT_SIZE];
00109 static uint8_t artist_buf[TEXT_SIZE];
00110 static uint8_t album_buf[TEXT_SIZE];
00111 
00112 static const key_pic_info_t top_screen_key_tbl[] = {
00113     /*   X       Y     Width   Height   Func code                 */
00114     {    50,    350,    120,     52,    RGA_FUNC_DRAW_RECTANGLE    },  /* RGA Func1 */
00115     {   230,    350,    120,     52,    RGA_FUNC_VIDEO_PLAYER      },  /* RGA Func2 */
00116     {   410,    350,    120,     52,    RGA_FUNC_DISSOLVE          },  /* RGA Func3 */
00117     {    50,    420,    120,     52,    RGA_FUNC_SCROLL            },  /* RGA Func4 */
00118     {   230,    420,    120,     52,    RGA_FUNC_ZOOM              },  /* RGA Func5 */
00119     {   410,    420,    120,     52,    RGA_FUNC_ROTATION          },  /* RGA Func6 */
00120     {   615,    420,    120,     52,    RGA_FUNC_ACCELERATE        },  /* RGA Func7 */
00121     {     0,      0,      0,      0,    RGA_FUNC_END               }   /* table end */
00122 };
00123 
00124 static const key_pic_info_t return_key_tbl[] = {
00125     /*   X       Y     Width   Height   Func code                 */
00126     {   640,     10,    150,     84,    RGA_FUNC_RETURN            },  /* Return Top Screen */
00127     {     0,      0,      0,      0,    RGA_FUNC_END               }   /* table end */
00128 };
00129 
00130 static const key_pic_info_t animetion_timing_key_tbl[] = {
00131     /*   X       Y     Width   Height   Func code                 */
00132     {   640,     10,    150,     84,    RGA_FUNC_RETURN            },  /* Return Top Screen */
00133     {    17,    372,    136,     50,    RGA_FUNC_ANIME_EASE        },  /* ease */
00134     {   173,    372,    136,     50,    RGA_FUNC_ANIME_LINEAR      },  /* linear */
00135     {   330,    372,    136,     50,    RGA_FUNC_ANIME_EASE_IN     },  /* ease-in */
00136     {   487,    372,    136,     50,    RGA_FUNC_ANIME_EASE_OUT    },  /* ease-out */
00137     {   644,    372,    136,     50,    RGA_FUNC_ANIME_EASE_IN_OUT },  /* ease-in-out */
00138     {     0,      0,      0,      0,    RGA_FUNC_END               }   /* table end */
00139 };
00140 
00141 static const key_pic_info_t video_screen_key_tbl[] = {
00142     /*   X       Y     Width   Height   Func code                 */
00143     {   640,     10,    150,     84,    RGA_FUNC_RETURN            },  /* Return Top Screen */
00144     {   545,     55,    192,     64,    RGA_FUNC_VIDEO_PLAY        },  /* Video Play */
00145     {   545,     138,   192,     64,    RGA_FUNC_VIDEO_STOP        },  /* Video Stop */
00146     {   654,     241,    89,     60,    RGA_FUNC_VIDEO_FWD         },  /* Video Forward */
00147     {   545,     241,    89,     60,    RGA_FUNC_VIDEO_REV         }   /* Video Reverse */
00148 };
00149 TLV320_RBSP audio(P10_13, I2C_SDA, I2C_SCL, P4_4, P4_5, P4_7, P4_6,
00150                   0x80, (AUDIO_WRITE_BUFF_NUM - 1), 0);
00151                   
00152 /****** LCD ******/
00153 static void IntCallbackFunc_LoVsync(DisplayBase::int_type_t int_type) {
00154     /* Interrupt callback function for Vsync interruption */
00155     if (vsync_count > 0) {
00156         vsync_count--;
00157     }
00158 }
00159 
00160 static void Wait_Vsync(const int32_t wait_count) {
00161     /* Wait for the specified number of times Vsync occurs */
00162     vsync_count = wait_count;
00163     while (vsync_count > 0) {
00164         /* Do nothing */
00165     }
00166 }
00167 
00168 static void Init_LCD_Display(void) {
00169     DisplayBase::graphics_error_t error;
00170     DisplayBase::lcd_config_t lcd_config;
00171     PinName lvds_pin[8] = {
00172         /* data pin */
00173         P5_7, P5_6, P5_5, P5_4, P5_3, P5_2, P5_1, P5_0
00174     };
00175 
00176     lcd_pwon = 0;
00177     lcd_blon = 0;
00178     Thread::wait(100);
00179     lcd_pwon = 1;
00180     lcd_blon = 1;
00181 
00182     Display.Graphics_Lvds_Port_Init(lvds_pin, 8);
00183 
00184     /* Graphics initialization process */
00185     lcd_config = LcdCfgTbl_LCD_shield;
00186     error = Display.Graphics_init(&lcd_config);
00187     if (error != DisplayBase::GRAPHICS_OK) {
00188         printf("Line %d, error %d\n", __LINE__, error);
00189         mbed_die();
00190     }
00191 
00192     /* Interrupt callback function setting (Vsync signal output from scaler 0) */
00193     error = Display.Graphics_Irq_Handler_Set(DisplayBase::INT_TYPE_S0_LO_VSYNC, 0, IntCallbackFunc_LoVsync);
00194     if (error != DisplayBase::GRAPHICS_OK) {
00195         printf("Line %d, error %d\n", __LINE__, error);
00196         mbed_die();
00197     }
00198 }
00199 
00200 static void Start_LCD_Display(uint8_t * p_buf) {
00201     DisplayBase::rect_t rect;
00202 
00203     rect.vs = 0;
00204     rect.vw = LCD_PIXEL_HEIGHT;
00205     rect.hs = 0;
00206     rect.hw = LCD_PIXEL_WIDTH;
00207     Display.Graphics_Read_Setting(
00208         DisplayBase::GRAPHICS_LAYER_0,
00209         (void *)p_buf,
00210         FRAME_BUFFER_STRIDE,
00211         GRAPHICS_FORMAT,
00212         WR_RD_WRSWA,
00213         &rect
00214     );
00215     Display.Graphics_Start(DisplayBase::GRAPHICS_LAYER_0);
00216 }
00217 
00218 static void Update_LCD_Display(frame_buffer_t * frmbuf_info) {
00219     Display.Graphics_Read_Change(DisplayBase::GRAPHICS_LAYER_0,
00220      (void *)frmbuf_info->buffer_address[frmbuf_info->draw_buffer_index]);
00221     Wait_Vsync(1);
00222 }
00223 
00224 static void Swap_FrameBuffer(frame_buffer_t * frmbuf_info) {
00225     if (frmbuf_info->draw_buffer_index == 1) {
00226         frmbuf_info->draw_buffer_index = 0;
00227     } else {
00228         frmbuf_info->draw_buffer_index = 1;
00229     }
00230 }
00231 /****** Audio ******/
00232 static void callback_audio_write_end(void * p_data, int32_t result, void * p_app_data) {
00233     if (result < 0) {
00234         printf("audio write callback error %d\n", result);
00235     }
00236 }
00237 
00238 /****** Touch ******/
00239 static func_code_t Scan_Key(const key_pic_info_t * key_tbl, const uint32_t pos_x, const uint32_t pos_y) {
00240     func_code_t ret = RGA_FUNC_NON;
00241 
00242     while (ret == RGA_FUNC_NON) {
00243         if (key_tbl->func_code == RGA_FUNC_END) {
00244             break;
00245         }
00246         /* Check the range of the X position */
00247         if ((pos_x >= key_tbl->pic_pos_x) && (pos_x <= (key_tbl->pic_pos_x + key_tbl->pic_width))) {
00248             /* Check the range of the Y position */
00249             if ((pos_y >= key_tbl->pic_pos_y) && (pos_y <= (key_tbl->pic_pos_y + key_tbl->pic_height))) {
00250                 /* Decide the func code. */
00251                 ret = key_tbl->func_code;
00252             }
00253         }
00254         key_tbl++;
00255     }
00256 
00257     return ret;
00258 }
00259 
00260 /****** Efect ******/
00261 static void Exe_RGA_Func(func_code_t func_name, frame_buffer_t* frmbuf_info, TouckKey_LCD_shield * p_touch) {
00262     uint8_t touch_num = 0;
00263     TouchKey::touch_pos_t touch_pos[TOUCH_NUM];
00264 
00265     switch (func_name) {
00266         case RGA_FUNC_DRAW_RECTANGLE:
00267         {
00268             bool key_on = false;
00269             int cnt;
00270             int color_cnt = 0;
00271             int x_0 = 0;
00272             int y_0 = 0;
00273             draw_rectangle_pos_t pos_tbl[DRAW_RECTANGLE_CNT_MAX] = {0};
00274 
00275             pos_tbl[0].style = "#FF0000";  /* red */
00276             pos_tbl[1].style = "#00FF00";  /* green */
00277             pos_tbl[2].style = "#0000FF";  /* blue */
00278             pos_tbl[3].style = "#000000";  /* black */
00279 
00280             while (1) {
00281                 /* Get coordinates */
00282                 touch_num = p_touch->GetCoordinates(TOUCH_NUM, touch_pos);
00283                 if (touch_num != 0) {
00284                     if (Scan_Key(return_key_tbl, touch_pos[0].x, touch_pos[0].y) == RGA_FUNC_RETURN) {
00285                         break;
00286                     }
00287                     if (key_on == false) {
00288                         key_on = true;
00289                         if (color_cnt == 0) {
00290                             for (cnt = 0; cnt < DRAW_RECTANGLE_CNT_MAX; cnt++) {
00291                                 pos_tbl[cnt].x = 0;
00292                                 pos_tbl[cnt].y = 0;
00293                                 pos_tbl[cnt].w = 0;
00294                                 pos_tbl[cnt].h = 0;
00295                             }
00296                         }
00297                         x_0 = touch_pos[0].x;
00298                         y_0 = touch_pos[0].y;
00299                     }
00300                     if (x_0 < touch_pos[0].x) {
00301                         pos_tbl[color_cnt].x = x_0;
00302                         pos_tbl[color_cnt].w = touch_pos[0].x - x_0;
00303                     } else {
00304                         pos_tbl[color_cnt].x = touch_pos[0].x;
00305                         pos_tbl[color_cnt].w = x_0 - touch_pos[0].x;
00306                     }
00307                     if (y_0 < touch_pos[0].y) {
00308                         pos_tbl[color_cnt].y = y_0;
00309                         pos_tbl[color_cnt].h = touch_pos[0].y - y_0;
00310                     } else {
00311                         pos_tbl[color_cnt].y = touch_pos[0].y;
00312                         pos_tbl[color_cnt].h = y_0 - touch_pos[0].y;
00313                     }
00314                 } else {
00315                     if (key_on != false) {
00316                         color_cnt++;
00317                         if (color_cnt == DRAW_RECTANGLE_CNT_MAX) {
00318                             color_cnt = 0;
00319                         }
00320                     }
00321                     key_on = false;
00322                 }
00323                 /* Draw screen */
00324                 Swap_FrameBuffer(frmbuf_info);
00325                 RGA_Func_DrawRectangle(frmbuf_info, pos_tbl, DRAW_RECTANGLE_CNT_MAX);
00326                 Update_LCD_Display(frmbuf_info);
00327             }
00328         }
00329         break;
00330         case RGA_FUNC_DRAW_IMAGE:
00331         {
00332             int center_pos_x = 320;
00333             int center_pos_y = 110;
00334             while (1) {
00335                 /* Get coordinates */
00336                 touch_num = p_touch->GetCoordinates(TOUCH_NUM, touch_pos);
00337                 if (touch_num != 0) {
00338                     if (Scan_Key(return_key_tbl, touch_pos[0].x, touch_pos[0].y) == RGA_FUNC_RETURN) {
00339                         break;
00340                     }
00341                     center_pos_x = touch_pos[0].x;
00342                     center_pos_y = touch_pos[0].y;
00343                 }
00344                 /* Draw screen */
00345                 Swap_FrameBuffer(frmbuf_info);
00346                 RGA_Func_DrawImage(frmbuf_info, center_pos_x, center_pos_y);
00347                 Update_LCD_Display(frmbuf_info);
00348             }
00349         }
00350         break;
00351         case RGA_FUNC_VIDEO_PLAYER:
00352         {
00353             // FileSystem
00354             FILE * vfp = NULL;
00355             FILE * afp = NULL;
00356             DIR  * d = NULL;
00357             char file_path[sizeof(FLD_PATH) + FILE_NAME_LEN];
00358             uint16_t read_bytes = 0;
00359             dec_wav wav_file;
00360             
00361             // Video File
00362             int framesize = 0;
00363             float framerate = 0.0;
00364             uint8_t frame_skip = 2;
00365             
00366             // Audio File
00367             uint16_t buff_index = 0;
00368             uint8_t * p_buf = NULL;
00369             size_t audio_data_size;
00370             rbsp_data_conf_t audio_write_async_ctl = {&callback_audio_write_end, NULL};
00371             
00372             // Sync
00373             uint32_t frame_period_ms = 0;
00374             uint32_t audio_sample_size = 0;
00375             Timer timer;
00376             
00377             // Control
00378             bool audio_off = false;
00379             bool video_off = false;
00380             int8_t audio_skip = 0;
00381             
00382             /*******************************************************************
00383             *   Initialize SDHC FileSystem
00384             *******************************************************************/
00385             FATFileSystem fs("usb");
00386             SDBlockDevice_GR_PEACH msd;
00387             
00388             printf("GR-PEACH SDHC MSD\n");
00389             
00390             while(!msd.connect()) {
00391                 Thread::wait(500);
00392             }
00393             // Now that the MSD device is connected, file system is mounted.
00394             fs.mount(&msd);
00395             
00396             /*******************************************************************
00397             *   Initialize Audio
00398             *******************************************************************/
00399             audio.power(0x02); // mic off
00400             audio.inputVolume(0.7, 0.7);
00401     
00402             /*******************************************************************
00403             *   Read background
00404             *******************************************************************/
00405             strcpy(file_path, FLD_PATH);
00406             strcat(file_path, "Background.jpg");
00407             printf("File Open: %s\n", file_path);
00408             vfp = fopen(file_path, "r");
00409             read_bytes = fread(&jpeg_frame_buffer1[0], sizeof(char), 114419, vfp);
00410             fclose(vfp);
00411             
00412             /*******************************************************************
00413             *   Open Video File
00414             *******************************************************************/
00415             strcpy(file_path, FLD_PATH);
00416             strcat(file_path, "Renesas.jpg");
00417             vfp = fopen(file_path, "r");
00418             fread ( &framerate, sizeof(char), 4, vfp);
00419             printf( "Video FrameRate : %f\n", framerate );
00420             fread ( &framesize, sizeof(char), 4, vfp);
00421             fread ( jpeg_frame_buffer2, sizeof(char), framesize, vfp);
00422             
00423             /*******************************************************************
00424             *   Open and Anylize WAV file
00425             *******************************************************************/
00426             strcpy(file_path, FLD_PATH);
00427             strcat(file_path, "Renesas.wav");
00428             afp = fopen(file_path, "r");
00429             wav_file.AnalyzeHeder(title_buf, artist_buf, album_buf, TEXT_SIZE, afp);
00430             if ( false == audio.format(wav_file.GetBlockSize()) ) {
00431                 printf( "Audio ERROR Setting format : %d\n", wav_file.GetBlockSize());
00432                 break;
00433             }
00434             if ( false == audio.frequency(wav_file.GetSamplingRate()) ) {
00435                 printf( "Audio ERROR Setting frequency : f%Hz\n", wav_file.GetSamplingRate());
00436                 break;
00437             }
00438             /*******************************************************************
00439             *   Initialize Sync
00440             *******************************************************************/
00441             frame_period_ms = (int)((1/framerate) * 1000);
00442             printf( "Audio Frame Lenght : %dms\n", frame_period_ms);
00443             frame_period_ms = frame_period_ms * MJPEG_DIV;
00444             printf( "Video Frame Lenght : %dms\n", frame_period_ms);
00445             audio_sample_size = (int)((wav_file.GetSamplingRate() * wav_file.GetChannel()
00446                                                 * (wav_file.GetBlockSize()/8)) / ( framerate )) * MJPEG_DIV;
00447             frame_skip = MJPEG_DIV-1;
00448             
00449             TestPin0 = 0;
00450             TestPin1 = 0;
00451             TestPin2 = 0;
00452             TestPin3 = 0;
00453             timer.reset();
00454 
00455             while (1) {
00456                 
00457                 switch ( video_mode ) {
00458                     case RGA_FUNC_VIDEO_STOP:
00459                         audio_skip = 0;
00460                         audio_off = true;
00461                         frame_skip = MJPEG_DIV-1;
00462                         video_off = true;
00463                     case RGA_FUNC_VIDEO_FWD:
00464                         audio_skip = 4/MJPEG_DIV;
00465                         audio_off = true;
00466                         frame_skip += 4;
00467                         video_off = false;
00468                         break;
00469                     case RGA_FUNC_VIDEO_REV:
00470                     // TODO
00471                         break;
00472                     case RGA_FUNC_VIDEO_PLAY:
00473                         audio_skip = 0;
00474                         audio_off = false;
00475                         frame_skip = MJPEG_DIV-1;
00476                         video_off = false;
00477                     default :
00478                 }
00479                 timer.start();
00480                 
00481                 // if device disconnected, try to connect again
00482                 if (!msd.connected()) {
00483                     break;
00484                 }
00485                                 
00486                 // Read Next Video Frame
00487                 TestPin0 = 1;
00488                 if ( video_off != true ) {                
00489                     for ( int i = 0; i < frame_skip; i++ ) {
00490                         fread ( &framesize, sizeof(char), 4, vfp);
00491                         fseek ( vfp, framesize, SEEK_CUR);
00492                     }
00493                     fread ( &framesize, sizeof(char), 4, vfp);
00494                     fread ( jpeg_frame_buffer2, sizeof(char), framesize, vfp);
00495                 } else {
00496                     if ( vfp != NULL || afp != NULL ) {
00497                         fclose(vfp);
00498                         vfp = NULL;
00499                         fclose(afp);
00500                         afp = NULL;
00501                     }
00502                 }
00503                 TestPin0 = 0;
00504                 
00505                 // Read and play Next Audio Frame
00506                 TestPin1 = 1;
00507                 p_buf = audio_write_buff[buff_index];
00508                 audio_data_size = wav_file.GetNextData(p_buf, AUDIO_WRITE_BUFF_SIZE);
00509                 if (audio_data_size > 0) {
00510                     audio.write(p_buf, audio_data_size, &audio_write_async_ctl);
00511                     buff_index++;
00512                     if (buff_index >= AUDIO_WRITE_BUFF_NUM) {
00513                         buff_index = 0;
00514                     }
00515                 }
00516                 TestPin1 = 0;
00517                                    
00518                 /* Draw screen */
00519                 TestPin2 = 1;
00520                 if ( video_off != true ) {
00521                     Swap_FrameBuffer(frmbuf_info);
00522                     RGA_Func_VideoPlayer(frmbuf_info, jpeg_frame_buffer1, jpeg_frame_buffer2);
00523                     Update_LCD_Display(frmbuf_info);
00524                 }
00525                 TestPin2 = 0;
00526                 buff_index++;
00527             
00528                 // Sync
00529                 TestPin3 = 1;
00530                 while( frame_period_ms > timer.read_ms() && frame_skip < MJPEG_DIV );
00531                 timer.stop();
00532                 timer.reset();
00533                 TestPin3 = 0;               
00534                 
00535             } // end of switch 
00536         }
00537         break;
00538         case RGA_FUNC_DISSOLVE:
00539         {
00540             float32_t work_alpha = 0.0f;
00541             while (1) {
00542                 /* Get coordinates */
00543                 touch_num = p_touch->GetCoordinates(TOUCH_NUM, touch_pos);
00544                 if (touch_num != 0) {
00545                     if (Scan_Key(return_key_tbl, touch_pos[0].x, touch_pos[0].y) == RGA_FUNC_RETURN) {
00546                         break;
00547                     }
00548                     work_alpha = (float32_t)touch_pos[0].x / (float32_t)(LCD_PIXEL_WIDTH);
00549                 }
00550                 /* Draw screen */
00551                 Swap_FrameBuffer(frmbuf_info);
00552                 RGA_Func_Dissolve(frmbuf_info, work_alpha);
00553                 Update_LCD_Display(frmbuf_info);
00554             }
00555         }
00556         break;
00557         case RGA_FUNC_SCROLL:
00558         {
00559             int work_width_pos = 0;
00560             while (1) {
00561                 /* Get coordinates */
00562                 touch_num = p_touch->GetCoordinates(TOUCH_NUM, touch_pos);
00563                 if (touch_num != 0) {
00564                     if (Scan_Key(return_key_tbl, touch_pos[0].x, touch_pos[0].y) == RGA_FUNC_RETURN) {
00565                         break;
00566                     }
00567                     work_width_pos = SCROLL_MAX_NUM * ((float32_t)touch_pos[0].x / (float32_t)(LCD_PIXEL_WIDTH));
00568                 }
00569                 /* Draw screen */
00570                 Swap_FrameBuffer(frmbuf_info);
00571                 RGA_Func_Scroll(frmbuf_info, work_width_pos);
00572                 Update_LCD_Display(frmbuf_info);
00573             }
00574         }
00575         break;
00576         case RGA_FUNC_ZOOM:
00577         {
00578             int work_height_pos = ZOOM_MAX_NUM;
00579             while (1) {
00580                 /* Get coordinates */
00581                 touch_num = p_touch->GetCoordinates(TOUCH_NUM, touch_pos);
00582                 if (touch_num != 0) {
00583                     if (Scan_Key(return_key_tbl, touch_pos[0].x, touch_pos[0].y) == RGA_FUNC_RETURN) {
00584                         break;
00585                     }
00586                     work_height_pos = ZOOM_MAX_NUM * ((float32_t)touch_pos[0].x / (float32_t)(LCD_PIXEL_WIDTH));
00587                 }
00588                 /* Draw screen */
00589                 Swap_FrameBuffer(frmbuf_info);
00590                 RGA_Func_Zoom(frmbuf_info,  work_height_pos);
00591                 Update_LCD_Display(frmbuf_info);
00592             }
00593         }
00594         break;
00595         case RGA_FUNC_ROTATION:
00596         {
00597             graphics_matrix_float_t work_angle = 0;
00598             while (1) {
00599                 /* Get coordinates */
00600                 touch_num = p_touch->GetCoordinates(TOUCH_NUM, touch_pos);
00601                 if (touch_num != 0) {
00602                     if (Scan_Key(return_key_tbl, touch_pos[0].x, touch_pos[0].y) == RGA_FUNC_RETURN) {
00603                         break;
00604                     }
00605                     work_angle = ROTATION_MAX_NUM * ((float32_t)touch_pos[0].x / (float32_t)(LCD_PIXEL_WIDTH));
00606                 }
00607                 /* Draw screen */
00608                 Swap_FrameBuffer(frmbuf_info);
00609                 RGA_Func_Rotation(frmbuf_info, work_angle);
00610                 Update_LCD_Display(frmbuf_info);
00611             }
00612         }
00613         break;
00614         case RGA_FUNC_ACCELERATE:
00615         {
00616             int acce_frame_num = 0;
00617             int animation_timing = 0;
00618             float32_t work_relative_pos;
00619             while (1) {
00620                 /* Get coordinates */
00621                 touch_num = p_touch->GetCoordinates(TOUCH_NUM, touch_pos);
00622                 if (touch_num != 0) {
00623                     func_code_t func_code;
00624 
00625                     func_code = Scan_Key(animetion_timing_key_tbl, touch_pos[0].x, touch_pos[0].y);
00626                     if (func_code == RGA_FUNC_RETURN) {
00627                         break;
00628                     }
00629                     switch (func_code) {
00630                         case RGA_FUNC_ANIME_EASE:
00631                             animation_timing = 0;
00632                             acce_frame_num = 0;
00633                             break;
00634                         case RGA_FUNC_ANIME_LINEAR:
00635                             animation_timing = 1;
00636                             acce_frame_num = 0;
00637                             break;
00638                         case RGA_FUNC_ANIME_EASE_IN:
00639                             animation_timing = 2;
00640                             acce_frame_num = 0;
00641                             break;
00642                         case RGA_FUNC_ANIME_EASE_OUT:
00643                             animation_timing = 3;
00644                             acce_frame_num = 0;
00645                             break;
00646                         case RGA_FUNC_ANIME_EASE_IN_OUT:
00647                             animation_timing = 4;
00648                             acce_frame_num = 0;
00649                             break;
00650                         default:
00651                             /* Do Nothing */
00652                             break;
00653                     }
00654                 }
00655                 work_relative_pos = acce_frame_num / (float32_t)ACCELERATE_MAX_NUM;
00656                 acce_frame_num++;
00657                 if (acce_frame_num > ACCELERATE_MAX_NUM) {
00658                     acce_frame_num = 0;
00659                 }
00660                 /* Draw screen */
00661                 Swap_FrameBuffer(frmbuf_info);
00662                 RGA_Func_Accelerate(frmbuf_info, animation_timing, work_relative_pos);
00663                 Update_LCD_Display(frmbuf_info);
00664             }
00665         }
00666         break;
00667         default :
00668             /* Do nothing */
00669             break;
00670     }
00671 }
00672 
00673 int main(void) {
00674     func_code_t func_code;
00675     uint8_t touch_num = 0;
00676     TouchKey::touch_pos_t touch_pos[TOUCH_NUM];
00677 
00678     /* Initialization of LCD */
00679     Init_LCD_Display();    /* When using LCD, please call before than Init_Video(). */
00680 
00681     memset(user_frame_buffer1, 0, sizeof(user_frame_buffer1));
00682     memset(user_frame_buffer2, 0, sizeof(user_frame_buffer2));
00683     frame_buffer_info.buffer_address[0] = user_frame_buffer1;
00684     frame_buffer_info.buffer_address[1] = user_frame_buffer2;
00685     frame_buffer_info.buffer_count      = 2;
00686     frame_buffer_info.show_buffer_index = 0;
00687     frame_buffer_info.draw_buffer_index = 0;
00688     frame_buffer_info.width             = LCD_PIXEL_WIDTH;
00689     frame_buffer_info.byte_per_pixel    = FRAME_BUFFER_BYTE_PER_PIXEL;
00690     frame_buffer_info.stride            = LCD_PIXEL_WIDTH * FRAME_BUFFER_BYTE_PER_PIXEL;
00691     frame_buffer_info.height            = LCD_PIXEL_HEIGHT;
00692     frame_buffer_info.pixel_format      = PIXEL_FORMAT_RGB565;
00693 
00694     /* Display Top Screen */
00695     Set_RGAObject(&frame_buffer_info);
00696     RGA_Func_DrawTopScreen(&frame_buffer_info);
00697         
00698     /* Start of LCD */
00699     Start_LCD_Display(frame_buffer_info.buffer_address[0]);
00700 
00701     /* Backlight on */
00702     Thread::wait(200);
00703     lcd_cntrst.write(1.0);
00704 
00705     /* Reset touch IC */
00706     TouckKey_LCD_shield touch(P4_0, P2_13, I2C_SDA, I2C_SCL);
00707     touch.Reset();
00708     
00709     while (1) {
00710         /* Get Coordinates */
00711         touch_num = touch.GetCoordinates(TOUCH_NUM, touch_pos);
00712         if (touch_num != 0) {
00713             func_code = Scan_Key(top_screen_key_tbl, touch_pos[0].x, touch_pos[0].y);
00714             if (func_code != RGA_FUNC_NON) {
00715                 /* Wait key off */
00716                 while (1) {
00717                     touch_num = touch.GetCoordinates(TOUCH_NUM, touch_pos);
00718                     if (touch_num == 0) {
00719                         break;
00720                     }
00721                     Thread::wait(20);
00722                 }
00723 
00724                 /* Execute RGA functions */
00725                 Exe_RGA_Func(func_code, &frame_buffer_info, &touch);
00726 
00727                 /* Return Top Screen */
00728                 Swap_FrameBuffer(&frame_buffer_info);
00729                 RGA_Func_DrawTopScreen(&frame_buffer_info);
00730                 Update_LCD_Display(&frame_buffer_info);
00731             }
00732         }
00733         Thread::wait(20);
00734     }
00735 }