mirror of https://github.com/intel/libva-utils.git
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:
parent
6307b68156
commit
957a269f02
|
@ -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
|
||||
|
|
|
@ -216,6 +216,7 @@ AC_OUTPUT([
|
|||
putsurface/Makefile
|
||||
videoprocess/Makefile
|
||||
vendor/intel/Makefile
|
||||
vendor/intel/sfcsample/Makefile
|
||||
])
|
||||
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -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
|
||||
|
||||
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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
|
Loading…
Reference in New Issue