Subversion Repositories Kolibri OS

Rev

Rev 6136 | Blame | Compare with Previous | Last modification | View Log | 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 <math.h>
  8. #include <kos32sys.h>
  9. #include <sound.h>
  10.  
  11. #include "winlib/winlib.h"
  12. #include "fplay.h"
  13.  
  14. extern int res_pause_btn[];
  15. extern int res_pause_btn_pressed[];
  16.  
  17. extern int res_play_btn[];
  18. extern int res_play_btn_pressed[];
  19.  
  20. extern int64_t stream_duration;
  21. extern volatile int sound_level_0;
  22. extern volatile int sound_level_1;
  23.  
  24. struct SwsContext *cvt_ctx = NULL;
  25.  
  26. render_t   *main_render;
  27.  
  28. void get_client_rect(rect_t *rc);
  29. void run_render(window_t *win, void *render);
  30. void window_update_layout(window_t *win);
  31. int  fini_winlib();
  32.  
  33. void flush_video(vst_t *vst)
  34. {
  35.     vframe_t *vframe, *tmp;
  36.  
  37.     mutex_lock(&vst->output_lock);
  38.     mutex_lock(&vst->input_lock);
  39.  
  40.     list_for_each_entry_safe(vframe, tmp, &vst->output_list, list)
  41.         list_move_tail(&vframe->list, &vst->input_list);
  42.  
  43.     list_for_each_entry(vframe, &vst->input_list, list)
  44.     {
  45.         vframe->pts   = 0;
  46.         vframe->ready = 0;
  47.     }
  48.     vst->frames_count = 0;
  49.  
  50.     mutex_unlock(&vst->input_lock);
  51.     mutex_unlock(&vst->output_lock);
  52. };
  53.  
  54.  
  55.  
  56. extern volatile enum player_state player_state;
  57. extern volatile enum player_state decoder_state;
  58. extern volatile enum player_state sound_state;
  59.  
  60. extern int64_t rewind_pos;
  61.  
  62. static void player_stop()
  63. {
  64.     window_t  *win;
  65.  
  66.     win = main_render->win;
  67.  
  68.     rewind_pos = 0;
  69.  
  70.     win->panel.play_btn->img_default    = res_play_btn;
  71.     win->panel.play_btn->img_hilite     = res_play_btn;
  72.     win->panel.play_btn->img_pressed    = res_play_btn_pressed;
  73.     win->panel.prg->current             = rewind_pos;
  74.  
  75.     send_message(&win->panel.ctrl, MSG_PAINT, 0, 0);
  76.     player_state = STOP;
  77.     decoder_state = PLAY_2_STOP;
  78.     sound_state = PLAY_2_STOP;
  79.     render_draw_client(main_render);
  80. };
  81.  
  82. int MainWindowProc(ctrl_t *ctrl, uint32_t msg, uint32_t arg1, uint32_t arg2)
  83. {
  84.     window_t  *win = (window_t*)ctrl;
  85.     static int spc_down = 0;
  86.     static int ent_down = 0;
  87.  
  88.     switch(msg)
  89.     {
  90.         case MSG_SIZE:
  91.             if(main_render)
  92.             {
  93.                 render_adjust_size(main_render, win);
  94.                 render_draw_client(main_render);
  95.             };
  96.             break;
  97.  
  98.         case MSG_KEY:
  99.             switch((short)arg2)
  100.             {
  101.                 case 0x39:
  102.                     if(spc_down == 0)
  103.                     {
  104.                         spc_down = 1;
  105.                         send_message(win, MSG_LBTNDOWN, 0, 0);
  106.                     }
  107.                     break;
  108.  
  109.                 case 0xB9:
  110.                     spc_down = 0;
  111.                     break;
  112.  
  113.                 case 0x1C:
  114.                     if(ent_down == 0)
  115.                     {
  116.                         int screensize;
  117.                         if(win->win_state == NORMAL)
  118.                         {
  119.                             win->saved = win->rc;
  120.                             win->saved_state = win->win_state;
  121.  
  122.                             screensize = GetScreenSize();
  123.                             __asm__ __volatile__(
  124.                             "int $0x40"
  125.                             ::"a"(67), "b"(0), "c"(0),
  126.                             "d"((screensize >> 16)-1),"S"((screensize & 0xFFFF)-1) );
  127.                             win->win_state = FULLSCREEN;
  128.                             window_update_layout(win);
  129.                         }
  130.                         else if(win->win_state == FULLSCREEN)
  131.                         {
  132.                             __asm__ __volatile__(
  133.                             "int $0x40"
  134.                             ::"a"(67), "b"(win->saved.l), "c"(win->saved.t),
  135.                             "d"(win->saved.r-win->saved.l-1),"S"(win->saved.b-win->saved.t-1));
  136.                             win->win_state = win->saved_state;
  137.                             window_update_layout(win);
  138. //                            if(win->saved_state == MAXIMIZED)
  139. //                            {
  140. //                                blit_caption(&win->caption);
  141. //                                blit_panel(&win->panel);
  142. //                            }
  143.                         }
  144.                         ent_down = 1;
  145.                     };
  146.                     break;
  147.  
  148.                 case 0x9C:
  149.                     ent_down = 0;
  150.                     break;
  151.             };
  152.  
  153.         case MSG_DRAW_CLIENT:
  154.             if(main_render)
  155.             {
  156.                 render_draw_client(main_render);
  157.             };
  158.             break;
  159.  
  160.         case MSG_LBTNDOWN:
  161.  
  162.             if(player_state == PAUSE)
  163.             {
  164.                 win->panel.play_btn->img_default = res_pause_btn;
  165.                 win->panel.play_btn->img_hilite  = res_pause_btn;
  166.                 win->panel.play_btn->img_pressed = res_pause_btn_pressed;
  167.                 send_message(&win->panel.play_btn->ctrl, MSG_PAINT, 0, 0);
  168.                 player_state = PLAY;
  169.                 sound_state  = PAUSE_2_PLAY;
  170.  
  171.             }
  172.             else if(player_state == PLAY)
  173.             {
  174.                 win->panel.play_btn->img_default = res_play_btn;
  175.                 win->panel.play_btn->img_hilite  = res_play_btn;
  176.                 win->panel.play_btn->img_pressed = res_play_btn_pressed;
  177.                 send_message(&win->panel.play_btn->ctrl, MSG_PAINT, 0, 0);
  178.                 player_state = PAUSE;
  179.                 sound_state  = PLAY_2_PAUSE;
  180.             }
  181.             break;
  182.  
  183.         case MSG_COMMAND:
  184.             switch((short)arg1)
  185.             {
  186.                 case ID_PLAY:
  187.                     if(player_state == PAUSE)
  188.                     {
  189.                         win->panel.play_btn->img_default  = res_pause_btn;
  190.                         win->panel.play_btn->img_hilite   = res_pause_btn;
  191.                         win->panel.play_btn->img_pressed = res_pause_btn_pressed;
  192.                         player_state = PLAY;
  193.                         sound_state = PAUSE_2_PLAY;
  194.                     }
  195.                     else if(player_state == PLAY)
  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.                         player_state = PAUSE;
  201.                         sound_state  = PLAY_2_PAUSE;
  202.                     }
  203.                     else if(player_state == STOP)
  204.                     {
  205.                         win->panel.play_btn->img_default  = res_pause_btn;
  206.                         win->panel.play_btn->img_hilite   = res_pause_btn;
  207.                         win->panel.play_btn->img_pressed = res_pause_btn_pressed;
  208.                         rewind_pos = 0;
  209.                         send_message(&win->panel.ctrl, MSG_PAINT, 0, 0);
  210.                         player_state = PLAY;
  211.                         decoder_state = PREPARE;
  212.                     }
  213.                     break;
  214.  
  215.                 case ID_STOP:
  216.                     player_stop();
  217.                     break;
  218.  
  219.                 case ID_PROGRESS:
  220.                     if(player_state != REWIND)
  221.                     {
  222.                         progress_t *prg = (progress_t*)arg2;
  223.  
  224.                         rewind_pos = (prg->max - prg->min)*prg->pos/prg->ctrl.w;
  225.  
  226.                         player_state  = REWIND;
  227.                         decoder_state = REWIND;
  228.                         sound_state   = PLAY_2_STOP;
  229.                         if(rewind_pos < prg->current)
  230.                         {
  231.                             prg->current  = rewind_pos;
  232.                             rewind_pos = -rewind_pos;
  233.                         }
  234.                         else
  235.                             prg->current  = rewind_pos;
  236.  
  237.                         win->panel.play_btn->img_default  = res_pause_btn;
  238.                         win->panel.play_btn->img_hilite   = res_pause_btn;
  239.                         win->panel.play_btn->img_pressed  = res_pause_btn_pressed;
  240.                         send_message(&prg->ctrl, MSG_PAINT, 0, 0);
  241.                     };
  242.                     break;
  243.  
  244.                 case ID_VOL_CTRL:
  245.                 {
  246.                     slider_t *sld = (slider_t*)arg2;
  247.                     int      peak;
  248.                     int      level;
  249.  
  250.                     peak = sld->min + sld->pos * (sld->max - sld->min)/(96);
  251.                     level =  peak;
  252.  
  253.                     set_audio_volume(level, level);
  254.                     send_message(&sld->ctrl, MSG_PAINT, 0, 0);
  255.                     win->panel.lvl->vol = level;
  256.                 }
  257.  
  258.                 default:
  259.                     break;
  260.             }
  261.             break;
  262.  
  263.         default:
  264.             def_window_proc(ctrl,msg,arg1,arg2);
  265.     };
  266.     return 0;
  267. };
  268.  
  269. void render_time(render_t *render)
  270. {
  271.     progress_t *prg = main_render->win->panel.prg;
  272.     level_t    *lvl = main_render->win->panel.lvl;
  273.     vst_t      *vst = main_render->vst;
  274.     double      ctime;            /*    milliseconds    */
  275.     double      fdelay;           /*    milliseconds    */
  276.  
  277.     if(player_state == CLOSED)
  278.     {
  279.         render->win->win_command = WIN_CLOSED;
  280.         return;
  281.     }
  282.     else if((player_state == PAUSE) || (player_state == REWIND))
  283.     {
  284.         delay(1);
  285.         return;
  286.     }
  287.     else if (decoder_state == STOP && vst->frames_count  == 0 &&
  288.               player_state  != STOP)
  289.     {
  290.         player_stop();
  291.     }
  292.     else if(player_state != PLAY)
  293.     {
  294.         delay(1);
  295.         return;
  296.     };
  297.  
  298.     mutex_lock(&vst->output_lock);
  299.     if(list_empty(&vst->output_list))
  300.     {
  301.         mutex_unlock(&vst->output_lock);
  302.         delay(1);
  303.     }
  304.     else
  305.     {
  306.         vframe_t *vframe;
  307.         int sys_time;
  308.  
  309.         vframe = list_first_entry(&vst->output_list, vframe_t, list);
  310.         list_del(&vframe->list);
  311.         vst->frames_count--;
  312.         mutex_unlock(&vst->output_lock);
  313.  
  314.         ctime = get_master_clock();
  315.         fdelay = (vframe->pts - ctime);
  316.  
  317.         if(fdelay > 15.0)
  318.         {
  319.             delay((int)fdelay/10);
  320.         };
  321.  
  322. //        printf("output index: %d pts: %f pkt_pts %f pkt_dts %f\n",
  323. //               vframe->index,vframe->pts,vframe->pkt_pts,vframe->pkt_dts);
  324.  
  325.         main_render->draw(main_render, vframe);
  326.  
  327.         if(main_render->win->win_state != FULLSCREEN)
  328.         {
  329.             prg->current = vframe->pts * 1000;
  330.             lvl->current = vframe->index & 1 ? sound_level_1 : sound_level_0;
  331.  
  332.             send_message(&prg->ctrl, PRG_PROGRESS, 0, 0);
  333.  
  334.             if(main_render->win->panel.layout)
  335.                 send_message(&lvl->ctrl, MSG_PAINT, 0, 0);
  336.         }
  337.  
  338.         vframe->ready = 0;
  339.  
  340.         mutex_lock(&vst->input_lock);
  341.         list_add_tail(&vframe->list, &vst->input_list);
  342.         mutex_unlock(&vst->input_lock);
  343.     }
  344. }
  345.  
  346. int video_thread(void *param)
  347. {
  348.     vst_t *vst = param;
  349.     window_t  *MainWindow;
  350.  
  351.     init_winlib();
  352.  
  353.     MainWindow = create_window(vst->input_name,0,
  354.                                10,10,vst->vCtx->width,vst->vCtx->height+CAPTION_HEIGHT+PANEL_HEIGHT,MainWindowProc);
  355.  
  356.     MainWindow->panel.prg->max = stream_duration;
  357.  
  358.     show_window(MainWindow, NORMAL);
  359.  
  360.     main_render = create_render(vst, MainWindow, HW_TEX_BLIT|HW_BIT_BLIT);
  361.     if( main_render == NULL)
  362.     {
  363.         mutex_unlock(&vst->decoder_lock);
  364.         printf("Cannot create render\n\r");
  365.         return 0;
  366.     };
  367.  
  368.     __sync_or_and_fetch(&threads_running,VIDEO_THREAD);
  369.  
  370.     render_draw_client(main_render);
  371.     player_state = PLAY;
  372.  
  373.     mutex_unlock(&vst->decoder_lock);
  374.  
  375.     run_render(MainWindow, main_render);
  376.  
  377.     __sync_and_and_fetch(&threads_running,~VIDEO_THREAD);
  378.  
  379.     {
  380.         vframe_t *vframe, *tmp;
  381.         flush_video(vst);
  382.  
  383.         list_for_each_entry_safe(vframe, tmp, &vst->output_list, list)
  384.         {
  385.             list_del(&vframe->list);
  386.             if(vframe->planar != NULL)
  387.                 pxDestroyPlanar(vframe->planar);
  388.         }
  389.     }
  390.  
  391.     destroy_render(main_render);
  392.     fini_winlib();
  393.     player_state = CLOSED;
  394.     return 0;
  395. };
  396.  
  397.  
  398. void draw_hw_picture(render_t *render, vframe_t *vframe);
  399. void draw_sw_picture(render_t *render, vframe_t *vframe);
  400.  
  401. render_t *create_render(vst_t *vst, window_t *win, uint32_t flags)
  402. {
  403.     render_t *render;
  404.  
  405.     uint32_t right, bottom, draw_w, draw_h;
  406.     uint32_t s, sw, sh;
  407.     uint8_t  state;
  408.  
  409. //    __asm__ __volatile__("int3");
  410.  
  411.     render = (render_t*)malloc(sizeof(render_t));
  412.     memset(render, 0, sizeof(render_t));
  413.  
  414.     render->vst = vst;
  415.     render->win = win;
  416.  
  417.     render->ctx_width  = vst->vCtx->width;
  418.     render->ctx_height = vst->vCtx->height;
  419.     render->ctx_format = vst->vCtx->pix_fmt;
  420.  
  421.     render->caps = pxInit(1);
  422.  
  423.     right  = win->w;
  424.     bottom = win->h-CAPTION_HEIGHT-PANEL_HEIGHT;
  425.  
  426.     printf("window width %d height %d\n",
  427.                     right, bottom);
  428.  
  429.     render->win_state  = win->win_state;
  430.  
  431.     draw_w = bottom*render->ctx_width/render->ctx_height;
  432.     draw_h = right*render->ctx_height/render->ctx_width;
  433.  
  434.     if(draw_w > right)
  435.     {
  436.         draw_w = right;
  437.         draw_h = right*render->ctx_height/render->ctx_width;
  438.     };
  439.  
  440.     if(draw_h > bottom)
  441.     {
  442.         draw_h = bottom;
  443.         draw_w = bottom*render->ctx_width/render->ctx_height;
  444.     };
  445.  
  446.     render->win_width  = win->w;
  447.     render->win_height = win->h-CAPTION_HEIGHT-PANEL_HEIGHT;
  448.  
  449.     render_set_size(render, draw_w, draw_h);
  450.  
  451.     pxCreateClient(0, CAPTION_HEIGHT, right, bottom);
  452.  
  453.     if(render->caps==0)
  454.     {
  455.         render->bitmap[0] = pxCreateBitmap(draw_w, draw_h);
  456.         if(render->bitmap[0] == NULL)
  457.         {
  458.             free(render);
  459.             return NULL;
  460.         }
  461.         render->draw = draw_sw_picture;
  462.     }
  463.     else
  464.     {
  465.         int width, height;
  466.         int i;
  467.  
  468.         if(render->caps & HW_TEX_BLIT)
  469.         {
  470.             width  = render->ctx_width;
  471.             height = render->ctx_height;
  472.         }
  473.         else
  474.         {
  475.             width  = draw_w;
  476.             height = draw_h;;
  477.         }
  478.  
  479.         for( i=0; i < 2; i++)
  480.         {
  481.             render->bitmap[i] = pxCreateBitmap(width, height);
  482.             if( render->bitmap[i] == NULL )
  483.             {
  484.                 player_state = CLOSED;
  485.                 free(render);
  486.                 return NULL;
  487.             };
  488.         }
  489.  
  490.         render->state = INIT;
  491.         render->target = 0;
  492.         render->draw   = draw_hw_picture;
  493.     };
  494.  
  495.     printf("FPlay %s render engine: context %dx%d picture %dx%d\n",
  496.            render->caps & HW_TEX_BLIT ? "hw_tex_blit":
  497.            render->caps & HW_BIT_BLIT ? "hw_bit_blit":"software",
  498.            render->ctx_width, render->ctx_height,
  499.            draw_w, draw_h);
  500.  
  501.     return render;
  502. };
  503.  
  504. void destroy_render(render_t *render)
  505. {
  506.  
  507.     pxDestroyBitmap(render->bitmap[0]);
  508.  
  509.     if(render->caps & (HW_BIT_BLIT|HW_TEX_BLIT))          /* hw blitter */
  510.         pxDestroyBitmap(render->bitmap[1]);
  511.  
  512.     pxFini();
  513. };
  514.  
  515. void render_set_size(render_t *render, int width, int height)
  516. {
  517.     int i;
  518.  
  519.     render->layout = 0;
  520.     render->rcvideo.l = 0;
  521.     render->rcvideo.t = 0;
  522.     render->rcvideo.r = width;
  523.     render->rcvideo.b = height;
  524.  
  525. //    printf("render width %d height %d\n",width, height);
  526.  
  527.     if( render->win_height > height )
  528.     {
  529.         int yoffs;
  530.         yoffs = (render->win_height-height)/2;
  531.         if(yoffs)
  532.         {
  533.             render->rctop.t = 0;
  534.             render->rctop.b = yoffs;
  535.             render->rcvideo.t  = yoffs;
  536.             render->layout |= HAS_TOP;
  537.         }
  538.  
  539.         yoffs = render->win_height-(render->rcvideo.t+render->rcvideo.b);
  540.         if(yoffs)
  541.         {
  542.             render->rcbottom.t = render->rcvideo.t+render->rcvideo.b;
  543.             render->rcbottom.b = yoffs;
  544.             render->layout |= HAS_BOTTOM;
  545.         }
  546.     }
  547.  
  548.     if( render->win_width > width )
  549.     {
  550.         int xoffs;
  551.         xoffs = (render->win_width-width)/2;
  552.         if(xoffs)
  553.         {
  554.             render->rcleft.r  = xoffs;
  555.             render->rcvideo.l = xoffs;
  556.             render->layout |= HAS_LEFT;
  557.         }
  558.         xoffs = render->win_width-(render->rcvideo.l+render->rcvideo.r);
  559.         if(xoffs)
  560.         {
  561.             render->rcright.l = render->rcvideo.l+render->rcvideo.r;
  562.             render->rcright.r = xoffs;
  563.             render->layout |= HAS_RIGHT;
  564.         }
  565.     };
  566. };
  567.  
  568. void render_adjust_size(render_t *render, window_t *win)
  569. {
  570.     uint32_t right, bottom, new_w, new_h;
  571.     uint32_t s, sw, sh;
  572.     uint8_t  state;
  573.  
  574.     right  = win->w;
  575.     bottom = win->h;
  576.  
  577.     if(win->win_state != FULLSCREEN)
  578.         bottom-= CAPTION_HEIGHT+PANEL_HEIGHT;
  579.  
  580.  //   printf("window width %d height %d\n",
  581.  //                   right, bottom);
  582.  
  583.     render->win_state  = win->win_state;
  584.  
  585.     if(render->win_state == MINIMIZED)
  586.         return;
  587.  
  588.     if(render->win_state == ROLLED)
  589.         return;
  590.  
  591.     if( right  == render->win_width &&
  592.         bottom == render->win_height)
  593.         return;
  594.  
  595. //    printf("%s r: %d b: %d\n", __FUNCTION__, right, bottom);
  596.  
  597.     new_w = bottom*render->ctx_width/render->ctx_height;
  598.     new_h = right*render->ctx_height/render->ctx_width;
  599.  
  600.     if(new_w > right)
  601.     {
  602.         new_w = right;
  603.         new_h = right*render->ctx_height/render->ctx_width;
  604.     };
  605.     if(new_h > bottom)
  606.     {
  607.         new_h = bottom;
  608.         new_w = bottom*render->ctx_width/render->ctx_height;
  609.     };
  610.  
  611.     render->win_width  = right;
  612.     render->win_height = bottom;
  613.     render_set_size(render, new_w, new_h);
  614.  
  615.     if(render->caps & HW_TEX_BLIT)          /*  hw scaler  */
  616.     {
  617.         if(render->win->win_state == FULLSCREEN)
  618.             pxResizeClient(render->rcvideo.l, render->rcvideo.t, new_w, new_h);
  619.         else
  620.             pxResizeClient(render->rcvideo.l, render->rcvideo.t+CAPTION_HEIGHT, new_w, new_h);
  621.  
  622.         return;
  623.     };
  624.  
  625.     pxResizeBitmap(render->bitmap[0], new_w, new_h);
  626.  
  627.     if(render->caps & HW_BIT_BLIT)          /* hw blitter */
  628.         pxResizeBitmap(render->bitmap[1], new_w, new_h);
  629.  
  630.     return;
  631. };
  632.  
  633. static void render_hw_planar(render_t *render, vframe_t *vframe)
  634. {
  635.     vst_t *vst = render->vst;
  636.     planar_t *planar = vframe->planar;
  637.  
  638.     if(vframe->is_hw_pic != 0 && vframe->format != AV_PIX_FMT_NONE)
  639.     {
  640.         mutex_lock(&render->vst->gpu_lock);
  641.  
  642.         pxBlitPlanar(planar, render->rcvideo.l,
  643.                     CAPTION_HEIGHT+render->rcvideo.t,
  644.                     render->rcvideo.r, render->rcvideo.b,0,0);
  645.         mutex_unlock(&render->vst->gpu_lock);
  646.     }
  647. };
  648.  
  649. void draw_hw_picture(render_t *render, vframe_t *vframe)
  650. {
  651.     AVPicture *picture;
  652.     int       dst_width;
  653.     int       dst_height;
  654.     bitmap_t *bitmap;
  655.     uint8_t  *bitmap_data;
  656.     uint32_t  bitmap_pitch;
  657.     uint8_t  *data[4];
  658.     int       linesize[4];
  659.     enum AVPixelFormat format;
  660.  
  661.     vst_t *vst = render->vst;
  662.  
  663.     if(render->win->win_state == MINIMIZED ||
  664.        render->win->win_state == ROLLED)
  665.         return;
  666.  
  667.     if(render->caps & HW_TEX_BLIT)
  668.     {
  669.         dst_width  = render->ctx_width;
  670.         dst_height = render->ctx_height;
  671.     }
  672.     else
  673.     {
  674.         dst_width  = render->rcvideo.r;
  675.         dst_height = render->rcvideo.b;
  676.     };
  677.  
  678.     if(vframe->is_hw_pic)
  679.     {
  680.         render_hw_planar(render, vframe);
  681.         return;
  682.     };
  683.  
  684.     picture = &vframe->picture;
  685.  
  686.     format = render->ctx_format;
  687.     cvt_ctx = sws_getCachedContext(cvt_ctx, render->ctx_width, render->ctx_height, format,
  688.                                    dst_width, dst_height, AV_PIX_FMT_BGRA,
  689.                                    SWS_FAST_BILINEAR, NULL, NULL, NULL);
  690.     if(cvt_ctx == NULL)
  691.     {
  692.         printf("Cannot initialize the conversion context!\n");
  693.         return ;
  694.     };
  695.  
  696.     bitmap = render->bitmap[render->target];
  697.  
  698.     bitmap_data = pxLockBitmap(bitmap, &bitmap_pitch);
  699.     if( bitmap_data == NULL)
  700.     {
  701.         printf("Cannot lock bitmap!\n");
  702.         return ;
  703.     }
  704.  
  705.     data[0] = bitmap_data;
  706.     data[1] = bitmap_data+1;
  707.     data[2] = bitmap_data+2;
  708.     data[3] = bitmap_data+3;
  709.  
  710.     linesize[0] = bitmap_pitch;
  711.     linesize[1] = bitmap_pitch;
  712.     linesize[2] = bitmap_pitch;
  713.     linesize[3] = bitmap_pitch;
  714.  
  715.     sws_scale(cvt_ctx, (const uint8_t* const *)picture->data,
  716.               picture->linesize, 0, render->ctx_height, data, linesize);
  717. //    printf("sws_scale\n");
  718.  
  719.     mutex_lock(&render->vst->gpu_lock);
  720.  
  721.     if(render->caps & HW_TEX_BLIT)
  722.     {
  723.  
  724.         if(render->win->win_state == FULLSCREEN)
  725.             pxBlitBitmap(bitmap,render->rcvideo.l,render->rcvideo.t,
  726.                  render->rcvideo.r, render->rcvideo.b,0,0);
  727.         else
  728.             pxBlitBitmap(bitmap, render->rcvideo.l,
  729.                     CAPTION_HEIGHT+render->rcvideo.t,
  730.                     render->rcvideo.r, render->rcvideo.b,0,0);
  731.     }
  732.     else
  733.     {
  734.         if(render->win->win_state == FULLSCREEN)
  735.             pxBlitBitmap(bitmap,render->rcvideo.l,render->rcvideo.t,
  736.                     render->rcvideo.r, render->rcvideo.b, 0,0);
  737.         else
  738.             pxBlitBitmap(bitmap, render->rcvideo.l,
  739.                     CAPTION_HEIGHT+render->rcvideo.t,
  740.                     render->rcvideo.r, render->rcvideo.b, 0, 0);
  741.     };
  742.     mutex_unlock(&render->vst->gpu_lock);
  743.  
  744.     render->last_bitmap = bitmap;
  745.     render->target++;
  746.     render->target&= 1;
  747. }
  748.  
  749. void draw_sw_picture(render_t *render, vframe_t *vframe)
  750. {
  751.     AVPicture *picture;
  752.     uint8_t  *bitmap_data;
  753.     uint32_t  bitmap_pitch;
  754.     uint8_t  *data[4];
  755.     int      linesize[4];
  756.  
  757.     if(render->win->win_state == MINIMIZED ||
  758.        render->win->win_state == ROLLED)
  759.         return;
  760.  
  761.     picture = &vframe->picture;
  762.  
  763.     cvt_ctx = sws_getCachedContext(cvt_ctx,
  764.               render->ctx_width, render->ctx_height,
  765.               render->ctx_format,
  766.               render->rcvideo.r, render->rcvideo.b,
  767.               AV_PIX_FMT_BGRA, SWS_FAST_BILINEAR, NULL, NULL, NULL);
  768.     if(cvt_ctx == NULL)
  769.     {
  770.         printf("Cannot initialize the conversion context!\n");
  771.         return ;
  772.     }
  773.  
  774.     bitmap_data = pxLockBitmap(render->bitmap[0],&bitmap_pitch);
  775.  
  776.     data[0] = bitmap_data;
  777.     data[1] = bitmap_data+1;
  778.     data[2] = bitmap_data+2;
  779.     data[3] = bitmap_data+3;
  780.  
  781.     linesize[0] = bitmap_pitch;
  782.     linesize[1] = bitmap_pitch;
  783.     linesize[2] = bitmap_pitch;
  784.     linesize[3] = bitmap_pitch;
  785.  
  786.      sws_scale(cvt_ctx, (const uint8_t* const *)picture->data,
  787.               picture->linesize, 0, render->ctx_height, data, linesize);
  788.  
  789.     if(render->win->win_state == FULLSCREEN)
  790.         pxBlitBitmap(render->bitmap[0],render->rcvideo.l,render->rcvideo.t,
  791.                  render->rcvideo.r, render->rcvideo.b,0,0);
  792.     else
  793.         pxBlitBitmap(render->bitmap[0], render->rcvideo.l,
  794.                  CAPTION_HEIGHT+render->rcvideo.t,
  795.                  render->rcvideo.r, render->rcvideo.b,0,0);
  796.  
  797.     render->last_bitmap = render->bitmap[0];
  798. }
  799.  
  800. void render_draw_client(render_t *render)
  801. {
  802.     vst_t *vst = render->vst;
  803.     int y;
  804.  
  805.     if(render->win_state == MINIMIZED ||
  806.        render->win_state == ROLLED )
  807.         return;
  808.     if(render->win_state == FULLSCREEN)
  809.         y = 0;
  810.     else
  811.         y = CAPTION_HEIGHT;
  812.  
  813.     if(player_state == PAUSE)
  814.     {
  815. //         if(vst->vframe[vst->vfx].ready == 1 )
  816. //            main_render->draw(main_render, &vst->vframe[vst->vfx].picture);
  817. //         else
  818.             draw_bar(0, y, render->win_width,
  819.                  render->rcvideo.b, 0);
  820.     }
  821.     else if( player_state == STOP )
  822.     {
  823.         draw_bar(0,y, render->win_width,
  824.                  render->rcvideo.b, 0);
  825.     };
  826.  
  827.     if(render->layout & HAS_TOP)
  828.         draw_bar(0, y, render->win_width,
  829.                  render->rctop.b, 0);
  830.     if(render->layout & HAS_LEFT)
  831.         draw_bar(0, render->rcvideo.t+y, render->rcleft.r,
  832.                  render->rcvideo.b, 0);
  833.     if(render->layout & HAS_RIGHT)
  834.         draw_bar(render->rcright.l, render->rcvideo.t+y,
  835.                  render->rcright.r, render->rcvideo.b, 0);
  836.     if(render->layout & HAS_BOTTOM)
  837.         draw_bar(0, render->rcbottom.t+y,
  838.                  render->win_width, render->rcbottom.b, 0);
  839. }
  840.  
  841.  
  842.