Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 6657 → Rev 6658

/contrib/media/fplay/vaapi.c
37,11 → 37,19
#undef ARRAY_ELEMS
#define ARRAY_ELEMS(a) (sizeof(a) / sizeof((a)[0]))
 
struct va_decoder
{
struct decoder decoder;
VADisplay dpy;
void *hwctx;
VASurfaceID v_surface_id[16];
};
 
static struct va_decoder va_decoder;
 
static int drm_fd = 0;
static struct vaapi_context *v_context;
 
static VASurfaceID v_surface_id[16];
 
#define HAS_HEVC VA_CHECK_VERSION(0, 38, 0)
#define HAS_VP9 (VA_CHECK_VERSION(0, 38, 1) && defined(FF_PROFILE_VP9_0))
 
281,6 → 289,7
unsigned int picture_height)
{
struct vaapi_context* const vaapi = v_context;
struct va_decoder *hw_decoder = (struct va_decoder*)vst->decoder;
VAConfigAttrib attrib;
VAConfigID config_id = VA_INVALID_ID;
VAContextID context_id = VA_INVALID_ID;
309,9 → 318,19
return -1;
};
 
if (vaapi->context_id != VA_INVALID_ID)
vaDestroyContext(vaapi->display, vaapi->context_id);
 
if (hw_decoder->decoder.has_surfaces)
{
vaDestroySurfaces(vaapi->display,hw_decoder->v_surface_id,hw_decoder->decoder.nframes);
hw_decoder->decoder.has_surfaces = 0;
}
 
if (vaapi->config_id != VA_INVALID_ID)
vaDestroyConfig(vaapi->display, vaapi->config_id);
 
 
attrib.type = VAConfigAttribRTFormat;
 
printf("vaGetConfigAttributes\n");
341,17 → 360,20
 
printf("vaCreateSurfaces %dx%d\n",picture_width,picture_height);
status = vaCreateSurfaces(vaapi->display, VA_RT_FORMAT_YUV420, picture_width, picture_height,
v_surface_id,vst->decoder->nframes,NULL,0);
hw_decoder->v_surface_id,hw_decoder->decoder.nframes,NULL,0);
if (!vaapi_check_status(status, "vaCreateSurfaces()"))
{
FAIL();
return -1;
};
 
hw_decoder->decoder.has_surfaces = 1;
 
{
VAImage vaimage;
VABufferInfo info = {0};
 
vaDeriveImage(vaapi->display,v_surface_id[0],&vaimage);
vaDeriveImage(vaapi->display,hw_decoder->v_surface_id[0],&vaimage);
printf("vaDeriveImage: %x fourcc: %x\n"
"offset0: %d pitch0: %d\n"
"offset1: %d pitch1: %d\n"
376,7 → 398,7
status = vaCreateContext(vaapi->display, config_id,
picture_width, picture_height,
VA_PROGRESSIVE,
v_surface_id, vst->decoder->nframes,
hw_decoder->v_surface_id, vst->decoder->nframes,
&context_id);
if (!vaapi_check_status(status, "vaCreateContext()"))
{
395,24 → 417,19
const enum AVPixelFormat *fmt)
{
vst_t *vst = (vst_t*)avctx->opaque;
struct va_decoder* hw_decoder = (struct va_decoder*)vst->decoder;
struct decoder* decoder = &hw_decoder->decoder;
VAProfile profile = avctx->profile;
enum AVCodecID codec = avctx->codec_id;
 
if (codec == AV_CODEC_ID_H264)
if(avctx->hwaccel_context != NULL)
{
if(profile == FF_PROFILE_H264_BASELINE)
profile = FF_PROFILE_H264_CONSTRAINED_BASELINE;
};
 
if(avctx->hwaccel_context != NULL &&
(vst->codec_id != codec ||
vst->codec_profile != profile))
if(decoder->codec_id != avctx->codec_id ||
decoder->profile != avctx->profile)
{
struct decoder* decoder = vst->decoder;
 
printf("\n%s codec changed!!!\n"
"old id %d profile %x new id %d profile %x\n",
__FUNCTION__, vst->codec_id, vst->codec_profile,
__FUNCTION__, decoder->codec_id, decoder->profile,
codec, profile);
 
for(int i = 0; i < decoder->nframes; i++)
421,7 → 438,16
vframe->format = AV_PIX_FMT_NONE;
};
}
else
return AV_PIX_FMT_VAAPI_VLD;
}
 
if (codec == AV_CODEC_ID_H264)
{
if(profile == FF_PROFILE_H264_BASELINE)
profile = FF_PROFILE_H264_CONSTRAINED_BASELINE;
};
 
printf("\n%s codec %d profile %x\n", __FUNCTION__,avctx->codec_id, avctx->profile);
 
for (int i = 0; fmt[i] != PIX_FMT_NONE; i++)
438,8 → 464,6
if (vaapi_init_decoder(vst, profile, VAEntrypointVLD, avctx->width, avctx->height) == 0)
{
avctx->hwaccel_context = v_context;
vst->codec_id = codec;
vst->codec_profile = profile;
printf("%s format: %x\n",__FUNCTION__, fmt[i]);
return fmt[i];
}
466,9 → 490,10
{
static struct av_surface avsurface;
vst_t *vst = (vst_t*)avctx->opaque;
struct va_decoder* hw_decoder = (struct va_decoder*)vst->decoder;
void *surface;
 
surface = (void *)(uintptr_t)v_surface_id[vst->decoder->active_frame->index];
surface = (void *)(uintptr_t)hw_decoder->v_surface_id[vst->decoder->active_frame->index];
 
pic->data[3] = surface;
 
547,6 → 572,7
void va_create_planar(vst_t *vst, vframe_t *vframe)
{
struct vaapi_context* const vaapi = v_context;
struct va_decoder* hw_decoder = (struct va_decoder*)vst->decoder;
VABufferInfo info = {0};
 
VAImage vaimage;
553,12 → 579,18
VAStatus status;
planar_t *planar;
 
vaSyncSurface(vaapi->display,v_surface_id[vframe->index]);
vaSyncSurface(vaapi->display,hw_decoder->v_surface_id[vframe->index]);
 
if(vframe->format != AV_PIX_FMT_NONE)
return;
 
status = vaDeriveImage(vaapi->display,v_surface_id[vframe->index],&vaimage);
if(vframe->planar != NULL)
{
pxDestroyPlanar(vframe->planar);
vframe->planar = NULL;
};
 
status = vaDeriveImage(vaapi->display,hw_decoder->v_surface_id[vframe->index],&vaimage);
if (!vaapi_check_status(status, "vaDeriveImage()"))
{
FAIL();
687,29 → 719,57
return profile;
}
 
struct decoder* va_init_decoder(vst_t *vst)
static void fini_va_decoder(vst_t *vst)
{
struct vaapi_context* const vaapi = v_context;
struct va_decoder *hw_decoder = (struct va_decoder*)vst->decoder;
ENTER();
for(int i = 0; i < hw_decoder->decoder.nframes; i++)
{
vframe_t *vframe = &hw_decoder->decoder.vframes[i];
if(vframe->planar != NULL)
{
printf("destroy planar %d\n", i);
pxDestroyPlanar(vframe->planar);
vframe->planar = NULL;
};
};
 
av_frame_free(&hw_decoder->decoder.Frame);
 
if (vaapi->context_id != VA_INVALID_ID)
vaDestroyContext(vaapi->display, vaapi->context_id);
 
if (hw_decoder->decoder.has_surfaces)
vaDestroySurfaces(vaapi->display,hw_decoder->v_surface_id,hw_decoder->decoder.nframes);
 
if (vaapi->config_id != VA_INVALID_ID)
vaDestroyConfig(vaapi->display, vaapi->config_id);
 
vaTerminate(hw_decoder->dpy);
LEAVE();
};
 
 
struct decoder* init_va_decoder(vst_t *vst)
{
AVCodecContext *vCtx = vst->vCtx;
struct decoder *decoder;
VADisplay dpy;
struct va_decoder *hw_decoder = &va_decoder;
struct decoder *decoder = &hw_decoder->decoder;
 
drm_fd = get_service("DISPLAY");
if (drm_fd == 0)
return NULL;
 
dpy = vaGetDisplayDRM(drm_fd);
if (dpy == NULL)
hw_decoder->dpy = vaGetDisplayDRM(drm_fd);
if (hw_decoder->dpy == NULL)
goto err_0;
 
decoder = calloc(1, sizeof(struct decoder));
if(decoder == NULL)
goto err_0;
 
decoder->hwctx = vaapi_init(dpy);
if(decoder->hwctx == NULL)
hw_decoder->hwctx = vaapi_init(hw_decoder->dpy);
if(hw_decoder->hwctx == NULL)
goto err_1;
 
if(get_profile(dpy, vCtx->codec_id) == VAProfileNone)
if(get_profile(hw_decoder->dpy, vCtx->codec_id) == VAProfileNone)
goto err_1;
 
decoder->Frame = av_frame_alloc();
728,8 → 788,6
vframe->format = AV_PIX_FMT_NONE;
vframe->is_hw_pic = 1;
vframe->index = i;
vframe->pts = 0;
vframe->ready = 0;
list_add_tail(&vframe->list, &vst->input_list);
};
 
747,19 → 805,20
 
decoder->name = vst->vCodec->name;
decoder->codec_id = vCtx->codec_id;
decoder->profile = vCtx->profile;
decoder->pix_fmt = vCtx->pix_fmt;
decoder->width = vCtx->width;
decoder->height = vCtx->height;
decoder->is_hw = 1;
decoder->frame_reorder = 1;
decoder->fini = fini_va_decoder;
 
return decoder;
return (struct decoder*)decoder;
 
err_2:
av_frame_free(&decoder->Frame);
err_1:
vaTerminate(dpy);
free(decoder);
vaTerminate(hw_decoder->dpy);
err_0:
drm_fd = 0;
return NULL;