diff --git a/contrib/media/fplay/fplay.c b/contrib/media/fplay/fplay.c index 0dc7038088..9ba9ee4de9 100644 --- a/contrib/media/fplay/fplay.c +++ b/contrib/media/fplay/fplay.c @@ -16,14 +16,16 @@ #include "sound.h" #include "fplay.h" +#ifdef HAVE_VAAPI +int va_check_codec_support(enum AVCodecID id); +#endif + volatile enum player_state player_state = STOP; volatile enum player_state decoder_state = PREPARE; volatile enum player_state sound_state = STOP; uint32_t win_width, win_height; -void decoder(); -int fplay_init_context(AVCodecContext *avctx); AVFrame *pFrame; @@ -35,7 +37,7 @@ extern int resampler_size; extern int sample_rate; char *movie_file; -void flush_video(); +void flush_video(vst_t* vst); int64_t rewind_pos; @@ -78,6 +80,10 @@ int main( int argc, char *argv[]) avdevice_register_all(); av_register_all(); +#ifdef HAVE_VAAPI + fplay_vaapi_init(); +#endif + if( avformat_open_input(&vst.fCtx, movie_file, NULL, NULL) < 0) { printf("Cannot open file %s\n\r", movie_file); @@ -152,8 +158,20 @@ int main( int argc, char *argv[]) return -1; // Codec not found } +#ifdef HAVE_VAAPI + int hwdec = va_check_codec_support(vst.vCtx->codec_id); + if(hwdec) + { + printf("hardware decode supported\n"); + if (fplay_init_context(&vst) < 0) + { + printf("context initialization failed\n"); + return -1; + }; + }; +#endif if(avcodec_open2(vst.vCtx, vst.vCodec, NULL) < 0) { @@ -298,7 +316,7 @@ static void flush_all(vst_t* vst) while( get_packet(&vst->q_audio, &packet)!= 0) av_free_packet(&packet); - flush_video(); + flush_video(vst); astream.count = 0; }; diff --git a/contrib/media/fplay/fplay.h b/contrib/media/fplay/fplay.h index 3fd778d38c..46fd015431 100644 --- a/contrib/media/fplay/fplay.h +++ b/contrib/media/fplay/fplay.h @@ -111,6 +111,9 @@ struct vstate mutex_t gpu_lock; /* gpu access lock. libdrm not yet thread safe :( */ + int vfx; /* index of decoded frame */ + int dfx; /* index of renderd frame */ + }; @@ -130,6 +133,7 @@ void render_adjust_size(render_t *render, window_t *win); void render_set_size(render_t *render, int width, int height); void render_draw_client(render_t *render); +int fplay_init_context(vst_t *vst); int init_audio(int format); int audio_thread(void *param); @@ -152,6 +156,8 @@ static inline void GetNotify(void *event) } int fplay_vaapi_init(void); +void va_convert_picture(vst_t *vst, int width, int height, AVPicture *pic); + int init_fontlib(); char *get_moviefile(); diff --git a/contrib/media/fplay/vaapi.c b/contrib/media/fplay/vaapi.c index 0a9fd1f64f..6347409785 100644 --- a/contrib/media/fplay/vaapi.c +++ b/contrib/media/fplay/vaapi.c @@ -13,8 +13,6 @@ #include "winlib/winlib.h" #include "fplay.h" -extern int dfx; - struct hw_profile { enum AVCodecID av_codec; @@ -224,9 +222,6 @@ int vaapi_init(VADisplay display) vaapi->display = display; vaapi->config_id = VA_INVALID_ID; vaapi->context_id = VA_INVALID_ID; -// vaapi->pic_param_buf_id = VA_INVALID_ID; -// vaapi->iq_matrix_buf_id = VA_INVALID_ID; -// vaapi->bitplane_buf_id = VA_INVALID_ID; v_context = vaapi; @@ -466,14 +461,11 @@ static void av_release_buffer(void *opaque, uint8_t *data) av_freep(&data); } - static int get_buffer2(AVCodecContext *avctx, AVFrame *pic, int flags) { - void *surface = (void *)(uintptr_t)v_surface_id[dfx]; + vst_t *vst = (vst_t*)avctx->opaque; + void *surface = (void *)(uintptr_t)v_surface_id[vst->dfx]; -// printf("%s surface %x\n", __FUNCTION__, surface); - -// pic->type= FF_BUFFER_TYPE_USER; pic->data[3] = surface; struct av_surface *avsurface; @@ -489,15 +481,15 @@ static int get_buffer2(AVCodecContext *avctx, AVFrame *pic, int flags) struct vaapi_context va_context_storage; -int fplay_init_context(AVCodecContext *avctx) +int fplay_init_context(vst_t *vst) { - ENTER(); + AVCodecContext *vCtx = vst->vCtx; - avctx->thread_count = 1; - avctx->get_format = get_format; - avctx->get_buffer2 = get_buffer2; + vCtx->opaque = vst; + vCtx->thread_count = 1; + vCtx->get_format = get_format; + vCtx->get_buffer2 = get_buffer2; - LEAVE(); return 0; } @@ -515,16 +507,7 @@ int fplay_vaapi_init(void) struct SwsContext *vacvt_ctx; - -void va_sync() -{ - struct vaapi_context* const vaapi = v_context; - - vaSyncSurface(vaapi->display,v_surface_id[dfx]); -}; - - -void va_convert_picture(int width, int height, AVPicture *pic) +void va_convert_picture(vst_t *vst, int width, int height, AVPicture *pic) { uint8_t *src_data[4]; int src_linesize[4]; @@ -533,10 +516,9 @@ void va_convert_picture(int width, int height, AVPicture *pic) uint8_t *vdata; struct vaapi_context* const vaapi = v_context; + vaSyncSurface(vaapi->display,v_surface_id[vst->dfx]); - va_sync(); - - status = vaDeriveImage(vaapi->display,v_surface_id[dfx],&vaimage); + status = vaDeriveImage(vaapi->display,v_surface_id[vst->dfx],&vaimage); if (!vaapi_check_status(status, "vaDeriveImage()")) { FAIL(); @@ -545,7 +527,7 @@ void va_convert_picture(int width, int height, AVPicture *pic) static int once = 2; - if(once && dfx == 0) + if(once && vst->dfx == 0) { VABufferInfo info = {0}; diff --git a/contrib/media/fplay/video.c b/contrib/media/fplay/video.c index fea9c67aa4..848efd9143 100644 --- a/contrib/media/fplay/video.c +++ b/contrib/media/fplay/video.c @@ -12,7 +12,6 @@ #include "fplay.h" int fplay_blit_bitmap(bitmap_t *bitmap, int dst_x, int dst_y,int w, int h); -void draw_va_picture(render_t *render, AVPicture *picture); extern int res_pause_btn[]; extern int res_pause_btn_pressed[]; @@ -36,8 +35,6 @@ volatile int frames_count = 0; struct SwsContext *cvt_ctx = NULL; -int vfx = 0; -int dfx = 0; render_t *main_render; @@ -49,7 +46,7 @@ AVFrame *Frame; void get_client_rect(rect_t *rc); -void flush_video() +void flush_video(vst_t *vst) { int i; @@ -58,16 +55,16 @@ void flush_video() frames[i].pts = 0; frames[i].ready = 0; }; + vst->vfx = 0; + vst->dfx = 0; frames_count = 0; - vfx = 0; - dfx = 0; }; int init_video(vst_t *vst) { int i; - width = vst->vCtx->width; + width = vst->vCtx->width; height = vst->vCtx->height; Frame = av_frame_alloc(); @@ -106,7 +103,7 @@ int decode_video(vst_t* vst) int frameFinished; double current_clock; - if(frames[dfx].ready != 0 ) + if(frames[vst->dfx].ready != 0 ) return -1; if( get_packet(&vst->q_video, &pkt) == 0 ) @@ -145,24 +142,23 @@ int decode_video(vst_t* vst) Frame->reordered_opaque != AV_NOPTS_VALUE) pts = Frame->reordered_opaque; else if(pkt.dts != AV_NOPTS_VALUE) - pts= pkt.dts; + pts = pkt.dts; else - pts= 0; + pts = 0; pts *= av_q2d(video_time_base); - dst_pic = &frames[dfx].picture; + dst_pic = &frames[vst->dfx].picture; av_image_copy(dst_pic->data, dst_pic->linesize, (const uint8_t**)Frame->data, Frame->linesize, vst->vCtx->pix_fmt, vst->vCtx->width, vst->vCtx->height); - frames[dfx].pts = pts*1000.0; + frames[vst->dfx].pts = pts*1000.0; - frames[dfx].ready = 1; + frames[vst->dfx].ready = 1; - dfx++; - dfx&= 3; + vst->dfx = (vst->dfx + 1) & 3; frames_count++; }; mutex_unlock(&vst->gpu_lock); @@ -390,9 +386,9 @@ int MainWindowProc(ctrl_t *ctrl, uint32_t msg, uint32_t arg1, uint32_t arg2) void render_time(render_t *render) { - progress_t *prg = main_render->win->panel.prg; - level_t *lvl = main_render->win->panel.lvl; - + progress_t *prg = main_render->win->panel.prg; + level_t *lvl = main_render->win->panel.lvl; + vst_t *vst = main_render->vst; double ctime; /* milliseconds */ double fdelay; /* milliseconds */ @@ -421,12 +417,12 @@ void render_time(render_t *render) #ifdef VERSION_A - if(frames[vfx].ready == 1 ) + if(frames[vst->vfx].ready == 1 ) { int sys_time; ctime = get_master_clock(); - fdelay = (frames[vfx].pts - ctime); + fdelay = (frames[vst->vfx].pts - ctime); // printf("pts %f time %f delay %f\n", // frames[vfx].pts, ctime, fdelay); @@ -438,7 +434,7 @@ void render_time(render_t *render) }; #if 0 ctime = get_master_clock(); - fdelay = (frames[vfx].pts - ctime); + fdelay = (frames[vst->vfx].pts - ctime); // while(fdelay > 0) // { @@ -458,12 +454,12 @@ void render_time(render_t *render) printf("video cache %d audio cache %d\n", q_video.size/1024, q_audio.size/1024); #endif - main_render->draw(main_render, &frames[vfx].picture); + main_render->draw(main_render, &frames[vst->vfx].picture); if(main_render->win->win_state != FULLSCREEN) { - prg->current = frames[vfx].pts*1000; + prg->current = frames[vst->vfx].pts*1000; // printf("current %f\n", prg->current); - lvl->current = vfx & 1 ? sound_level_1 : sound_level_0; + lvl->current = vst->vfx & 1 ? sound_level_1 : sound_level_0; send_message(&prg->ctrl, PRG_PROGRESS, 0, 0); @@ -472,9 +468,8 @@ void render_time(render_t *render) } frames_count--; - frames[vfx].ready = 0; - vfx++; - vfx&= 3; + frames[vst->vfx].ready = 0; + vst->vfx = (vst->vfx + 1) & 3; } else delay(1); @@ -483,7 +478,7 @@ void render_time(render_t *render) if(frames[vfx].ready == 1 ) { ctime = get_master_clock(); - fdelay = (frames[vfx].pts - ctime); + fdelay = (frames[vst->vfx].pts - ctime); // printf("pts %f time %f delay %f\n", // frames[vfx].pts, ctime, fdelay); @@ -492,23 +487,21 @@ void render_time(render_t *render) { int next_vfx; fdelay = 0; - next_vfx = (vfx+1) & 3; + next_vfx = (vst->vfx+1) & 3; if( frames[next_vfx].ready == 1 ) { if(frames[next_vfx].pts <= ctime) { - frames[vfx].ready = 0; // skip this frame - vfx++; - vfx&= 3; + frames[vst->vfx].ready = 0; // skip this frame + vst->vfx = (vst->vfx + 1) & 3; } else { if( (frames[next_vfx].pts - ctime) < - ( ctime - frames[vfx].pts) ) + ( ctime - frames[vst->vfx].pts) ) { - frames[vfx].ready = 0; // skip this frame - vfx++; - vfx&= 3; + frames[vst->vfx].ready = 0; // skip this frame + vst->vfx = (vst->vfx + 1) & 3; fdelay = (frames[next_vfx].pts - ctime); } } @@ -519,22 +512,21 @@ void render_time(render_t *render) { int val = fdelay; printf("pts %f time %f delay %d\n", - frames[vfx].pts, ctime, val); + frames[vst->vfx].pts, ctime, val); delay(val/10); }; ctime = get_master_clock(); - fdelay = (frames[vfx].pts - ctime); + fdelay = (frames[vst->vfx].pts - ctime); printf("pts %f time %f delay %f\n", - frames[vfx].pts, ctime, fdelay); + frames[vst->vfx].pts, ctime, fdelay); main_render->draw(main_render, &frames[vfx].picture); main_render->win->panel.prg->current = frames[vfx].pts; // send_message(&render->win->panel.prg->ctrl, MSG_PAINT, 0, 0); - frames[vfx].ready = 0; - vfx++; - vfx&= 3; + frames[vst->vfx].ready = 0; + vst->vfx = (vst->vfx + 1) & 3; } else yield(); #endif @@ -909,7 +901,7 @@ void draw_sw_picture(render_t *render, AVPicture *picture) { uint8_t *bitmap_data; uint32_t bitmap_pitch; - uint8_t *data[4]; + uint8_t *data[4]; int linesize[4]; if(render->win->win_state == MINIMIZED || @@ -955,6 +947,7 @@ void draw_sw_picture(render_t *render, AVPicture *picture) void render_draw_client(render_t *render) { + vst_t *vst = render->vst; int y; if(render->win_state == MINIMIZED || @@ -967,8 +960,8 @@ void render_draw_client(render_t *render) if(player_state == PAUSE) { - if(frames[vfx].ready == 1 ) - main_render->draw(main_render, &frames[vfx].picture); + if(frames[vst->vfx].ready == 1 ) + main_render->draw(main_render, &frames[vst->vfx].picture); else draw_bar(0, y, render->win_width, render->rcvideo.b, 0);