Subversion Repositories Kolibri OS

Rev

Rev 3292 | Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1.  
  2. #include <stdint.h>
  3. #include <libavcodec/avcodec.h>
  4. #include <libavformat/avformat.h>
  5. #include <libswscale/swscale.h>
  6. #include <libavutil/imgutils.h>
  7. #include "system.h"
  8. #include "../winlib/winlib.h"
  9. #include "sound.h"
  10. #include "fplay.h"
  11. #include <math.h>
  12.  
  13. extern int res_pause_btn[];
  14. extern int res_pause_btn_pressed[];
  15.  
  16. extern int res_play_btn[];
  17. extern int res_play_btn_pressed[];
  18.  
  19. extern int64_t stream_duration;
  20. extern volatile int sound_level_0;
  21. extern volatile int sound_level_1;
  22.  
  23. typedef struct
  24. {
  25.     AVPicture      picture;
  26.     double         pts;
  27.     volatile int   ready;
  28. }vframe_t;
  29.  
  30. vframe_t           frames[4];
  31. volatile int      frames_count = 0;
  32.  
  33. struct SwsContext *cvt_ctx = NULL;
  34.  
  35. int vfx    = 0;
  36. int dfx    = 0;
  37.  
  38. render_t   *main_render;
  39.  
  40. int width;
  41. int height;
  42.  
  43. AVRational video_time_base;
  44. AVFrame  *Frame;
  45.  
  46. volatile uint32_t driver_lock;
  47.  
  48. void get_client_rect(rect_t *rc);
  49.  
  50. void flush_video()
  51. {
  52.     int i;
  53.  
  54.     for(i = 0; i < 4; i++)
  55.     {    
  56.         frames[i].pts    = 0;
  57.         frames[i].ready  = 0;
  58.     };
  59.     frames_count = 0;
  60.     vfx    = 0;
  61.     dfx    = 0;
  62. };
  63.  
  64. int init_video(AVCodecContext *ctx)
  65. {
  66.     int        i;
  67.  
  68.     width = ctx->width;
  69.     height = ctx->height;
  70.  
  71.  
  72.     Frame = avcodec_alloc_frame();
  73.     if ( Frame == NULL )
  74.     {
  75.         printf("Cannot alloc video frame\n\r");
  76.         return 0;
  77.     };
  78.  
  79.     for( i=0; i < 4; i++)
  80.     {
  81.         int ret;
  82.  
  83. //        printf("alloc picture %d %d %x\n",
  84. //                   ctx->width, ctx->height, ctx->pix_fmt );
  85.  
  86.         ret = avpicture_alloc(&frames[i].picture, ctx->pix_fmt,
  87.                                ctx->width, ctx->height);
  88.         if ( ret != 0 )
  89.         {
  90.             printf("Cannot alloc video buffer\n\r");
  91.             return 0;
  92.         };
  93.  
  94.         frames[i].pts    = 0;
  95.         frames[i].ready  = 0;
  96.     };
  97.  
  98.     create_thread(video_thread, ctx, 1024*1024);
  99.  
  100.     delay(50);
  101.     return 1;
  102. };
  103.  
  104. int decode_video(AVCodecContext  *ctx, queue_t *qv)
  105. {
  106.     AVPacket   pkt;
  107.     double     pts;
  108.     int frameFinished;
  109.     double current_clock;
  110.  
  111.     if(frames[dfx].ready != 0 )
  112.         return -1;
  113.  
  114.     if( get_packet(qv, &pkt) == 0 )
  115.         return 0;
  116.  
  117. /*
  118.     current_clock = -90.0 + get_master_clock();
  119.  
  120.     if( pkt.dts == AV_NOPTS_VALUE &&
  121.         Frame->reordered_opaque != AV_NOPTS_VALUE)
  122.         pts = Frame->reordered_opaque;
  123.     else if(pkt.dts != AV_NOPTS_VALUE)
  124.         pts= pkt.dts;
  125.     else
  126.         pts= 0;
  127.        
  128.  
  129.     pts *= av_q2d(video_time_base)*1000.0;
  130. */
  131.     if( 1 /*pts > current_clock*/)
  132.     {
  133.         frameFinished = 0;
  134.  
  135.         ctx->reordered_opaque = pkt.pts;
  136.  
  137.         if(avcodec_decode_video2(ctx, Frame, &frameFinished, &pkt) <= 0)
  138.             printf("video decoder error\n");
  139.  
  140.         if(frameFinished)
  141.         {
  142.             AVPicture *dst_pic;
  143.  
  144.             if( pkt.dts == AV_NOPTS_VALUE &&
  145.                 Frame->reordered_opaque != AV_NOPTS_VALUE)
  146.                 pts = Frame->reordered_opaque;
  147.             else if(pkt.dts != AV_NOPTS_VALUE)
  148.                 pts= pkt.dts;
  149.             else
  150.                 pts= 0;
  151.  
  152. //        pts = *(int64_t*)av_opt_ptr(avcodec_get_frame_class(),
  153. //                                Frame, "best_effort_timestamp");
  154.  
  155. //        if (pts == AV_NOPTS_VALUE)
  156. //            pts = 0;
  157.  
  158.             pts *= av_q2d(video_time_base);
  159.  
  160.             dst_pic = &frames[dfx].picture;
  161.  
  162.             av_image_copy(dst_pic->data, dst_pic->linesize,
  163.                       (const uint8_t**)Frame->data,
  164.                       Frame->linesize, ctx->pix_fmt, ctx->width, ctx->height);
  165.  
  166.             frames[dfx].pts = pts*1000.0;
  167. //            printf("pts %f\n", frames[dfx].pts);
  168.  
  169.             frames[dfx].ready = 1;
  170.  
  171.             dfx++;
  172.             dfx&= 3;
  173.             frames_count++;
  174.         };
  175.     };
  176.     av_free_packet(&pkt);
  177.  
  178.     return 1;
  179. }
  180.  
  181. extern volatile enum player_state player_state;
  182. extern volatile enum player_state decoder_state;
  183. extern volatile enum player_state sound_state;
  184.  
  185. //rect_t     win_rect;
  186.  
  187. extern int64_t rewind_pos;
  188.  
  189. static void player_stop()
  190. {
  191.     window_t  *win;    
  192.    
  193.     win = main_render->win;
  194.    
  195.     rewind_pos = 0;
  196.    
  197.     win->panel.play_btn->img_default    = res_play_btn;
  198.     win->panel.play_btn->img_hilite     = res_play_btn;
  199.     win->panel.play_btn->img_pressed    = res_play_btn_pressed;
  200.     win->panel.prg->current             = rewind_pos;
  201.    
  202.     send_message(&win->panel.ctrl, MSG_PAINT, 0, 0);
  203.     player_state = STOP;
  204.     decoder_state = PLAY_2_STOP;
  205.     sound_state = PLAY_2_STOP;
  206.     render_draw_client(main_render);
  207. //    printf("stop player\n");
  208.    
  209. };
  210.  
  211. int MainWindowProc(ctrl_t *ctrl, uint32_t msg, uint32_t arg1, uint32_t arg2)
  212. {
  213.     window_t  *win;
  214.  
  215.     win = (window_t*)ctrl;
  216.  
  217.     switch(msg)
  218.     {
  219.         case MSG_SIZE:
  220.             //printf("MSG_SIZE\n");
  221.             if(main_render)
  222.             {
  223.                 render_adjust_size(main_render, win);
  224.                 render_draw_client(main_render);
  225.             };
  226.             break;
  227.  
  228.         case MSG_DRAW_CLIENT:
  229.             render_draw_client(main_render);
  230.             break;
  231.  
  232.         case MSG_LBTNDOWN:
  233.        
  234.             if(player_state == PAUSE)
  235.             {
  236.                 win->panel.play_btn->img_default = res_pause_btn;
  237.                 win->panel.play_btn->img_hilite  = res_pause_btn;
  238.                 win->panel.play_btn->img_pressed = res_pause_btn_pressed;
  239.                 send_message(&win->panel.play_btn->ctrl, MSG_PAINT, 0, 0);
  240.                 player_state = PLAY;
  241.                 sound_state  = PAUSE_2_PLAY;
  242.  
  243.             }
  244.             else if(player_state == PLAY)
  245.             {
  246.                 win->panel.play_btn->img_default = res_play_btn;
  247.                 win->panel.play_btn->img_hilite  = res_play_btn;
  248.                 win->panel.play_btn->img_pressed = res_play_btn_pressed;
  249.                 send_message(&win->panel.play_btn->ctrl, MSG_PAINT, 0, 0);
  250.                 player_state = PAUSE;
  251.                 sound_state  = PLAY_2_PAUSE;
  252.             }
  253.             break;
  254.  
  255.         case MSG_COMMAND:
  256.             switch((short)arg1)
  257.             {
  258.                 case ID_PLAY:
  259.                     if(player_state == PAUSE)
  260.                     {
  261.                         win->panel.play_btn->img_default  = res_pause_btn;
  262.                         win->panel.play_btn->img_hilite   = res_pause_btn;
  263.                         win->panel.play_btn->img_pressed = res_pause_btn_pressed;
  264.                         player_state = PLAY;
  265.                         sound_state = PAUSE_2_PLAY;
  266.                     }
  267.                     else if(player_state == PLAY)
  268.                     {
  269.                         win->panel.play_btn->img_default = res_play_btn;
  270.                         win->panel.play_btn->img_hilite  = res_play_btn;
  271.                         win->panel.play_btn->img_pressed  = res_play_btn_pressed;
  272.                         player_state = PAUSE;
  273.                         sound_state  = PLAY_2_PAUSE;
  274.                     }
  275.                     else if(player_state == STOP)
  276.                     {
  277.                         win->panel.play_btn->img_default  = res_pause_btn;
  278.                         win->panel.play_btn->img_hilite   = res_pause_btn;
  279.                         win->panel.play_btn->img_pressed = res_pause_btn_pressed;
  280.                         rewind_pos = 0;    
  281.                         send_message(&win->panel.ctrl, MSG_PAINT, 0, 0);
  282.                         player_state = PLAY;
  283.                         decoder_state = PREPARE;
  284.                     }
  285.                     break;
  286.                    
  287.                 case ID_STOP:
  288.                     player_stop();
  289.                     break;
  290.                    
  291.                 case ID_PROGRESS:
  292.                     if(player_state != REWIND)
  293.                     {
  294.                         progress_t *prg = (progress_t*)arg2;
  295.                    
  296.                         rewind_pos = (prg->max - prg->min)*prg->pos/prg->ctrl.w;
  297.                              
  298. //                        printf("progress action pos: %d time: %f\n", prg->pos, (double)rewind_pos);
  299.                         player_state  = REWIND;
  300.                         decoder_state = REWIND;
  301.                         sound_state   = PLAY_2_STOP;
  302.                         if(rewind_pos < prg->current)
  303.                         {
  304.                             prg->current  = rewind_pos;
  305.                             rewind_pos = -rewind_pos;
  306.                         }
  307.                         else
  308.                             prg->current  = rewind_pos;
  309.                        
  310.                         win->panel.play_btn->img_default  = res_pause_btn;
  311.                         win->panel.play_btn->img_hilite   = res_pause_btn;
  312.                         win->panel.play_btn->img_pressed  = res_pause_btn_pressed;
  313.                         send_message(&prg->ctrl, MSG_PAINT, 0, 0);
  314.                     };
  315.                     break;
  316.                    
  317.                 case ID_VOL_CTRL:      
  318.                 {
  319.                     slider_t *sld = (slider_t*)arg2;
  320.                     int      peak;
  321.                     int      level;
  322.                    
  323.                     peak = sld->min + sld->pos * (sld->max - sld->min)/(96);
  324. //                    level = (log2(peak+16384)*10000.0)/15 - 10000;
  325.                     level =  peak;
  326.                      
  327. //                    printf("level %d\n", level);
  328.                     set_audio_volume(level, level);
  329.                     send_message(&sld->ctrl, MSG_PAINT, 0, 0);
  330.                     win->panel.lvl->vol = level;
  331.                 }
  332.                
  333.                 default:
  334.                     break;
  335.             }
  336.             break;
  337.  
  338.         default:
  339.             def_window_proc(ctrl,msg,arg1,arg2);
  340.     };
  341.     return 0;
  342. };
  343.  
  344. #define VERSION_A          1
  345.  
  346. void render_time(render_t *render)
  347. {
  348.     progress_t  *prg = main_render->win->panel.prg;
  349.     level_t     *lvl = main_render->win->panel.lvl;
  350.      
  351.     double      ctime;            /*    milliseconds    */
  352.     double      fdelay;           /*    milliseconds    */
  353.  
  354. //again:
  355.  
  356.     if(player_state == CLOSED)
  357.     {
  358.         render->win->win_command = WIN_CLOSED;
  359.         return;
  360.     }
  361.     else if(player_state == REWIND)
  362.     {
  363.         yield();
  364.         return;  
  365.     }
  366.     else if (decoder_state == STOP && frames_count  == 0 &&
  367.               player_state  != STOP)
  368.     {          
  369.         player_stop();
  370.     }
  371.     else if(player_state != PLAY)
  372.     {
  373.         yield();
  374.         return;
  375.     };
  376.  
  377.  
  378. #ifdef VERSION_A
  379.     if(frames[vfx].ready == 1 )
  380.     {
  381.         int sys_time;
  382.  
  383.         ctime = get_master_clock();
  384.         fdelay = (frames[vfx].pts - ctime);
  385.  
  386. //        printf("pts %f time %f delay %f\n",
  387. //                frames[vfx].pts, ctime, fdelay);
  388.  
  389.         if(fdelay > 15.0)
  390.         {
  391.             delay(1);
  392. //            yield();
  393.             return;
  394.         };
  395.  
  396.         ctime = get_master_clock();
  397.         fdelay = (frames[vfx].pts - ctime);
  398.  
  399.         sys_time = get_tick_count();
  400.  
  401. //      if(fdelay < 0)
  402. //            printf("systime %d pts %f time %f delay %f\n",
  403. //                    sys_time*10, frames[vfx].pts, ctime, fdelay);
  404.  
  405.         main_render->draw(main_render, &frames[vfx].picture);
  406.         if(main_render->win->win_state != FULLSCREEN)
  407.         {
  408.             prg->current = frames[vfx].pts*1000;
  409. //        printf("current %f\n", prg->current);
  410.             lvl->current = vfx & 1 ? sound_level_1 : sound_level_0;
  411.        
  412.             send_message(&prg->ctrl, PRG_PROGRESS, 0, 0);
  413.        
  414.             if(main_render->win->panel.layout)
  415.                 send_message(&lvl->ctrl, MSG_PAINT, 0, 0);
  416.         }
  417.        
  418.         frames_count--;
  419.         frames[vfx].ready = 0;
  420.         vfx++;
  421.         vfx&= 3;
  422.     }
  423.     else yield();
  424.  
  425. #else
  426.  
  427.     if(frames[vfx].ready == 1 )
  428.     {
  429.         ctime = get_master_clock();
  430.         fdelay = (frames[vfx].pts - ctime);
  431.  
  432. //            printf("pts %f time %f delay %f\n",
  433. //                    frames[vfx].pts, ctime, fdelay);
  434.  
  435.         if(fdelay < 0.0 )
  436.         {
  437.             int  next_vfx;
  438.             fdelay = 0;
  439.             next_vfx = (vfx+1) & 3;
  440.             if( frames[next_vfx].ready == 1 )
  441.             {
  442.                 if(frames[next_vfx].pts <= ctime)
  443.                 {
  444.                     frames[vfx].ready = 0;                  // skip this frame
  445.                     vfx++;
  446.                     vfx&= 3;
  447.                 }
  448.                 else
  449.                 {
  450.                     if( (frames[next_vfx].pts - ctime) <
  451.                         ( ctime - frames[vfx].pts) )
  452.                     {
  453.                         frames[vfx].ready = 0;                  // skip this frame
  454.                         vfx++;
  455.                         vfx&= 3;
  456.                         fdelay = (frames[next_vfx].pts - ctime);
  457.                     }
  458.                 }
  459.             };
  460.         };
  461.  
  462.         if(fdelay > 10.0)
  463.         {
  464.            int val = fdelay;
  465.            printf("pts %f time %f delay %d\n",
  466.                    frames[vfx].pts, ctime, val);
  467.            delay(val/10);
  468.         };
  469.  
  470.         ctime = get_master_clock();
  471.         fdelay = (frames[vfx].pts - ctime);
  472.  
  473.         printf("pts %f time %f delay %f\n",
  474.                 frames[vfx].pts, ctime, fdelay);
  475.  
  476.         main_render->draw(main_render, &frames[vfx].picture);
  477.         main_render->win->panel.prg->current = frames[vfx].pts;
  478. //        send_message(&render->win->panel.prg->ctrl, MSG_PAINT, 0, 0);
  479.         frames[vfx].ready = 0;
  480.         vfx++;
  481.         vfx&= 3;
  482.     }
  483.     else yield();
  484. #endif
  485.  
  486. }
  487.  
  488.  
  489. extern char *movie_file;
  490.  
  491. int video_thread(void *param)
  492. {
  493.     AVCodecContext *ctx = param;
  494.     window_t  *MainWindow;
  495.    
  496.     init_winlib();
  497.  
  498.     MainWindow = create_window(movie_file,0,
  499.                                10,10,width,height+CAPTION_HEIGHT+PANEL_HEIGHT,MainWindowProc);
  500.  
  501.     MainWindow->panel.prg->max = stream_duration;
  502. //    printf("MainWindow %x\n", MainWindow);
  503.  
  504.     show_window(MainWindow, NORMAL);
  505.  
  506. //    __asm__ __volatile__("int3");
  507.  
  508.     main_render = create_render(MainWindow, ctx, HW_BIT_BLIT|HW_TEX_BLIT);
  509.     if( main_render == NULL)
  510.     {
  511.         printf("Cannot create render\n\r");
  512.         return 0;
  513.     };
  514.  
  515.     render_draw_client(main_render);
  516.     player_state = PLAY;
  517.  
  518.     run_render(MainWindow, main_render);
  519.  
  520.     destroy_render(main_render);
  521.     fini_winlib();
  522.  
  523.     player_state = CLOSED;
  524.     return 0;
  525. };
  526.  
  527.  
  528. void draw_hw_picture(render_t *render, AVPicture *picture);
  529. void draw_sw_picture(render_t *render, AVPicture *picture);
  530.  
  531. render_t *create_render(window_t *win, AVCodecContext *ctx, uint32_t flags)
  532. {
  533.     render_t *render;
  534.  
  535.     uint32_t right, bottom, draw_w, draw_h;
  536.     uint32_t s, sw, sh;
  537.     uint8_t  state;
  538.  
  539. //    __asm__ __volatile__("int3");
  540.  
  541.     render = (render_t*)malloc(sizeof(render_t));
  542.     memset(render, 0, sizeof(render_t));
  543.  
  544.     render->win = win;
  545.  
  546.     render->ctx_width  = ctx->width;
  547.     render->ctx_height = ctx->height;
  548.     render->ctx_format = ctx->pix_fmt;
  549.  
  550.     mutex_lock(&driver_lock);
  551.     render->caps = init_pixlib(flags);
  552.     mutex_unlock(&driver_lock);
  553.    
  554.     right  = win->w;
  555.     bottom = win->h-CAPTION_HEIGHT-PANEL_HEIGHT;
  556.  
  557.  //   printf("window width %d height %d\n",
  558.  //                   right, bottom);
  559.  
  560.     render->win_state  = win->win_state;
  561.  
  562.     draw_w = bottom*render->ctx_width/render->ctx_height;
  563.     draw_h = right*render->ctx_height/render->ctx_width;
  564.  
  565.     if(draw_w > right)
  566.     {
  567.         draw_w = right;
  568.         draw_h = right*render->ctx_height/render->ctx_width;
  569.     };
  570.    
  571.     if(draw_h > bottom)
  572.     {
  573.         draw_h = bottom;
  574.         draw_w = bottom*render->ctx_width/render->ctx_height;
  575.     };
  576.  
  577.     render->win_width  = win->w;
  578.     render->win_height = win->h-CAPTION_HEIGHT-PANEL_HEIGHT;
  579.    
  580.     render_set_size(render, draw_w, draw_h);
  581.    
  582.  
  583.     if(render->caps==0)
  584.     {
  585.         render->bitmap[0].width  = draw_w;
  586.         render->bitmap[0].height = draw_h;
  587.  
  588.         if( create_bitmap(&render->bitmap[0]) != 0 )
  589.         {
  590.             free(render);
  591.             return NULL;
  592.         }
  593.         render->draw = draw_sw_picture;
  594.     }
  595.     else
  596.     {
  597.         int width, height, flags;
  598.         int i;
  599.        
  600.         if(render->caps & HW_TEX_BLIT)
  601.         {
  602.             sna_create_mask();
  603.  
  604.             width  = render->ctx_width;    
  605.             height = render->ctx_height;    
  606.             flags  = HW_TEX_BLIT;    
  607.         }
  608.         else
  609.         {
  610.             width  = draw_w;    
  611.             height = draw_h;;    
  612.             flags  = HW_BIT_BLIT;    
  613.         }
  614.  
  615.         for( i=0; i < 2; i++)
  616.         {
  617.             render->bitmap[i].width  = width;
  618.             render->bitmap[i].height = height;
  619.             render->bitmap[i].flags  = flags;
  620.  
  621.             if( create_bitmap(&render->bitmap[i]) != 0 )
  622.             {
  623.                 player_state = CLOSED;
  624.                 free(render);
  625.                 return NULL;
  626.             };
  627.         }
  628.        
  629.         render->state = INIT;
  630.         render->target = 0;
  631.         render->draw   = draw_hw_picture;
  632.     };
  633.    
  634.     printf("FPlay %s render engine: context %dx%d picture %dx%d\n",
  635.            render->caps==0 ? "software":"hardware",
  636.            render->ctx_width, render->ctx_height,
  637.            draw_w, draw_h);
  638.              
  639.     return render;
  640. };
  641.  
  642. void destroy_render(render_t *render)
  643. {
  644.  
  645.     destroy_bitmap(&render->bitmap[0]);
  646.    
  647.     if(render->caps & (HW_BIT_BLIT|HW_TEX_BLIT))          /* hw blitter */
  648.         destroy_bitmap(&render->bitmap[1]);
  649.    
  650.     done_pixlib();  
  651. };
  652.  
  653. void render_set_size(render_t *render, int width, int height)
  654. {
  655.     int i;
  656.  
  657.     render->layout = 0;
  658.     render->rcvideo.l = 0;
  659.     render->rcvideo.t = 0;
  660.     render->rcvideo.r = width;
  661.     render->rcvideo.b = height;
  662.  
  663. //    printf("render width %d height %d\n",width, height);
  664.  
  665.     if( render->win_height > height )
  666.     {
  667.         int yoffs;
  668.         yoffs = (render->win_height-height)/2;
  669.         if(yoffs)
  670.         {
  671.             render->rctop.t = 0;
  672.             render->rctop.b = yoffs;
  673.             render->rcvideo.t  = yoffs;
  674.             render->layout |= HAS_TOP;
  675.         }
  676.  
  677.         yoffs = render->win_height-(render->rcvideo.t+render->rcvideo.b);
  678.         if(yoffs)
  679.         {
  680.             render->rcbottom.t = render->rcvideo.t+render->rcvideo.b;
  681.             render->rcbottom.b = yoffs;
  682.             render->layout |= HAS_BOTTOM;
  683.         }
  684.     }
  685.  
  686.     if( render->win_width > width )
  687.     {
  688.         int xoffs;
  689.         xoffs = (render->win_width-width)/2;
  690.         if(xoffs)
  691.         {
  692.             render->rcleft.r  = xoffs;
  693.             render->rcvideo.l = xoffs;
  694.             render->layout |= HAS_LEFT;
  695.         }
  696.         xoffs = render->win_width-(render->rcvideo.l+render->rcvideo.r);
  697.         if(xoffs)
  698.         {
  699.             render->rcright.l = render->rcvideo.l+render->rcvideo.r;
  700.             render->rcright.r = xoffs;
  701.             render->layout |= HAS_RIGHT;
  702.         }
  703.     };
  704. };
  705.  
  706. void render_adjust_size(render_t *render, window_t *win)
  707. {
  708.     uint32_t right, bottom, new_w, new_h;
  709.     uint32_t s, sw, sh;
  710.     uint8_t  state;
  711.  
  712.     right  = win->w;
  713.     bottom = win->h;
  714.  
  715.     if(win->win_state != FULLSCREEN)
  716.         bottom-= CAPTION_HEIGHT+PANEL_HEIGHT;
  717.    
  718.  //   printf("window width %d height %d\n",
  719.  //                   right, bottom);
  720.  
  721.     render->win_state  = win->win_state;
  722.  
  723.     if(render->win_state == MINIMIZED)
  724.         return;
  725.  
  726.     if(render->win_state == ROLLED)
  727.         return;
  728.  
  729.     if( right  == render->win_width &&
  730.         bottom == render->win_height)
  731.         return;
  732.  
  733.     printf("%s r: %d b: %d\n", __FUNCTION__, right, bottom);
  734.    
  735.     new_w = bottom*render->ctx_width/render->ctx_height;
  736.     new_h = right*render->ctx_height/render->ctx_width;
  737.  
  738.     if(new_w > right)
  739.     {
  740.         new_w = right;
  741.         new_h = right*render->ctx_height/render->ctx_width;
  742.     };
  743.     if(new_h > bottom)
  744.     {
  745.         new_h = bottom;
  746.         new_w = bottom*render->ctx_width/render->ctx_height;
  747.     };
  748.  
  749.     render->win_width  = right;
  750.     render->win_height = bottom;
  751.     render_set_size(render, new_w, new_h);
  752.  
  753.     if(render->caps & HW_TEX_BLIT)          /*  hw scaler  */
  754.         return;
  755.  
  756.     render->bitmap[0].width  = new_w;
  757.     render->bitmap[0].height = new_h;
  758.     resize_bitmap(&render->bitmap[0]);
  759.  
  760.     if(render->caps & HW_BIT_BLIT)          /* hw blitter */
  761.     {
  762.         render->bitmap[1].width  = new_w;
  763.         render->bitmap[1].height = new_h;
  764.         resize_bitmap(&render->bitmap[1]);
  765.     };
  766.     return;
  767. };
  768.  
  769. void draw_hw_picture(render_t *render, AVPicture *picture)
  770. {
  771.     int      dst_width, dst_height;
  772.     bitmap_t   *bitmap;
  773.     uint8_t    *data[4];
  774.     int      linesize[4];
  775.     int ret;
  776.  
  777.     if(render->win->win_state == MINIMIZED ||
  778.        render->win->win_state == ROLLED)
  779.         return;
  780.  
  781.     if(render->caps & HW_TEX_BLIT)
  782.     {
  783.         dst_width  = render->ctx_width;
  784.         dst_height = render->ctx_height;
  785.     }
  786.     else
  787.     {
  788.         dst_width  = render->rcvideo.r;
  789.         dst_height = render->rcvideo.b;
  790.     };
  791.  
  792.     cvt_ctx = sws_getCachedContext(cvt_ctx,
  793.               render->ctx_width, render->ctx_height, render->ctx_format,
  794.               dst_width, dst_height, PIX_FMT_BGRA,
  795.               SWS_FAST_BILINEAR, NULL, NULL, NULL);
  796.     if(cvt_ctx == NULL)
  797.     {
  798.         printf("Cannot initialize the conversion context!\n");
  799.         return ;
  800.     };
  801.  
  802.     bitmap = &render->bitmap[render->target];
  803.  
  804.     ret = lock_bitmap(bitmap);
  805.     if( ret != 0)
  806.     {
  807.         printf("Cannot lock bitmap!\n");
  808.         return ;
  809.     }
  810.  
  811. //    printf("sws_getCachedContext\n");
  812.     data[0] = bitmap->data;
  813.     data[1] = bitmap->data+1;
  814.     data[2] = bitmap->data+2;
  815.     data[3] = bitmap->data+3;
  816.  
  817.     linesize[0] = bitmap->pitch;
  818.     linesize[1] = bitmap->pitch;
  819.     linesize[2] = bitmap->pitch;
  820.     linesize[3] = bitmap->pitch;
  821.  
  822.     sws_scale(cvt_ctx, (const uint8_t* const *)picture->data,
  823.               picture->linesize, 0, render->ctx_height, data, linesize);
  824. //    printf("sws_scale\n");
  825.  
  826.     if(render->win->win_state == FULLSCREEN)
  827.         blit_bitmap(bitmap,render->rcvideo.l,render->rcvideo.t,
  828.                  render->rcvideo.r, render->rcvideo.b);
  829.     else
  830.         blit_bitmap(bitmap, render->rcvideo.l,
  831.                  CAPTION_HEIGHT+render->rcvideo.t,
  832.                  render->rcvideo.r, render->rcvideo.b);
  833.    
  834.     render->last_bitmap = bitmap;
  835. //    printf("blit_bitmap\n");
  836.  
  837.  
  838.     render->target++;
  839.     render->target&= 1;
  840. }
  841.  
  842. void draw_sw_picture(render_t *render, AVPicture *picture)
  843. {
  844.     uint8_t     *data[4];
  845.     int      linesize[4];
  846.  
  847.     if(render->win->win_state == MINIMIZED ||
  848.        render->win->win_state == ROLLED)
  849.         return;
  850.  
  851.     cvt_ctx = sws_getCachedContext(cvt_ctx,
  852.               render->ctx_width, render->ctx_height,
  853.               render->ctx_format,
  854.               render->rcvideo.r, render->rcvideo.b,
  855.               PIX_FMT_BGRA, SWS_FAST_BILINEAR, NULL, NULL, NULL);
  856.     if(cvt_ctx == NULL)
  857.     {
  858.         printf("Cannot initialize the conversion context!\n");
  859.         return ;
  860.     }
  861.  
  862.     lock_bitmap(&render->bitmap[0]);
  863.  
  864.     data[0] = render->bitmap[0].data;
  865.     data[1] = render->bitmap[0].data+1;
  866.     data[2] = render->bitmap[0].data+2;
  867.     data[3] = render->bitmap[0].data+3;
  868.  
  869.  
  870.     linesize[0] = render->bitmap[0].pitch;
  871.     linesize[1] = render->bitmap[0].pitch;
  872.     linesize[2] = render->bitmap[0].pitch;
  873.     linesize[3] = render->bitmap[0].pitch;
  874.  
  875.     sws_scale(cvt_ctx, (const uint8_t* const *)picture->data,
  876.               picture->linesize, 0, render->ctx_height, data, linesize);
  877.  
  878.     if(render->win->win_state == FULLSCREEN)
  879.         blit_bitmap(&render->bitmap[0],render->rcvideo.l,render->rcvideo.t,
  880.                  render->rcvideo.r, render->rcvideo.b);
  881.     else
  882.         blit_bitmap(&render->bitmap[0], render->rcvideo.l,
  883.                  CAPTION_HEIGHT+render->rcvideo.t,
  884.                  render->rcvideo.r, render->rcvideo.b);
  885.                
  886.     render->last_bitmap = &render->bitmap[0];
  887. }
  888.  
  889. void render_draw_client(render_t *render)
  890. {
  891.     int y;
  892.    
  893.     if(render->win_state == MINIMIZED ||
  894.        render->win_state == ROLLED )
  895.         return;
  896.     if(render->win_state == FULLSCREEN)
  897.         y = 0;
  898.     else
  899.         y = CAPTION_HEIGHT;
  900.            
  901.     if(player_state == PAUSE)
  902.     {
  903.          if(frames[vfx].ready == 1 )
  904.             main_render->draw(main_render, &frames[vfx].picture);
  905.          else
  906.             draw_bar(0, y, render->win_width,
  907.                  render->rcvideo.b, 0);
  908.     }
  909.     else if( player_state == STOP )
  910.     {
  911.         draw_bar(0,y, render->win_width,
  912.                  render->rcvideo.b, 0);
  913.     };
  914.  
  915.     if(render->layout & HAS_TOP)
  916.         draw_bar(0, y, render->win_width,
  917.                  render->rctop.b, 0);
  918.     if(render->layout & HAS_LEFT)
  919.         draw_bar(0, render->rcvideo.t+y, render->rcleft.r,
  920.                  render->rcvideo.b, 0);
  921.     if(render->layout & HAS_RIGHT)
  922.         draw_bar(render->rcright.l, render->rcvideo.t+y,
  923.                  render->rcright.r, render->rcvideo.b, 0);
  924.     if(render->layout & HAS_BOTTOM)
  925.         draw_bar(0, render->rcbottom.t+y,
  926.                  render->win_width, render->rcbottom.b, 0);
  927. }
  928.  
  929.  
  930.  
  931.  
  932.  
  933.