Skip to content

Commit

Permalink
[libVA] Add HEVC, VP9 and VC1. Supported by skylake range of processor
Browse files Browse the repository at this point in the history
  • Loading branch information
mean committed Sep 19, 2016
1 parent 69b5efc commit db2fe0c
Show file tree
Hide file tree
Showing 3 changed files with 141 additions and 54 deletions.
49 changes: 45 additions & 4 deletions avidemux/common/ADM_videoCodec/src/ADM_ffmpeg_libva.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -300,10 +300,12 @@ static enum AVPixelFormat ADM_LIBVA_getFormat(struct AVCodecContext *avctx, con
switch(avctx->codec_id)
{
FMT_V_CHECK(H264,H264)
FMT_V_CHECK(H265,H265)
FMT_V_CHECK(MPEG1VIDEO,MPEG1)
FMT_V_CHECK(MPEG2VIDEO,MPEG2)
FMT_V_CHECK(WMV3,WMV3)
FMT_V_CHECK(VC1,VC1)
FMT_V_CHECK(VP9,VP9)
default:
continue;
break;
Expand Down Expand Up @@ -366,9 +368,27 @@ decoderFFLIBVA::decoderFFLIBVA(AVCodecContext *avctx,decoderFF *parent)
vaapi_context *va_context=new vaapi_context;
memset(va_context,0,sizeof(*va_context)); // dangerous...

VAProfile profile;
switch(avctx->codec_id)
{
default:
case AV_CODEC_ID_H264:
profile=VAProfileH264High;
break;

case AV_CODEC_ID_H265:
profile=VAProfileHEVCMain; // TODO VAProfileHEVCMain10
break;
case AV_CODEC_ID_VP9:
profile=VAProfileVP9Profile3;
break;
case AV_CODEC_ID_VC1:
profile=VAProfileVC1Advanced;
break;

}


va_context->context_id=admLibVA::createDecoder(avctx->coded_width,avctx->coded_height,ADM_DEFAULT_SURFACE,initSurfaceID); // this is most likely wrong
va_context->context_id=admLibVA::createDecoder(profile,avctx->coded_width,avctx->coded_height,ADM_DEFAULT_SURFACE,initSurfaceID); // this is most likely wrong
if(va_context->context_id==VA_INVALID)
{
ADM_warning("Cannot create decoder\n");
Expand All @@ -379,7 +399,7 @@ decoderFFLIBVA::decoderFFLIBVA(AVCodecContext *avctx,decoderFF *parent)
}


if(!admLibVA::fillContext(va_context))
if(!admLibVA::fillContext(profile,va_context))
{
ADM_warning("Cannot get va context initialized for libavcodec\n");
alive=false;
Expand Down Expand Up @@ -535,9 +555,30 @@ bool ADM_hwAccelEntryLibVA::canSupportThis(struct AVCodecContext *avct
if(ofmt==AV_PIX_FMT_NONE)
return false;
outputFormat=ofmt;
ADM_info("This is supported by LIBVA\n");
ADM_info("This is maybe supported by LIBVA\n");
VAProfile profile=VAProfileNone;
switch(avctx->codec_id)
{
case AV_CODEC_ID_H264: profile= VAProfileH264High;break;
case AV_CODEC_ID_H265: profile= VAProfileHEVCMain;break;;
case AV_CODEC_ID_VC1: profile= VAProfileVC1Advanced;break;
case AV_CODEC_ID_VP9: profile= VAProfileVP9Profile3;break;
}
if(!admLibVA::supported(profile))
{
ADM_warning("Not supported by libVA\n");
return false;
}
return true;
}


/**
*
* @param avctx
* @param fmt
* @return
*/
ADM_acceleratedDecoderFF *ADM_hwAccelEntryLibVA::spawn( struct AVCodecContext *avctx, const enum AVPixelFormat *fmt )
{
decoderFF *ff=(decoderFF *)avctx->opaque;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ class admLibVA
static bool setupEncodingConfig(void);
/* Surface */

static VAContextID createDecoder(int width, int height, int nbSurface, VASurfaceID *surfaces);
static VAContextID createDecoder(VAProfile profile,int width, int height, int nbSurface, VASurfaceID *surfaces);
static bool destroyDecoder(VAContextID decoder);

static VASurfaceID allocateSurface( int w, int h);
Expand All @@ -73,7 +73,7 @@ static VAImage *allocateImage( int w, int h);


static bool transfer(VAContextID session, int w, int h,VASurfaceID surface, ADMImage *img,VAImage *tmp,uint8_t *yv12);
static bool fillContext(vaapi_context *c);
static bool fillContext(VAProfile profile,vaapi_context *c);

// Indirect access through image
static bool uploadToImage(ADMImage *src,VAImage *dest );
Expand All @@ -90,6 +90,8 @@ static bool putX11Surface(ADM_vaSurface *img,int widget,int displayWidth,
static bool admImageToSurface( ADMImage *src,ADM_vaSurface *dest);
static bool surfaceToAdmImage(ADMImage *dest,ADM_vaSurface *src);

//
static bool supported(VAProfile profile);

};
/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/***************************************************************************
\file : ADM_coreXvba.cpp
\brief : Wrapper around xvba functions
\author : (C) 2013 by mean fixounet@free.fr, derived from xbmc_pvr
\file : ADM_coreLibVA.cpp
\brief : Wrapper around libVA functions
\author : (C) 2013/2016 by mean fixounet@free.fr, derived from xbmc_pvr
***************************************************************************/

/***************************************************************************
Expand Down Expand Up @@ -44,7 +44,10 @@ namespace ADM_coreLibVA
{
void *context;
VADisplay display;
VAConfigID config;
VAConfigID configH264;
VAConfigID configH265;
VAConfigID configVC1;
VAConfigID configVP9;
VAImageFormat imageFormatNV12;
VAImageFormat imageFormatYV12;
bool directOperation;
Expand Down Expand Up @@ -188,7 +191,36 @@ bool admLibVA::setupEncodingConfig(void)
ADM_info("H264 Encoding config created\n");
return true;
}

/**
* \fn checkProfile
* @param profile
* @param cid
* @param name
* @return
*/
static bool checkProfile(const VAProfile &profile,VAConfigID *cid,const char *name)
{
VAStatus xError;

*cid=-1;
VAConfigAttrib attrib;
attrib.type = VAConfigAttribRTFormat;
CHECK_ERROR(vaGetConfigAttributes(ADM_coreLibVA::display, profile, VAEntrypointVLD, &attrib, 1));
if(xError)
{
ADM_warning("Cannot get attribute for %s \n",name);
return false;
}
CHECK_ERROR(vaCreateConfig( ADM_coreLibVA::display, profile, VAEntrypointVLD,&attrib, 1,cid));
if(xError)
{
ADM_warning("Cannot create config %s\n",name);
*cid=-1;
return false;
}
ADM_info("Config created %s \n",name);
return true;
}
/**
* \fn setupConfig
* \brief verify that h264 main profile is supported
Expand All @@ -199,7 +231,7 @@ bool admLibVA::setupConfig(void)
bool r=false;
int nb=vaMaxNumProfiles(ADM_coreLibVA::display);
ADM_info("Max config = %d \n",nb);
VAProfile *prof=new VAProfile[nb];
VAProfile *prof=(VAProfile *)alloca(sizeof(VAProfile)*nb);
int nbProfiles;
CHECK_ERROR(vaQueryConfigProfiles (ADM_coreLibVA::display, prof,&nbProfiles));

Expand All @@ -214,45 +246,18 @@ bool admLibVA::setupConfig(void)
r=true;
ADM_info("H264 high profile found\n");
}
}
}
}
// supported ?
if(r)
{
VAConfigAttrib attrib;
attrib.type = VAConfigAttribRTFormat;
CHECK_ERROR(vaGetConfigAttributes(ADM_coreLibVA::display, VAProfileH264High, VAEntrypointVLD, &attrib, 1))

if (!(attrib.value & VA_RT_FORMAT_YUV420) )
{
ADM_warning("YUV420 not supported\n");
r=false;
}else
{
ADM_info("YUV420 supported\n");

VAConfigID id;
CHECK_ERROR(vaCreateConfig( ADM_coreLibVA::display, VAProfileH264High, VAEntrypointVLD,&attrib, 1,&id));
if(xError)
{
ADM_warning("Cannot create config\n");
}
else
{
ADM_info("Config created\n");
ADM_coreLibVA::config=id;
r=true;
}

}


}

delete [] prof;
return r;
// if H264 is not supported, no need to go further
if(!r)
return false;


checkProfile(VAProfileH264High, &ADM_coreLibVA::configH264,"H264 Hight");
checkProfile(VAProfileHEVCMain, &ADM_coreLibVA::configH265,"HEVC Main");
checkProfile(VAProfileVC1Advanced, &ADM_coreLibVA::configVC1 ,"VC1");
checkProfile(VAProfileVP9Profile3, &ADM_coreLibVA::configVP9 ,"VP9");
return true;
}
/**
* \fn fourCC_tostring
Expand Down Expand Up @@ -320,10 +325,21 @@ bool admLibVA::setupImageFormat()
* @param c
* @return
*/
bool admLibVA::fillContext(vaapi_context *c)
bool admLibVA::fillContext(VAProfile profile ,vaapi_context *c)
{
CHECK_WORKING(false);
c->config_id=ADM_coreLibVA::config;
VAConfigID cid;
switch(profile)
{
case VAProfileH264High: cid=ADM_coreLibVA::configH264;break;
case VAProfileHEVCMain: cid=ADM_coreLibVA::configH265;break;
case VAProfileVC1Advanced: cid=ADM_coreLibVA::configVC1;break;
case VAProfileVP9Profile3: cid=ADM_coreLibVA::configVP9;break;
default:
ADM_assert(0);

}
c->config_id=cid;
c->display=ADM_coreLibVA::display;
return true;
}
Expand Down Expand Up @@ -396,8 +412,23 @@ bool admLibVA::isOperationnal(void)
{
return coreLibVAWorking;
}


/**
*
* @param profile
* @return
*/
bool admLibVA::supported(VAProfile profile)
{
#define SUPSUP(a,b) case a: if(ADM_coreLibVA::b!=-1) return true;break;
switch(profile)
{
SUPSUP(VAProfileH264High,configH264)
SUPSUP(VAProfileHEVCMain,configH265)
SUPSUP(VAProfileVC1Advanced,configVC1)
SUPSUP(VAProfileVP9Profile3,configVP9)
}
return false;
}

/**
* \fn createDecoder
Expand All @@ -406,12 +437,25 @@ bool admLibVA::isOperationnal(void)
* @return
*/

VAContextID admLibVA::createDecoder(int width, int height,int nbSurface, VASurfaceID *surfaces)
VAContextID admLibVA::createDecoder(VAProfile profile,int width, int height,int nbSurface, VASurfaceID *surfaces)
{
int xError=1;
CHECK_WORKING(VA_INVALID);
VAContextID id;
CHECK_ERROR(vaCreateContext ( ADM_coreLibVA::display, ADM_coreLibVA::config,
VAConfigID cid;

switch(profile)
{
case VAProfileH264High: cid=ADM_coreLibVA::configH264;break;
case VAProfileHEVCMain: cid=ADM_coreLibVA::configH265;break;
case VAProfileVC1Advanced: cid=ADM_coreLibVA::configVC1;break;
case VAProfileVP9Profile3: cid=ADM_coreLibVA::configVP9;break;
default:
ADM_assert(0);

}

CHECK_ERROR(vaCreateContext ( ADM_coreLibVA::display, cid,
width, height,
VA_PROGRESSIVE, // ?? NOT SURE ??
surfaces,
Expand Down

0 comments on commit db2fe0c

Please sign in to comment.