Subversion Repositories Kolibri OS

Rev

Rev 2693 | Blame | Last modification | View Log | Download | RSS feed

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