forked from KolibriOS/kolibrios
Fplay: vaapi works, but the video output is too slow.
git-svn-id: svn://kolibrios.org@6121 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
parent
09b80753fe
commit
63743484d7
@ -27,11 +27,11 @@ volatile enum player_state sound_state = STOP;
|
||||
uint32_t win_width, win_height;
|
||||
|
||||
|
||||
AVFrame *pFrame;
|
||||
AVFrame *pFrame;
|
||||
|
||||
int have_sound = 0;
|
||||
int have_sound = 0;
|
||||
|
||||
uint8_t *decoder_buffer;
|
||||
uint8_t *decoder_buffer;
|
||||
extern int resampler_size;
|
||||
|
||||
extern int sample_rate;
|
||||
@ -80,10 +80,6 @@ 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);
|
||||
@ -158,20 +154,8 @@ 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(fplay_init_context(&vst))
|
||||
return -1;
|
||||
|
||||
if(avcodec_open2(vst.vCtx, vst.vCodec, NULL) < 0)
|
||||
{
|
||||
@ -180,6 +164,7 @@ int main( int argc, char *argv[])
|
||||
return -1; // Could not open codec
|
||||
};
|
||||
|
||||
printf("ctx->pix_fmt %d\n", vst.vCtx->pix_fmt);
|
||||
|
||||
mutex_init(&vst.q_video.lock);
|
||||
mutex_init(&vst.q_audio.lock);
|
||||
|
@ -16,6 +16,15 @@ typedef struct vstate vst_t;
|
||||
#define HAS_RIGHT (1<<2)
|
||||
#define HAS_BOTTOM (1<<3)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
enum AVPixelFormat format;
|
||||
AVPicture picture;
|
||||
int planar;
|
||||
double pts;
|
||||
volatile int ready;
|
||||
}vframe_t;
|
||||
|
||||
struct render
|
||||
{
|
||||
vst_t *vst;
|
||||
@ -98,26 +107,27 @@ int get_packet(queue_t *q, AVPacket *pkt);
|
||||
|
||||
struct vstate
|
||||
{
|
||||
AVFormatContext *fCtx; /* format context */
|
||||
AVCodecContext *vCtx; /* video decoder context */
|
||||
AVCodecContext *aCtx; /* audio decoder context */
|
||||
AVCodec *vCodec; /* video codec */
|
||||
AVCodec *aCodec; /* audio codec */
|
||||
int vStream; /* video stream index */
|
||||
int aStream; /* audio stream index */
|
||||
AVFormatContext *fCtx; /* format context */
|
||||
AVCodecContext *vCtx; /* video decoder context */
|
||||
AVCodecContext *aCtx; /* audio decoder context */
|
||||
AVCodec *vCodec; /* video codec */
|
||||
AVCodec *aCodec; /* audio codec */
|
||||
int vStream; /* video stream index */
|
||||
int aStream; /* audio stream index */
|
||||
|
||||
queue_t q_video; /* video packets queue */
|
||||
queue_t q_audio; /* audio packets queue */
|
||||
queue_t q_video; /* video packets queue */
|
||||
queue_t q_audio; /* audio packets queue */
|
||||
|
||||
mutex_t gpu_lock; /* gpu access lock. libdrm not yet thread safe :( */
|
||||
|
||||
int vfx; /* index of decoded frame */
|
||||
int dfx; /* index of renderd frame */
|
||||
|
||||
vframe_t vframe[4]; /* decoder workset */
|
||||
int vfx; /* index of decoded frame */
|
||||
int dfx; /* index of renderd frame */
|
||||
void *hwCtx; /* hardware context */
|
||||
int hwdec; /* hardware decoder */
|
||||
};
|
||||
|
||||
|
||||
|
||||
#define DECODER_THREAD 1
|
||||
#define AUDIO_THREAD 2
|
||||
#define VIDEO_THREAD 4
|
||||
@ -155,7 +165,6 @@ static inline void GetNotify(void *event)
|
||||
::"a"(68),"b"(14),"c"(event));
|
||||
}
|
||||
|
||||
int fplay_vaapi_init(void);
|
||||
void va_convert_picture(vst_t *vst, int width, int height, AVPicture *pic);
|
||||
|
||||
int init_fontlib();
|
||||
|
@ -176,7 +176,7 @@ VADisplay va_open_display(void)
|
||||
return NULL;
|
||||
};
|
||||
|
||||
int vaapi_init(VADisplay display)
|
||||
void *vaapi_init(VADisplay display)
|
||||
{
|
||||
struct vaapi_context *vaapi;
|
||||
int major_version, minor_version;
|
||||
@ -225,14 +225,13 @@ int vaapi_init(VADisplay display)
|
||||
|
||||
v_context = vaapi;
|
||||
|
||||
return 0;
|
||||
return vaapi;
|
||||
|
||||
error:
|
||||
free(display_attrs);
|
||||
return -1;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static int has_profile(struct vaapi_context *vaapi, VAProfile profile)
|
||||
{
|
||||
VAProfile *profiles;
|
||||
@ -485,25 +484,61 @@ int fplay_init_context(vst_t *vst)
|
||||
{
|
||||
AVCodecContext *vCtx = vst->vCtx;
|
||||
|
||||
vCtx->opaque = vst;
|
||||
vCtx->thread_count = 1;
|
||||
vCtx->get_format = get_format;
|
||||
vCtx->get_buffer2 = get_buffer2;
|
||||
if(va_check_codec_support(vCtx->codec_id))
|
||||
{
|
||||
VADisplay dpy;
|
||||
|
||||
dpy = va_open_display();
|
||||
vst->hwCtx = vaapi_init(dpy);
|
||||
|
||||
if(vst->hwCtx != NULL)
|
||||
{
|
||||
for(int i = 0; i < 4; i++)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = avpicture_alloc(&vst->vframe[i].picture, AV_PIX_FMT_BGRA,
|
||||
vst->vCtx->width, vst->vCtx->height);
|
||||
if ( ret != 0 )
|
||||
{
|
||||
printf("Cannot alloc video buffer\n\r");
|
||||
return ret;
|
||||
};
|
||||
vst->vframe[i].format = AV_PIX_FMT_BGRA;
|
||||
vst->vframe[i].pts = 0;
|
||||
vst->vframe[i].ready = 0;
|
||||
};
|
||||
|
||||
vst->hwdec = 1;
|
||||
vCtx->opaque = vst;
|
||||
vCtx->thread_count = 1;
|
||||
vCtx->get_format = get_format;
|
||||
vCtx->get_buffer2 = get_buffer2;
|
||||
return 0;
|
||||
};
|
||||
};
|
||||
|
||||
vst->hwdec = 0;
|
||||
|
||||
for(int i = 0; i < 4; i++)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = avpicture_alloc(&vst->vframe[i].picture, vst->vCtx->pix_fmt,
|
||||
vst->vCtx->width, vst->vCtx->height);
|
||||
if ( ret != 0 )
|
||||
{
|
||||
printf("Cannot alloc video buffer\n\r");
|
||||
return ret;
|
||||
};
|
||||
vst->vframe[i].format = vst->vCtx->pix_fmt;
|
||||
vst->vframe[i].pts = 0;
|
||||
vst->vframe[i].ready = 0;
|
||||
};
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int fplay_vaapi_init(void)
|
||||
{
|
||||
VADisplay dpy;
|
||||
|
||||
dpy = va_open_display();
|
||||
|
||||
if (vaapi_init(dpy) < 0)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct SwsContext *vacvt_ctx;
|
||||
|
||||
@ -584,9 +619,6 @@ void va_convert_picture(vst_t *vst, int width, int height, AVPicture *pic)
|
||||
return ;
|
||||
};
|
||||
|
||||
|
||||
// __asm__ volatile ("int3");
|
||||
|
||||
sws_scale(vacvt_ctx, (const uint8_t* const *)src_data, src_linesize, 0, height, pic->data, pic->linesize);
|
||||
|
||||
vaUnmapBuffer (vaapi->display, vaimage.buf);
|
||||
|
@ -11,8 +11,6 @@
|
||||
#include "winlib/winlib.h"
|
||||
#include "fplay.h"
|
||||
|
||||
int fplay_blit_bitmap(bitmap_t *bitmap, int dst_x, int dst_y,int w, int h);
|
||||
|
||||
extern int res_pause_btn[];
|
||||
extern int res_pause_btn_pressed[];
|
||||
|
||||
@ -23,15 +21,7 @@ extern int64_t stream_duration;
|
||||
extern volatile int sound_level_0;
|
||||
extern volatile int sound_level_1;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
AVPicture picture;
|
||||
double pts;
|
||||
volatile int ready;
|
||||
}vframe_t;
|
||||
|
||||
vframe_t frames[4];
|
||||
volatile int frames_count = 0;
|
||||
volatile int frames_count = 0;
|
||||
|
||||
struct SwsContext *cvt_ctx = NULL;
|
||||
|
||||
@ -52,8 +42,8 @@ void flush_video(vst_t *vst)
|
||||
|
||||
for(i = 0; i < 4; i++)
|
||||
{
|
||||
frames[i].pts = 0;
|
||||
frames[i].ready = 0;
|
||||
vst->vframe[i].pts = 0;
|
||||
vst->vframe[i].ready = 0;
|
||||
};
|
||||
vst->vfx = 0;
|
||||
vst->dfx = 0;
|
||||
@ -74,22 +64,6 @@ int init_video(vst_t *vst)
|
||||
return 0;
|
||||
};
|
||||
|
||||
for( i=0; i < 4; i++)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = avpicture_alloc(&frames[i].picture, vst->vCtx->pix_fmt,
|
||||
vst->vCtx->width, vst->vCtx->height);
|
||||
if ( ret != 0 )
|
||||
{
|
||||
printf("Cannot alloc video buffer\n\r");
|
||||
return 0;
|
||||
};
|
||||
|
||||
frames[i].pts = 0;
|
||||
frames[i].ready = 0;
|
||||
};
|
||||
|
||||
create_thread(video_thread, vst, 1024*1024);
|
||||
|
||||
delay(50);
|
||||
@ -103,7 +77,7 @@ int decode_video(vst_t* vst)
|
||||
int frameFinished;
|
||||
double current_clock;
|
||||
|
||||
if(frames[vst->dfx].ready != 0 )
|
||||
if(vst->vframe[vst->dfx].ready != 0 )
|
||||
return -1;
|
||||
|
||||
if( get_packet(&vst->q_video, &pkt) == 0 )
|
||||
@ -148,16 +122,17 @@ int decode_video(vst_t* vst)
|
||||
|
||||
pts *= av_q2d(video_time_base);
|
||||
|
||||
dst_pic = &frames[vst->dfx].picture;
|
||||
dst_pic = &vst->vframe[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[vst->dfx].pts = pts*1000.0;
|
||||
|
||||
frames[vst->dfx].ready = 1;
|
||||
if(vst->hwdec == 0)
|
||||
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);
|
||||
else
|
||||
va_convert_picture(vst, vst->vCtx->width, vst->vCtx->height, dst_pic);
|
||||
|
||||
vst->vframe[vst->dfx].pts = pts*1000.0;
|
||||
vst->vframe[vst->dfx].ready = 1;
|
||||
vst->dfx = (vst->dfx + 1) & 3;
|
||||
frames_count++;
|
||||
};
|
||||
@ -417,12 +392,12 @@ void render_time(render_t *render)
|
||||
|
||||
|
||||
#ifdef VERSION_A
|
||||
if(frames[vst->vfx].ready == 1 )
|
||||
if(vst->vframe[vst->vfx].ready == 1 )
|
||||
{
|
||||
int sys_time;
|
||||
|
||||
ctime = get_master_clock();
|
||||
fdelay = (frames[vst->vfx].pts - ctime);
|
||||
fdelay = (vst->vframe[vst->vfx].pts - ctime);
|
||||
|
||||
// printf("pts %f time %f delay %f\n",
|
||||
// frames[vfx].pts, ctime, fdelay);
|
||||
@ -434,7 +409,7 @@ void render_time(render_t *render)
|
||||
};
|
||||
#if 0
|
||||
ctime = get_master_clock();
|
||||
fdelay = (frames[vst->vfx].pts - ctime);
|
||||
fdelay = (vst->vframe[vst->vfx].pts - ctime);
|
||||
|
||||
// while(fdelay > 0)
|
||||
// {
|
||||
@ -450,14 +425,14 @@ void render_time(render_t *render)
|
||||
// sys_time*10, frames[vfx].pts, ctime, fdelay);
|
||||
|
||||
printf("pts %f time %f delay %f\n",
|
||||
frames[vfx].pts, ctime, fdelay);
|
||||
vst->vframe[vst->vfx].pts, ctime, fdelay);
|
||||
printf("video cache %d audio cache %d\n", q_video.size/1024, q_audio.size/1024);
|
||||
#endif
|
||||
|
||||
main_render->draw(main_render, &frames[vst->vfx].picture);
|
||||
main_render->draw(main_render, &vst->vframe[vst->vfx].picture);
|
||||
if(main_render->win->win_state != FULLSCREEN)
|
||||
{
|
||||
prg->current = frames[vst->vfx].pts*1000;
|
||||
prg->current = vst->vframe[vst->vfx].pts*1000;
|
||||
// printf("current %f\n", prg->current);
|
||||
lvl->current = vst->vfx & 1 ? sound_level_1 : sound_level_0;
|
||||
|
||||
@ -468,17 +443,17 @@ void render_time(render_t *render)
|
||||
}
|
||||
|
||||
frames_count--;
|
||||
frames[vst->vfx].ready = 0;
|
||||
vst->vframe[vst->vfx].ready = 0;
|
||||
vst->vfx = (vst->vfx + 1) & 3;
|
||||
}
|
||||
else delay(1);
|
||||
|
||||
#else
|
||||
|
||||
if(frames[vfx].ready == 1 )
|
||||
if(vst->vframe[vfx].ready == 1 )
|
||||
{
|
||||
ctime = get_master_clock();
|
||||
fdelay = (frames[vst->vfx].pts - ctime);
|
||||
fdelay = (vst->vrame[vst->vfx].pts - ctime);
|
||||
|
||||
// printf("pts %f time %f delay %f\n",
|
||||
// frames[vfx].pts, ctime, fdelay);
|
||||
@ -488,21 +463,21 @@ void render_time(render_t *render)
|
||||
int next_vfx;
|
||||
fdelay = 0;
|
||||
next_vfx = (vst->vfx+1) & 3;
|
||||
if( frames[next_vfx].ready == 1 )
|
||||
if( vst->vrame[next_vfx].ready == 1 )
|
||||
{
|
||||
if(frames[next_vfx].pts <= ctime)
|
||||
if(vst->vrame[next_vfx].pts <= ctime)
|
||||
{
|
||||
frames[vst->vfx].ready = 0; // skip this frame
|
||||
vst->vrame[vst->vfx].ready = 0; // skip this frame
|
||||
vst->vfx = (vst->vfx + 1) & 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( (frames[next_vfx].pts - ctime) <
|
||||
if( (vst->vrame[next_vfx].pts - ctime) <
|
||||
( ctime - frames[vst->vfx].pts) )
|
||||
{
|
||||
frames[vst->vfx].ready = 0; // skip this frame
|
||||
vst->vrame[vst->vfx].ready = 0; // skip this frame
|
||||
vst->vfx = (vst->vfx + 1) & 3;
|
||||
fdelay = (frames[next_vfx].pts - ctime);
|
||||
fdelay = (vst->vrame[next_vfx].pts - ctime);
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -512,20 +487,20 @@ void render_time(render_t *render)
|
||||
{
|
||||
int val = fdelay;
|
||||
printf("pts %f time %f delay %d\n",
|
||||
frames[vst->vfx].pts, ctime, val);
|
||||
vst->vrame[vst->vfx].pts, ctime, val);
|
||||
delay(val/10);
|
||||
};
|
||||
|
||||
ctime = get_master_clock();
|
||||
fdelay = (frames[vst->vfx].pts - ctime);
|
||||
fdelay = (vst->vrame[vst->vfx].pts - ctime);
|
||||
|
||||
printf("pts %f time %f delay %f\n",
|
||||
frames[vst->vfx].pts, ctime, fdelay);
|
||||
vst->vrame[vst->vfx].pts, ctime, fdelay);
|
||||
|
||||
main_render->draw(main_render, &frames[vfx].picture);
|
||||
main_render->win->panel.prg->current = frames[vfx].pts;
|
||||
main_render->draw(main_render, &vst->vrame[vfx].picture);
|
||||
main_render->win->panel.prg->current = vst->vrame[vfx].pts;
|
||||
// send_message(&render->win->panel.prg->ctrl, MSG_PAINT, 0, 0);
|
||||
frames[vst->vfx].ready = 0;
|
||||
vst->vrame[vst->vfx].ready = 0;
|
||||
vst->vfx = (vst->vfx + 1) & 3;
|
||||
}
|
||||
else yield();
|
||||
@ -817,6 +792,7 @@ void draw_hw_picture(render_t *render, AVPicture *picture)
|
||||
uint32_t bitmap_pitch;
|
||||
uint8_t *data[4];
|
||||
int linesize[4];
|
||||
enum AVPixelFormat format;
|
||||
|
||||
if(render->win->win_state == MINIMIZED ||
|
||||
render->win->win_state == ROLLED)
|
||||
@ -833,8 +809,9 @@ void draw_hw_picture(render_t *render, AVPicture *picture)
|
||||
dst_height = render->rcvideo.b;
|
||||
};
|
||||
|
||||
format = render->vst->hwdec == 0 ? render->ctx_format : AV_PIX_FMT_BGRA
|
||||
cvt_ctx = sws_getCachedContext(cvt_ctx,
|
||||
render->ctx_width, render->ctx_height, render->ctx_format,
|
||||
render->ctx_width, render->ctx_height, format,
|
||||
dst_width, dst_height, AV_PIX_FMT_BGRA,
|
||||
SWS_FAST_BILINEAR, NULL, NULL, NULL);
|
||||
if(cvt_ctx == NULL)
|
||||
@ -960,8 +937,8 @@ void render_draw_client(render_t *render)
|
||||
|
||||
if(player_state == PAUSE)
|
||||
{
|
||||
if(frames[vst->vfx].ready == 1 )
|
||||
main_render->draw(main_render, &frames[vst->vfx].picture);
|
||||
if(vst->vframe[vst->vfx].ready == 1 )
|
||||
main_render->draw(main_render, &vst->vframe[vst->vfx].picture);
|
||||
else
|
||||
draw_bar(0, y, render->win_width,
|
||||
render->rcvideo.b, 0);
|
||||
|
Loading…
Reference in New Issue
Block a user