Subversion Repositories Kolibri OS

Rev

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