sample code for decode SFC

1. SFC is for decode Scalar & Format Converter
2. Shows downscaling and ARGB conversion
3. Only shows one frame

Signed-off-by: kanghuaz <kanghua.zhu@intel.com>
This commit is contained in:
kanghuaz 2018-09-11 18:32:57 +08:00 committed by XinfengZhang
parent 6307b68156
commit 957a269f02
7 changed files with 3433 additions and 1 deletions

View File

@ -24,7 +24,7 @@ ACLOCAL_AMFLAGS = -I m4 ${ACLOCAL_FLAGS}
AUTOMAKE_OPTIONS = foreign
SUBDIRS = common decode encode vainfo videoprocess vendor/intel
SUBDIRS = common decode encode vainfo videoprocess vendor/intel vendor/intel/sfcsample
if USE_X11
SUBDIRS += putsurface

View File

@ -216,6 +216,7 @@ AC_OUTPUT([
putsurface/Makefile
videoprocess/Makefile
vendor/intel/Makefile
vendor/intel/sfcsample/Makefile
])

2485
vendor/intel/sfcsample/DecodeParamBuffer.h vendored Executable file

File diff suppressed because it is too large Load Diff

55
vendor/intel/sfcsample/Makefile.am vendored Normal file
View File

@ -0,0 +1,55 @@
# Copyright (C) 2018 Intel Corporation. All Rights Reserved.
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sub license, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice (including the
# next paragraph) shall be included in all copies or substantial portions
# of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
# IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
# ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
bin_PROGRAMS = sfcsample
AM_CPPFLAGS = \
-Wall \
-fstack-protector \
$(LIBVA_CFLAGS) \
-I$(top_srcdir)/common \
-I$(top_srcdir)/vendor/intel/sfcsample \
$(NULL)
TEST_LIBS = \
$(LIBVA_LIBS) \
$(top_builddir)/common/libva-display.la \
$(NULL)
sfcsample_LDADD = $(TEST_LIBS)
source_c = TestMain.cpp
source_c += VDecAccelVA.cpp
sfcsample_SOURCES = $(source_c)
valgrind:$(bin_PROGRAMS)
for a in $(bin_PROGRAMS); do \
valgrind --leak-check=full --show-reachable=yes .libs/$$a; \
done

47
vendor/intel/sfcsample/TestMain.cpp vendored Executable file
View File

@ -0,0 +1,47 @@
/*
* * Copyright (C) 2018 Intel Corporation. All Rights Reserved.
* *
* * Permission is hereby granted, free of charge, to any person obtaining a
* * copy of this software and associated documentation files (the
* * "Software"), to deal in the Software without restriction, including
* * without limitation the rights to use, copy, modify, merge, publish,
* * distribute, sub license, and/or sell copies of the Software, and to
* * permit persons to whom the Software is furnished to do so, subject to
* * the following conditions:
* *
* * The above copyright notice and this permission notice (including the
* * next paragraph) shall be included in all copies or substantial portions
* * of the Software.
* *
* * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
* * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
* * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* */
#include "VDecAccelVA.h"
using namespace mvaccel;
int main(int argc, char** argv)
{
VDecAccelVAImpl VideoProc;
//initialize, check caps and prepare buffers
if(VideoProc.Open() != 0)
{
printf("Failed to open decode accelerator");
return 1;
}
//actual decode process
if(VideoProc.DecodePicture() != 0)
{
printf("Failed to decode picture");
return 1;
}
return 0;
}

699
vendor/intel/sfcsample/VDecAccelVA.cpp vendored Executable file
View File

@ -0,0 +1,699 @@
/*
* * Copyright (C) 2018 Intel Corporation. All Rights Reserved.
* *
** Permission is hereby granted, free of charge, to any person obtaining a
* * copy of this software and associated documentation files (the
* * "Software"), to deal in the Software without restriction, including
* * without limitation the rights to use, copy, modify, merge, publish,
* * distribute, sub license, and/or sell copies of the Software, and to
* * permit persons to whom the Software is furnished to do so, subject to
* * the following conditions:
* *
* * The above copyright notice and this permission notice (including the
* * next paragraph) shall be included in all copies or substantial portions
* * of the Software.
* *
* * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
* * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
* * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* */
/**
* @file VDecAccelVA.cpp
* @brief LibVA decode accelerator implementation.
*/
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
#include <linux/fb.h>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <assert.h>
#include <algorithm>
#include <string.h>
#include "VDecAccelVA.h"
#include <va/va.h>
#include <va/va_drm.h>
#include <va/va_x11.h>
#define VASUCCEEDED(err) (err == VA_STATUS_SUCCESS)
#define VAFAILED(err) (err != VA_STATUS_SUCCESS)
mvaccel::VDecAccelVAImpl::VDecAccelVAImpl(void* device)
: m_vaDisplay(0)
, m_vaProfile(VAProfileNone)
, m_vaEntrypoint(VAEntrypointVLD)
, m_vaConfigID(0)
, m_vaContextID(0)
, m_surfaceType(VA_RT_FORMAT_YUV420)
{
if (device)
m_vaDisplay = *(reinterpret_cast<VADisplay*>(device));
if (!m_vaDisplay)
{
printf("Invalid VADisplay\n");
delete this;
return;
}
}
mvaccel::VDecAccelVAImpl::VDecAccelVAImpl()
: m_vaDisplay(0)
, m_vaProfile(VAProfileNone)
, m_vaEntrypoint(VAEntrypointVLD)
, m_vaConfigID(0)
, m_vaContextID(0)
, m_surfaceType(VA_RT_FORMAT_YUV420)
{
}
mvaccel::VDecAccelVAImpl::~VDecAccelVAImpl()
{
}
int mvaccel::VDecAccelVAImpl::Open()
{
VAStatus vaStatus = VA_STATUS_ERROR_UNKNOWN;
//get display device
int MajorVer, MinorVer;
int drm_fd = -1;
if (vaStatus != VA_STATUS_SUCCESS) {
drm_fd = open("/dev/dri/renderD128", O_RDWR);
if (drm_fd >= 0) {
m_vaDisplay = vaGetDisplayDRM(drm_fd);
vaStatus = vaInitialize(m_vaDisplay, &MajorVer, &MinorVer);
}
}
//initialize decode description
create_decode_desc();
m_vaProfile = VAProfileH264Main;
// We only support VLD currently
m_vaEntrypoint = VAEntrypointVLD;
int count = 0;
count = vaMaxNumEntrypoints(m_vaDisplay);
assert(count);
std::vector<VAEntrypoint> vaEntrypoints(count);
vaStatus = vaQueryConfigEntrypoints(
m_vaDisplay,
m_vaProfile,
&vaEntrypoints[0],
&count);
if(VAFAILED(vaStatus))
printf("vaQueryConfigEntrypoints fail\n");
std::vector<VAEntrypoint>::iterator it = std::find(vaEntrypoints.begin(), vaEntrypoints.end(), m_vaEntrypoint);
if (it == vaEntrypoints.end())
{
if(VAFAILED(vaStatus))
printf("VAEntrypoint is not found\n");
return 1;
}
if (!is_config_compatible(m_DecodeDesc))
{
if(VAFAILED(vaStatus))
printf("Decode configuration is not compatible\n");
return 1;
}
// Setup config attributes
std::vector<VAConfigAttrib> vaAttribs;
prepare_config_attribs(m_DecodeDesc, vaAttribs);
// Create config
vaStatus = vaCreateConfig(
m_vaDisplay,
m_vaProfile,
m_vaEntrypoint,
&vaAttribs.at(0),
vaAttribs.size(),
&m_vaConfigID
);
if(VAFAILED(vaStatus))
printf("vaCreateConfig fail\n");
if (!is_rt_foramt_supported(m_DecodeDesc))
{
if(VAFAILED(vaStatus))
printf("Render target is not supported\n");
return 1;
}
// Calculate aligned width/height for gfx surface
uint32_t aligned_width = m_DecodeDesc.width;
uint32_t aligned_height = m_DecodeDesc.height;
// Setup surface attributes
prepare_surface_attribs(m_DecodeDesc, m_vaSurfAttribs, false);
// Create surfaces
for (uint32_t i=0; i<m_DecodeDesc.surfaces_num; i++)
{
VASurfaceID vaID = VA_INVALID_SURFACE;
vaStatus = vaCreateSurfaces(
m_vaDisplay,
m_surfaceType,
aligned_width,
aligned_height,
&vaID,
1,
&(m_vaSurfAttribs.at(0)),
m_vaSurfAttribs.size()
);
if (VASUCCEEDED(vaStatus))
m_vaIDs.push_back(vaID);
}
// Check if surfaces created is equal to requested.
if (m_vaIDs.size() != m_DecodeDesc.surfaces_num)
{
if(VAFAILED(vaStatus))
printf("Create surface fail\n");
return 1;
}
// Create context
vaStatus = vaCreateContext(
m_vaDisplay,
m_vaConfigID,
aligned_width,
aligned_height,
VA_PROGRESSIVE,
&(m_vaIDs.at(0)),
m_vaIDs.size(),
&m_vaContextID
);
if(VAFAILED(vaStatus))
printf("vaCreateContext fail\n");
check_process_pipeline_caps(m_DecodeDesc);
return vaStatus;
}
void mvaccel::VDecAccelVAImpl::Close()
{
std::vector<VASurfaceID>::iterator it;
for (it = m_vaIDs.begin(); it != m_vaIDs.end(); ++it)
delete_surface(*it);
vaDestroyConfig(m_vaDisplay, m_vaConfigID);
vaDestroyContext(m_vaDisplay, m_vaContextID);
m_images.clear();
m_vaIDs.clear();
m_vaSurfAttribs.clear();
m_vaConfigID = 0;
m_vaContextID = 0;
}
uint32_t mvaccel::VDecAccelVAImpl::GetSurfaceID(uint32_t index)
{
assert(index < m_vaIDs.size());
return m_vaIDs[index];
}
/**
* @brief Check if video decode acceleration description is supported.
* @param cc Video decode acceleration description.
* @return true if supported, false if not.
*/
bool mvaccel::VDecAccelVAImpl::is_config_compatible(DecodeDesc& desc)
{
if (!is_slice_mode_supported(desc))
return false;
if (!is_encryption_supported(desc))
return false;
if(!is_sfc_config_supported(desc))
return false;
return true;
}
/**
* @brief Check if long or short format is supported not not.
* @param cc Video decode acceleration description.
* @return true if supported, false if not.
*/
bool mvaccel::VDecAccelVAImpl::is_slice_mode_supported(DecodeDesc& desc)
{
VAConfigAttrib vaAttrib;
memset(&vaAttrib, 0, sizeof(vaAttrib));
vaAttrib.type = VAConfigAttribDecSliceMode;
vaAttrib.value = 0;
vaGetConfigAttributes(
m_vaDisplay,
m_vaProfile,
m_vaEntrypoint,
&vaAttrib,
1);
if(vaAttrib.value & VA_DEC_SLICE_MODE_BASE || vaAttrib.value & VA_DEC_SLICE_MODE_NORMAL)
return true;
else
return false;
}
/**
* @brief Check if encryption is supported or not.
* @param cc Video decode acceleration description.
* @return true if supported, false if not.
*/
bool mvaccel::VDecAccelVAImpl::is_encryption_supported(DecodeDesc& desc)
{
VAConfigAttrib vaAttrib;
memset(&vaAttrib, 0, sizeof(vaAttrib));
vaAttrib.type = VAConfigAttribEncryption;
vaAttrib.value = 0;
vaGetConfigAttributes(
m_vaDisplay,
m_vaProfile,
m_vaEntrypoint,
&vaAttrib,
1
);
if(vaAttrib.value & VA_ATTRIB_NOT_SUPPORTED)
return true;
else
return false;
}
/**
* @brief Check if SFC attribute is supported or not.
* @param cc Video decode acceleration description.
* @return true if supported, false if not.
*/
bool mvaccel::VDecAccelVAImpl::is_sfc_config_supported(DecodeDesc& desc)
{
// SFC attribute check
VAConfigAttrib vaAttrib;
memset(&vaAttrib, 0, sizeof(vaAttrib));
vaAttrib.type = VAConfigAttribDecProcessing;
vaAttrib.value = 0;
vaGetConfigAttributes(
m_vaDisplay,
m_vaProfile,
m_vaEntrypoint,
&vaAttrib,
1);
if (vaAttrib.value != VA_DEC_PROCESSING)
return false;
return true;
}
/**
* @brief Check if render target format is supported or not.
* @param cc Video decode acceleration description.
* @return true if supported, false if not.
*/
bool mvaccel::VDecAccelVAImpl::is_rt_foramt_supported(DecodeDesc& desc)
{
uint32_t count = VASurfaceAttribCount + vaMaxNumImageFormats(m_vaDisplay);
std::vector<VASurfaceAttrib> attribs(count);
VAStatus vaStatus = VA_STATUS_SUCCESS;
vaStatus = vaQuerySurfaceAttributes(
m_vaDisplay,
m_vaConfigID,
&attribs.at(0),
&count
);
if (VAFAILED(vaStatus))
{
printf("vaQuerySurfaceAttributes failed\n");
return false;
}
return true;
}
/**
* @brief Prepare config attribs VAContext creation.
* @param desc Video decode acceleration description.
* @param vaAttribs Array of VASurfaceAttrib which will contains the attrib.
*/
void mvaccel::VDecAccelVAImpl::prepare_config_attribs(
DecodeDesc& desc,
VAConfigAttribArray& attribs)
{
VAConfigAttrib attrib;
memset(&attrib, 0, sizeof(attrib));
// RT formats
attrib.type = VAConfigAttribRTFormat;
attrib.value = VA_RT_FORMAT_YUV420;
attribs.push_back(attrib);
// Slice Mode
attrib.type = VAConfigAttribDecSliceMode;
attrib.value = VA_DEC_SLICE_MODE_NORMAL;
attribs.push_back(attrib);
//dec processing attribs
attrib.type = VAConfigAttribDecProcessing;
attrib.value = VA_DEC_PROCESSING;
attribs.push_back(attrib);
}
/**
* @brief Prepare the VA surface attribs for creation.
* @param desc Video decode acceleration description.
* @param vaSurfAttribs Array of VASurfaceAttrib which will contains attrib.
*/
void mvaccel::VDecAccelVAImpl::prepare_surface_attribs(
DecodeDesc& desc,
VASurfaceAttribArray& attribs,
bool bDecodeDownsamplingHinted)
{
VASurfaceAttrib attrib;
memset(&attrib, 0, sizeof(attrib));
attrib.type = VASurfaceAttribPixelFormat;
attrib.flags = VA_SURFACE_ATTRIB_SETTABLE;
attrib.value.type = VAGenericValueTypeInteger;
// VA_FOURCC and MVFOURCC are interchangeable
if(bDecodeDownsamplingHinted)
attrib.value.value.i = VA_FOURCC_ARGB;
else
attrib.value.value.i = VA_FOURCC_NV12;
attribs.push_back(attrib);
}
/**
* @brief Delete allocated surface
* @param surfaceID Index of allocated surface. After delete, the surface
* values will be set to invalid value.
*/
void mvaccel::VDecAccelVAImpl::delete_surface(VASurfaceID& vaID)
{
// Make sure no others is using this surface
if (m_images.count(vaID))
m_images.erase(m_images.find(vaID));
vaDestroySurfaces(m_vaDisplay, &vaID, 1);
vaID = VA_INVALID_SURFACE;
}
uint8_t* mvaccel::VDecAccelVAImpl::lock_surface(VASurfaceID id, bool write)
{
// Check if decode is completed
VAStatus status = vaSyncSurface(m_vaDisplay, id);
if (VAFAILED(status))
{
printf("vaSyncSurface Error.\n");
return NULL;
}
//sync decode surface
VASurfaceStatus surf_status = VASurfaceSkipped;
for(;;)
{
vaQuerySurfaceStatus(m_vaDisplay, id, &surf_status);
if (surf_status != VASurfaceRendering &&
surf_status != VASurfaceDisplaying)
break;
}
if (surf_status != VASurfaceReady)
{
printf("Surface is not ready by vaQueryStatusSurface");
return NULL;
}
uint8_t* buffer = NULL;
//map the decoded buffer
for(;;)
{
status = vaDeriveImage(m_vaDisplay, id, &m_images[id]);
if (VAFAILED(status))
printf("vaDeriveImage fail. \n");
status = vaMapBuffer(m_vaDisplay, m_images[id].buf, (void**)&buffer);
if (VAFAILED(status))
printf("vaDeriveImage fail. \n");
break;
}
if (VAFAILED(status))
{
status = vaUnmapBuffer(m_vaDisplay, m_images[id].buf);
status = vaDestroyImage(m_vaDisplay, m_images[id].image_id);
}
return buffer;
}
void mvaccel::VDecAccelVAImpl::unlock_surface(VASurfaceID id)
{
VAStatus status = vaUnmapBuffer(m_vaDisplay, m_images[id].buf);
assert(VASUCCEEDED(status));
status = vaDestroyImage(m_vaDisplay, m_images[id].image_id);
assert(VASUCCEEDED(status));
}
//prepare basic format/resolution parameter
void mvaccel::VDecAccelVAImpl::create_decode_desc()
{
m_DecodeDesc.format = VA_FOURCC_NV12;
m_DecodeDesc.sfcformat = VA_FOURCC_ARGB;
m_DecodeDesc.width = 352;
m_DecodeDesc.height = 288;
m_DecodeDesc.sfc_widht = 176;
m_DecodeDesc.sfc_height = 144;
m_DecodeDesc.surfaces_num = 2;
}
bool mvaccel::VDecAccelVAImpl::DecodePicture()
{
// Create addition surfaces for scaled video output
if (m_sfcIDs.empty())
{
if (create_resources())
return 1;
}
VAStatus vaStatus = VA_STATUS_SUCCESS;
VAContextID vaContextID = 0;
VASurfaceID vaID = 0;
//va begin picture
vaStatus = vaBeginPicture(m_vaDisplay, m_vaContextID, vaID);
if (VAFAILED(vaStatus))
printf("vaBeginPicture fail.");
// Set Context ID for End Picture
vaContextID = m_vaContextID;
std::vector<VABufferID> vaBufferIDs;
// Pic parameters buffers
VABufferID vaBufferID;
vaStatus = vaCreateBuffer( m_vaDisplay,
m_vaContextID,
VAPictureParameterBufferType,
sizeof(g_PicParams_AVC),
1,
(uint8_t*)g_PicParams_AVC,
&vaBufferID );
assert(VASUCCEEDED(vaStatus));
if (VASUCCEEDED(vaStatus))
vaBufferIDs.push_back(vaBufferID);
// IQ matrics
vaStatus = vaCreateBuffer( m_vaDisplay,
m_vaContextID,
VAIQMatrixBufferType,
sizeof(g_Qmatrix_AVC),
1,
(uint8_t*)g_Qmatrix_AVC,
&vaBufferID );
assert(VASUCCEEDED(vaStatus));
if (VASUCCEEDED(vaStatus))
vaBufferIDs.push_back(vaBufferID);
//slice parameter buffers
vaStatus = vaCreateBuffer(m_vaDisplay,
m_vaContextID,
VASliceParameterBufferType,
sizeof(g_SlcParams_AVC),
1,
(uint8_t*)g_SlcParams_AVC,
&vaBufferID );
assert(VASUCCEEDED(vaStatus));
if (VASUCCEEDED(vaStatus))
vaBufferIDs.push_back(vaBufferID);
//BITSTREAM buffers
vaStatus = vaCreateBuffer(m_vaDisplay,
m_vaContextID,
VASliceDataBufferType,
sizeof(g_Bitstream_AVC),
1,
(uint8_t*)g_Bitstream_AVC,
&vaBufferID );
assert(VASUCCEEDED(vaStatus));
if (VASUCCEEDED(vaStatus))
vaBufferIDs.push_back(vaBufferID);
//PROC_PIPELINE buffers
vaStatus = vaCreateBuffer(m_vaDisplay,
m_vaContextID,
VAProcPipelineParameterBufferType,
sizeof(m_vaProcBuffer),
1,
(uint8_t*)&m_vaProcBuffer,
&vaBufferID );
assert(VASUCCEEDED(vaStatus));
if (VASUCCEEDED(vaStatus))
vaBufferIDs.push_back(vaBufferID);
if (vaBufferIDs.size())
{
vaStatus = vaRenderPicture(
m_vaDisplay,
m_vaContextID,
&(vaBufferIDs.at(0)),
vaBufferIDs.size());
}
//va end picture
vaStatus = vaEndPicture(m_vaDisplay, vaContextID);
if (VAFAILED(vaStatus))
printf("vaEndPicture fail.");
//lock surface
uint8_t* gfx_surface_buf = lock_surface(m_sfcIDs[0], false);
if (gfx_surface_buf == NULL)
{
printf("Fail to lock gfx surface\n");
return 1;
}
//write to yuv file
FILE* sfc_stream = fopen("sfc_sample_176_144_argb.yuv", "wb");
uint32_t file_size = m_DecodeDesc.sfc_widht * m_DecodeDesc.sfc_height * 4; //ARGB format
fwrite(gfx_surface_buf, file_size, 1, sfc_stream);
fclose(sfc_stream);
//unlock surface and clear
unlock_surface(m_sfcIDs[0]);
Close();
return (VASUCCEEDED(vaStatus) ? 0 : 1);
}
// check vaQueryVideoProcPipelineCaps
int mvaccel::VDecAccelVAImpl::check_process_pipeline_caps(DecodeDesc& desc)
{
VAProcPipelineCaps caps;
VAProcColorStandardType inputCST[VAProcColorStandardCount];
VAProcColorStandardType outputCST[VAProcColorStandardCount];
caps.input_color_standards = inputCST;
caps.output_color_standards = outputCST;
m_in4CC.resize(vaMaxNumImageFormats(m_vaDisplay));
m_out4CC.resize(vaMaxNumImageFormats(m_vaDisplay));
caps.input_pixel_format = &m_in4CC.at(0);
caps.output_pixel_format = &m_out4CC.at(0);
VABufferID filterIDs[VAProcFilterCount];
uint32_t filterCount = 0;
VAStatus vaStatus = VA_STATUS_SUCCESS;
vaStatus = vaQueryVideoProcPipelineCaps(
m_vaDisplay,
m_vaContextID,
filterIDs,
filterCount,
&caps
);
if (VAFAILED(vaStatus))
{
printf("vaQueryVideoProcPipelineCaps fail\n");
return 1;
}
m_in4CC.resize(caps.num_input_pixel_formats);
m_out4CC.resize(caps.num_output_pixel_formats);
return 0;
}
int mvaccel::VDecAccelVAImpl::create_resources()
{
if (m_sfcIDs.empty())
m_sfcIDs.resize(1);
// Create addition surfaces for scaled video output
uint16_t width = m_DecodeDesc.sfc_widht;
uint16_t height = m_DecodeDesc.sfc_height;
//prepare sfc surface attribs
DecodeDesc SfcDesc;
SfcDesc.sfcformat = VA_FOURCC('A','R','G','B');
VASurfaceAttribArray Sfc_vaSurfAttribs;
prepare_surface_attribs(SfcDesc, Sfc_vaSurfAttribs, true);
uint32_t surfaceType = m_surfaceType;
m_surfaceType = (uint32_t)SfcDesc.sfcformat;
for(uint32_t i = 0; i < m_sfcIDs.size(); i++)
{
vaCreateSurfaces(
m_vaDisplay,
m_surfaceType,
width,
height,
&m_sfcIDs[i],
1,
&(Sfc_vaSurfAttribs.at(0)),
Sfc_vaSurfAttribs.size()
);
}
m_surfaceType = surfaceType;
m_rectSFC.x = m_rectSFC.y = 0;
m_rectSFC.width = width;
m_rectSFC.height = height;
// Prepare VAProcPipelineParameterBuffer for decode
VAProcPipelineParameterBuffer buffer;
memset(&buffer, 0, sizeof(buffer));
m_rectSrc.x = m_rectSrc.y = 0;
m_rectSrc.width = (uint16_t)m_DecodeDesc.width;
m_rectSrc.height = (uint16_t)m_DecodeDesc.height;
buffer.surface_region = &m_rectSrc;
buffer.output_region = &m_rectSFC;
buffer.additional_outputs = (VASurfaceID*)&(m_sfcIDs[0]);
buffer.num_additional_outputs = 1;
m_vaProcBuffer = buffer;
return 0;
}

145
vendor/intel/sfcsample/VDecAccelVA.h vendored Executable file
View File

@ -0,0 +1,145 @@
/*
* * Copyright (C) 2018 Intel Corporation. All Rights Reserved.
* *
** Permission is hereby granted, free of charge, to any person obtaining a
* * copy of this software and associated documentation files (the
* * "Software"), to deal in the Software without restriction, including
* * without limitation the rights to use, copy, modify, merge, publish,
* * distribute, sub license, and/or sell copies of the Software, and to
* * permit persons to whom the Software is furnished to do so, subject to
* * the following conditions:
* *
* * The above copyright notice and this permission notice (including the
* * next paragraph) shall be included in all copies or substantial portions
* * of the Software.
* *
* * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
* * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
* * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* */
/**
* @file VDecAccelVA.h
* @brief LibVA decode accelerator declaration
*/
#ifndef MV_ACCELERATOR_VAAPI_DECODE_H
#define MV_ACCELERATOR_VAAPI_DECODE_H
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <map>
#include <vector>
#include <algorithm>
#include <va/va.h>
#include "DecodeParamBuffer.h"
#include <X11/Xlib.h>
typedef Display* HDISP;
namespace mvaccel
{
/**
* @brief LibVA decode accelerator
*/
class VDecAccelVAImpl
{
public:
VDecAccelVAImpl(void* device);
VDecAccelVAImpl();
virtual ~VDecAccelVAImpl();
// VDecAccel interface
virtual int Open();
virtual void Close();
virtual uint32_t GetSurfaceID(uint32_t index);
bool DecodePicture();
void bind_buffer(uint8_t* base);
protected:
// GfxSurfaceAccess interface
uint32_t get_width(VASurfaceID id);
uint32_t get_height(VASurfaceID id);
uint32_t get_stride(VASurfaceID id);
uint8_t* lock_surface(VASurfaceID id, bool write);
void unlock_surface(VASurfaceID id);
void* get_raw(VASurfaceID id);
void* get_device(VASurfaceID id);
typedef std::vector<VAConfigAttrib> VAConfigAttribArray;
typedef std::vector<VASurfaceAttrib> VASurfaceAttribArray;
// Member functions inherit by children
virtual bool is_config_compatible(DecodeDesc& desc);
virtual bool is_rt_foramt_supported(DecodeDesc& desc);
virtual void prepare_config_attribs(
DecodeDesc& desc,
VAConfigAttribArray& attribs);
virtual void prepare_surface_attribs(
DecodeDesc& desc,
VASurfaceAttribArray& attribs,
bool bDecodeDownsamplingHinted);
// Member fucntions NOT inherit by children
bool is_slice_mode_supported(DecodeDesc& desc);
bool is_encryption_supported(DecodeDesc& desc);
bool is_sfc_config_supported(DecodeDesc& desc);
VAStatus render_picture(VAContextID& vaContextID);
VAStatus query_status();
VAStatus create_surface(
uint32_t width,
uint32_t height,
VASurfaceAttribArray& vaAttribs,
VASurfaceID& vaID);
void delete_surface(VASurfaceID& vaID);
void create_decode_desc();
int check_process_pipeline_caps(DecodeDesc& desc);
int create_resources();
protected:
// VA ID & Handles
VADisplay m_vaDisplay; /**< @brief VA hardware device */
VAProfile m_vaProfile; /**< @brief Video decoder profile */
VAEntrypoint m_vaEntrypoint; /**< @brief VA entry point */
VAConfigID m_vaConfigID; /**< @brief VA decode config id*/
VAContextID m_vaContextID; /**< @brief Video decoder context */
// VASurfaces id and attributes
std::vector<VASurfaceID> m_vaIDs;
VASurfaceAttribArray m_vaSurfAttribs;
uint32_t m_surfaceType; /**< @brief surface type */
// Gfx surface access management
std::map<VASurfaceID, VAImage> m_images; /**< @brief buf pointer */
enum SFC
{
MAX_IN_W,
MAX_IN_H,
MIN_IN_W,
MIN_IN_H,
MAX_OUT_W,
MAX_OUT_H,
MIN_OUT_W,
MIN_OUT_H,
NEW_W,
NEW_H,
};
DecodeDesc m_DecodeDesc; /**< @brief decode discription */
VARectangle m_rectSrc; /**< @brief Rectangle for source input */
VARectangle m_rectSFC; /**< @brief Rectangle for SFC output */
std::vector<uint32_t> m_in4CC; /**< @brief input FOURCC */
std::vector<uint32_t> m_out4CC; /**< @brief output FOURCC */
std::map<SFC,uint32_t> m_sfcSize; /**< @brief SFC sizes */
std::vector<VASurfaceID> m_sfcIDs; /**< @brief sfc surfaces */
VAProcPipelineParameterBuffer m_vaProcBuffer; /**< @brief sfc pipeline buffer */
};
} // namespace mvaccel
#endif // MV_ACCELERATOR_VAAPI_DECODE_H