Subversion Repositories Kolibri OS

Rev

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