Beispiel #1
0
bool VaapiImage::unmap()
{
    VAStatus status;

    if (!m_isMapped)
        return true;

    switch(m_rawImage.memoryType) {
    case VIDEO_DATA_MEMORY_TYPE_RAW_POINTER:
    case VIDEO_DATA_MEMORY_TYPE_RAW_COPY:
        status = vaUnmapBuffer(m_display->getID(), m_image->buf);
        if (!checkVaapiStatus(status, "vaUnmapBuffer()"))
            return false;
    break;
    case VIDEO_DATA_MEMORY_TYPE_DRM_NAME:
    case VIDEO_DATA_MEMORY_TYPE_DMA_BUF:
        status = vaReleaseBufferHandle(m_display->getID(), m_image->buf);
        if (!checkVaapiStatus(status, "vaReleaseBufferHandle()"))
            return false;
    break;
    default:
        ASSERT(0);
    break;
    }

    m_isMapped = false;
    return true;
}
Beispiel #2
0
VaapiImageRaw *VaapiImage::map(VideoDataMemoryType memoryType)
{
    uint32_t i;
    void *data;
    VAStatus status;

    if (m_isMapped) {
        return &m_rawImage;
    }

    m_rawImage.format = m_image->format.fourcc;
    m_rawImage.width = m_image->width;
    m_rawImage.height = m_image->height;
    m_rawImage.numPlanes = m_image->num_planes;
    m_rawImage.size = m_image->data_size;
    for (i = 0; i < m_image->num_planes; i++) {
        m_rawImage.strides[i] = m_image->pitches[i];
    }

    if (memoryType == VIDEO_DATA_MEMORY_TYPE_RAW_POINTER || memoryType == VIDEO_DATA_MEMORY_TYPE_RAW_COPY) {
        status = vaMapBuffer(m_display->getID(), m_image->buf, &data);
        if (!checkVaapiStatus(status, "vaMapBuffer()"))
            return NULL;
        for (i = 0; i < m_image->num_planes; i++) {
            m_rawImage.handles[i] = (intptr_t) data + m_image->offsets[i];
        }
    } else {
        VABufferInfo bufferInfo;
        if (memoryType == VIDEO_DATA_MEMORY_TYPE_DRM_NAME)
            bufferInfo.mem_type = VA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM;
        else if (memoryType == VIDEO_DATA_MEMORY_TYPE_DMA_BUF)
            bufferInfo.mem_type = VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME;
        else
            ASSERT(0);

        status = vaAcquireBufferHandle(m_display->getID(), m_image->buf, &bufferInfo);
        if (!checkVaapiStatus(status, "vaAcquireBufferHandle()"))
            return NULL;

       for (i = 0; i < m_image->num_planes; i++) {
           m_rawImage.handles[i] = (intptr_t) bufferInfo.handle;
        }
    }
    m_rawImage.memoryType = memoryType;
    m_isMapped = true;

    return &m_rawImage;
}
Beispiel #3
0
ImageRawPtr VaapiImageRaw::create(const DisplayPtr& display, const ImagePtr& image, VideoDataMemoryType memoryType)
{
    ImageRawPtr raw;
    RealeaseCallback release;
    uintptr_t handle;
    VAStatus status;
    VAImagePtr& vaImage = image->m_image;
    if (memoryType == VIDEO_DATA_MEMORY_TYPE_RAW_POINTER || memoryType == VIDEO_DATA_MEMORY_TYPE_RAW_COPY) {
        void* data;
        status = vaMapBuffer(display->getID(), vaImage->buf, &data);
        release = vaUnmapBuffer;
        handle = (uintptr_t)data;
    } else {
        VABufferInfo bufferInfo;
        if (memoryType == VIDEO_DATA_MEMORY_TYPE_DRM_NAME)
            bufferInfo.mem_type = VA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM;
        else if (memoryType == VIDEO_DATA_MEMORY_TYPE_DMA_BUF)
            bufferInfo.mem_type = VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME;
        else
            ASSERT(0);

        status = vaAcquireBufferHandle(display->getID(), vaImage->buf, &bufferInfo);
        release = vaReleaseBufferHandle;
        handle = (uintptr_t)bufferInfo.handle;
    }
    if (!checkVaapiStatus(status, "VaapiImageRaw::create()"))
        return raw;
    raw.reset(new VaapiImageRaw(display, image, memoryType, handle, release));
    return raw;
}
Beispiel #4
0
bool EglVaapiImage::acquireBufferHandle(VideoDataMemoryType memoryType)
{
    uint32_t i;
    if (m_acquired) {
        ASSERT(memoryType = m_frameInfo.memoryType);
        return true;
    }

    // FIXME, more type can be supported
    if (memoryType == VIDEO_DATA_MEMORY_TYPE_DRM_NAME)
        m_bufferInfo.mem_type = VA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM;
    else if (memoryType == VIDEO_DATA_MEMORY_TYPE_DMA_BUF)
        m_bufferInfo.mem_type = VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME;
    else
        ASSERT(0);
    VAStatus vaStatus = vaAcquireBufferHandle(m_display, m_image.buf, &m_bufferInfo);
    m_frameInfo.memoryType = memoryType;
    m_frameInfo.width = m_width;
    m_frameInfo.height = m_height;
    for (i=0; i<m_image.num_planes; i++) {
        m_frameInfo.pitch[i] = m_image.pitches[i];
        m_frameInfo.offset[i] = m_image.offsets[i];
    }
    m_frameInfo.fourcc = m_image.format.fourcc;
    m_frameInfo.size = m_image.data_size; // not interest for bufferhandle
    m_frameInfo.handle = m_bufferInfo.handle;

    m_acquired = true;

    return checkVaapiStatus(vaStatus, "vaAcquireBufferHandle");
}
Beispiel #5
0
const VAImageFormat *
VaapiDisplay::getVaFormat(uint32_t fourcc)
{
    AutoLock locker(m_lock);
    int i;

    if (m_vaImageFormats.empty()) {
        VAStatus vaStatus;
        int numImageFormats;
        numImageFormats = vaMaxNumImageFormats(m_vaDisplay);
        if (numImageFormats == 0)
            return NULL;

        m_vaImageFormats.reserve(numImageFormats);
        m_vaImageFormats.resize(numImageFormats);

        vaStatus = vaQueryImageFormats(m_vaDisplay, &m_vaImageFormats[0], &numImageFormats);
        checkVaapiStatus(vaStatus, "vaQueryImageFormats()");
        for (i=0; i< m_vaImageFormats.size(); i++)
            DEBUG_FOURCC("supported image format: ", m_vaImageFormats[i].fourcc);
    }

    for (i = 0; i < m_vaImageFormats.size(); i++) {
        VAImageFormat vaImageFormat = m_vaImageFormats[i];
        if (vaImageFormat.fourcc == fourcc)
            return &m_vaImageFormats[i];
    }
    return NULL;
}
Beispiel #6
0
static bool vaInit(VADisplay vaDisplay)
{
   int majorVersion, minorVersion;
   VAStatus vaStatus;
   vaStatus= vaInitialize(vaDisplay, &majorVersion, &minorVersion);
   return checkVaapiStatus(vaStatus, "vaInitialize");
}
Beispiel #7
0
/* Creates and maps VA buffer */
bool
vaapiCreateBuffer(VADisplay dpy,
                  VAContextID ctx,
                  int type,
                  uint32_t size,
                  const void *buf,
                  VABufferID * bufIdPtr, void **mappedData)
{
    VABufferID bufId;
    VAStatus status;
    void *data = (void *) buf;

    status =
        vaCreateBuffer(dpy, ctx, (VABufferType) type, size, 1, data,
                       &bufId);
    if (!checkVaapiStatus(status, "vaCreateBuffer()"))
        return false;

    if (mappedData) {
        data = vaapiMapBuffer(dpy, bufId);
        if (!data)
            goto error;
        *mappedData = data;
    }

    *bufIdPtr = bufId;
    return true;

  error:
    vaapiDestroyBuffer(dpy, &bufId);
    return false;
}
Beispiel #8
0
bool VaapiSurface::putImage(VaapiImage * image)
{
    VAImageID imageID;
    VAStatus status;
    uint32_t width, height;

    if (!image)
        return false;

    width = image->getWidth();
    height = image->getHeight();

    if (width != m_width || height != m_height) {
        ERROR("Image resolution does not match with surface");
        return false;
    }

    imageID = image->getID();

    status = vaGetImage(m_display->getID(), m_ID, 0, 0, width, height, imageID);

    if (!checkVaapiStatus(status, "vaPutImage()"))
        return false;

    return true;
}
Beispiel #9
0
bool getVaFormat(VADisplay display, VAImageFormat& format)
{
    int num = vaMaxNumImageFormats(display);
    if (!num)
        return false;
    std::vector<VAImageFormat> vaFormats;
    vaFormats.resize(num);
    VAStatus vaStatus = vaQueryImageFormats(display, &vaFormats[0], &num);
    if (!checkVaapiStatus(vaStatus, "vaQueryImageFormats"))
        return false;
    if (vaStatus != VA_STATUS_SUCCESS) {
        ERROR("query image formats return %d", vaStatus);
        return false;
    }
    vaFormats.resize(num);
    for (size_t i = 0; i < vaFormats.size(); i++)
    {
        const VAImageFormat& fmt = vaFormats[i];
        if (fmt.fourcc == VA_FOURCC_BGRX) {
            format = fmt;
            return true;
        }
    }
    return false;
}
Beispiel #10
0
bool VaapiEncoderBase::initVA()
{
    FUNC_ENTER();

    if (!m_externalDisplay)
        m_xDisplay = XOpenDisplay(NULL);
    if (!m_xDisplay)
    {
        ERROR("no x display.");
        return false;
    }

    int majorVersion, minorVersion;
    VAStatus vaStatus;

    m_display = vaGetDisplay(m_xDisplay);
    if (m_display == NULL) {
        ERROR("vaGetDisplay failed.");
        goto error;
    }

    vaStatus= vaInitialize(m_display, &majorVersion, &minorVersion);
    DEBUG("vaInitialize \n");
    if (!checkVaapiStatus(vaStatus, "vaInitialize"))
        goto error;

    DEBUG("profile = %d", m_videoParamCommon.profile);
    vaStatus = vaCreateConfig(m_display, m_videoParamCommon.profile, m_entrypoint,
                              NULL, 0, &m_config);
    if (!checkVaapiStatus(vaStatus, "vaCreateConfig "))
        goto error;

    vaStatus = vaCreateContext(m_display, m_config,
                               m_videoParamCommon.resolution.width,
                               m_videoParamCommon.resolution.height,
                               VA_PROGRESSIVE, 0, 0,
                               &m_context);
    if (!checkVaapiStatus(vaStatus, "vaCreateContext "))
        goto error;
    return true;

error:
    cleanupVA();
    return false;
}
Beispiel #11
0
static bool vaSelectDriver(VADisplay vaDisplay, const std::string& driverName)
{
    VAStatus vaStatus=VA_STATUS_SUCCESS;
    if (!driverName.empty())
    {
        vaStatus = vaSetDriverName(vaDisplay, const_cast<char*>(driverName.c_str()));
    }
    return checkVaapiStatus(vaStatus, "vaSetDriverName");
}
Beispiel #12
0
VaapiImage::~VaapiImage()
{
    VAStatus status;

    status = vaDestroyImage(m_display->getID(), m_image->image_id);

    if (!checkVaapiStatus(status, "vaDestoryImage()"))
        return;
}
Beispiel #13
0
/* Unmaps VA buffer */
void vaapiUnmapBuffer(VADisplay dpy, VABufferID bufId, void **pbuf)
{
    VAStatus status;

    if (pbuf)
        *pbuf = NULL;

    status = vaUnmapBuffer(dpy, bufId);
    if (!checkVaapiStatus(status, "vaUnmapBuffer()"))
        return;
}
Beispiel #14
0
bool VaapiSurface::sync()
{
    VAStatus status;

    status = vaSyncSurface((VADisplay) m_display->getID(), (VASurfaceID) m_ID);

    if (!checkVaapiStatus(status, "vaSyncSurface()"))
        return false;

    return true;
}
Beispiel #15
0
VaapiSurface::~VaapiSurface()
{
    VAStatus status;

    delete m_derivedImage;

    status = vaDestroySurfaces(m_display->getID(), &m_ID, 1);

    if (!checkVaapiStatus(status, "vaDestroySurfaces()"))
        WARNING("failed to destroy surface");

}
Beispiel #16
0
bool EglVaapiImage::init()
{
    if (m_inited) {
        ERROR("do not init twice");
        return false;
    }
    if (!getVaFormat(m_display, m_format))
        return false;
    VAStatus vaStatus = vaCreateImage(m_display, &m_format, m_width, m_height, &m_image);
    if (!checkVaapiStatus(vaStatus, "vaCreateImage"))
        return false;
    m_inited = true;
    return true;
}
Beispiel #17
0
/* Maps VA buffer */
void *vaapiMapBuffer(VADisplay dpy, VABufferID bufId)
{
    VAStatus status;
    void *data = NULL;

    status = vaMapBuffer(dpy, bufId, &data);

    if (!checkVaapiStatus(status, "vaMapBuffer()")) {
        ERROR("fail to map bufId = %x", bufId);
        return NULL;
    }

    return data;
}
Beispiel #18
0
bool VaapiDisplay::setRotation(int degree)
{
    VAStatus vaStatus;
    VADisplayAttribute* attrList = NULL;
    VADisplayAttribute rotate;
    int i, numAttributes;
    rotate.type = VADisplayAttribRotation;
    rotate.value = VA_ROTATION_NONE;
    if (degree == 0) //no need to set rotation when degree is zero
        return true;
    else if (degree == 90)
        rotate.value = VA_ROTATION_90;
    else if (degree == 180)
        rotate.value = VA_ROTATION_180;
    else if (degree == 270)
        rotate.value = VA_ROTATION_270;

    /* should query before set display attributres */
    vaStatus = vaQueryDisplayAttributes(m_vaDisplay, attrList, &numAttributes);
    if (!checkVaapiStatus(vaStatus, "vaQueryDisplayAttributes") || !attrList)
       return false;

    for (i = 0; i < numAttributes; i++) {
        if (attrList[i].type == VADisplayAttribRotation)
            break;
    }

    if ((i == numAttributes) || !(attrList[i].flags & VA_DISPLAY_ATTRIB_SETTABLE) )
        return false;

    vaStatus = vaSetDisplayAttributes(m_vaDisplay, &rotate, 1);
    if (!checkVaapiStatus(vaStatus, "vaSetDisplayAttributes"))
        return false;
    return true;

}
Beispiel #19
0
bool EglVaapiImage::blt(const SharedPtr<VideoFrame>& src)
{
    if (!m_inited) {
        ERROR("call init before blt!");
        return false;
    }
    if (m_acquired)
        vaReleaseBufferHandle(m_display, m_image.buf);

    VAStatus vaStatus = vaGetImage(m_display, (VASurfaceID)src->surface, src->crop.x, src->crop.y, src->crop.width, src->crop.height, m_image.image_id);

    // incomplete data yet
    m_frameInfo.timeStamp = src->timeStamp;
    m_frameInfo.flags = src->flags;
    return checkVaapiStatus(vaStatus, "vaGetImage");
}
Beispiel #20
0
bool EglVaapiImage::blt(const VideoFrameRawData& src)
{
    if (!m_inited) {
        ERROR("call init before blt!");
        return false;
    }
    if (m_acquired)
        vaReleaseBufferHandle(m_display, m_image.buf);

    VAStatus vaStatus = vaGetImage(m_display, src.internalID, 0, 0, src.width, src.height, m_image.image_id);

    // incomplete data yet
    m_frameInfo.timeStamp = src.timeStamp;
    m_frameInfo.flags = src.flags;
    return checkVaapiStatus(vaStatus, "vaGetImage");
}
Beispiel #21
0
bool VaapiSurface::queryStatus(VaapiSurfaceStatus * pStatus)
{
    VASurfaceStatus surfaceStatus;
    VAStatus status;

    if (!pStatus)
        return false;

    status = vaQuerySurfaceStatus((VADisplay) m_display->getID(),
                                  (VASurfaceID) m_ID, &surfaceStatus);

    if (!checkVaapiStatus(status, "vaQuerySurfaceStatus()"))
        return false;

    *pStatus = (VaapiSurfaceStatus) toVaapiSurfaceStatus(surfaceStatus);
    return true;
}
Beispiel #22
0
ImagePtr VaapiImage::derive(const SurfacePtr& surface)
{
    ImagePtr image;
    if (!surface)
        return image;

    DisplayPtr display = surface->getDisplay();
    VAImagePtr vaImage(new VAImage);

    VAStatus status = vaDeriveImage(display->getID(), surface->getID(), vaImage.get());
    if (!checkVaapiStatus(status, "vaDeriveImage()")) {
        return image;
    }
    image.reset(new VaapiImage(display, surface, vaImage));
    return image;

}
Beispiel #23
0
VaapiImage *VaapiSurface::getDerivedImage()
{
    VAImage va_image;
    VAStatus status;

    if (m_derivedImage)
        return m_derivedImage;

    va_image.image_id = VA_INVALID_ID;
    va_image.buf = VA_INVALID_ID;

    status = vaDeriveImage(m_display->getID(), m_ID, &va_image);
    if (!checkVaapiStatus(status, "vaDeriveImage()"))
        return NULL;

    m_derivedImage = new VaapiImage(m_display->getID(), &va_image);

    return m_derivedImage;
}
Beispiel #24
0
bool VaapiDisplay::setRotation(int degree)
{
    VAStatus vaStatus;
    VADisplayAttribute rotate;
    rotate.type = VADisplayAttribRotation;
    rotate.value = VA_ROTATION_NONE;
    if (degree == 0)
        rotate.value = VA_ROTATION_NONE;
    else if (degree == 90)
        rotate.value = VA_ROTATION_90;
    else if (degree == 180)
        rotate.value = VA_ROTATION_180;
    else if (degree == 270)
        rotate.value = VA_ROTATION_270;

    vaStatus = vaSetDisplayAttributes(m_vaDisplay, &rotate, 1);
    if (!checkVaapiStatus(vaStatus, "vaSetDisplayAttributes"))
        return false;
    return true;

}
bool VaapiPicture::renderVaBuffer(VaapiBufObject * &buffer,
                                  const char *bufferInfo)
{
    VAStatus status = VA_STATUS_SUCCESS;
    VABufferID bufferID = VA_INVALID_ID;

    if (!buffer)
        return false;

    bufferID = buffer->getID();
    if (bufferID == VA_INVALID_ID)
        return false;

    status = vaRenderPicture(m_display, m_context, &bufferID, 1);
    if (!checkVaapiStatus(status, bufferInfo))
        return false;

    delete buffer;
    buffer = NULL;

    return true;
}
Beispiel #26
0
SurfacePtr VaapiSurface::create(const DisplayPtr& display,
                                VaapiChromaType chromaType,
                                uint32_t width,
                                uint32_t height,
                                void *surfAttribArray,
                                uint32_t surfAttribNum)
{
    VAStatus status;
    uint32_t format, i;
    VASurfaceAttrib *surfAttribs = (VASurfaceAttrib *) surfAttribArray;
    SurfacePtr surface;
    VASurfaceID id;

    assert((surfAttribs && surfAttribNum)
           || (!surfAttribs && !surfAttribNum));


    format = vaapiChromaToVaChroma(chromaType);
    uint32_t externalBufHandle = 0;
    status = vaCreateSurfaces(display->getID(), format, width, height,
                              &id, 1, surfAttribs, surfAttribNum);
    if (!checkVaapiStatus(status, "vaCreateSurfacesWithAttribute()"))
        return surface;

    for (int i = 0; i < surfAttribNum; i++) {
        if (surfAttribs[i].type == VASurfaceAttribExternalBufferDescriptor) {
            VASurfaceAttribExternalBuffers *surfAttribExtBuf
                =
                (VASurfaceAttribExternalBuffers *) surfAttribs[i].value.
                value.p;
            externalBufHandle = surfAttribExtBuf->buffers[0];
            break;
        }
    }
    surface.reset(new VaapiSurface(display, id, chromaType,
                                    width, height,externalBufHandle));
    return surface;
}
bool VaapiPicture::decodePicture()
{
    VAStatus status;
    uint32_t i;
    vector < VaapiSlice * >::iterator iter;

    DEBUG("VaapiPicture::decodePicture 0x%08x", m_surfaceID);

    status = vaBeginPicture(m_display, m_context, m_surfaceID);
    if (!checkVaapiStatus(status, "vaBeginPicture()"))
        return false;

    if (m_picParam) {
        if (!renderVaBuffer
            (m_picParam, "vaRenderPicture(), render pic param"))
            return false;
    }

    if (m_probTable) {
        if (!renderVaBuffer
            (m_probTable, "vaRenderPicture(), render probability table"))
            return false;
    }

    if (m_iqMatrix) {
        if (!renderVaBuffer
            (m_iqMatrix, "vaRenderPicture(), render IQ matrix"))
            return false;
    }

    if (m_bitPlane) {
        if (!renderVaBuffer
            (m_bitPlane, "vaRenderPicture(), render bit plane"))
            return false;
    }

    if (m_hufTable) {
        if (!renderVaBuffer
            (m_hufTable, "vaRenderPicture(), render huffman table"))
            return false;
    }

    for (iter = m_sliceArray.begin(); iter != m_sliceArray.end(); ++iter) {
        VaapiBufObject *paramBuf = (*iter)->m_param;
        VaapiBufObject *dataBuf = (*iter)->m_data;

        if (!renderVaBuffer
            (paramBuf, "vaRenderPicture(), render slice param"))
            break;

        if (!renderVaBuffer
            (dataBuf, "vaRenderPicture(), render slice data"))
            break;
    }

    if (iter != m_sliceArray.end()) {
        m_sliceArray.clear();
        return false;
    }
    m_sliceArray.clear();

    status = vaEndPicture(m_display, m_context);
    if (!checkVaapiStatus(status, "vaEndPicture()"))
        return false;
    return true;
}
Beispiel #28
0
VaapiImageRaw::~VaapiImageRaw()
{
    VAImagePtr& image = m_image->m_image;
    VAStatus status = m_release(m_display->getID(), image->buf);
    checkVaapiStatus(status, "vaReleaseBufferHandle()");
}
Decode_Status
    VaapiDecoderBase::setupVA(uint32_t numSurface, VAProfile profile)
{
    INFO("base: setup VA");
    uint32_t i;
    VASurfaceID *surfaces;
    VideoSurfaceBuffer *buf;
    VaapiSurface *suf;
    Decode_Status status;
    VAStatus vaStatus = VA_STATUS_SUCCESS;

    if (m_enableNativeBuffersFlag == true) {
        numSurface = 20;        //NATIVE_WINDOW_COUNT;
    }

    if (m_VAStarted) {
        return DECODE_SUCCESS;
    }

    if (m_VADisplay != NULL) {
        WARNING("VA is partially started.");
        return DECODE_FAIL;
    }
#ifdef ANDROID
    m_display = new Display;
    *m_display = ANDROID_DISPLAY_HANDLE;
#else
    if (!m_display) {
        m_display = XOpenDisplay(NULL);
        m_ownNativeDisplay = true;
    }
#if __PLATFORM_BYT__
    if (setenv("LIBVA_DRIVER_NAME", "wrapper", 1) == 0) {
        INFO("setting LIBVA_DRIVER_NAME to wrapper for chromeos");
    }
#endif
#endif

    m_VADisplay = vaGetDisplay(m_display);
    if (m_VADisplay == NULL) {
        ERROR("vaGetDisplay failed.");
        return DECODE_DRIVER_FAIL;
    }

    int majorVersion, minorVersion;
    vaStatus = vaInitialize(m_VADisplay, &majorVersion, &minorVersion);
    checkVaapiStatus(vaStatus, "vaInitialize");

    VAConfigAttrib attrib;
    attrib.type = VAConfigAttribRTFormat;
    attrib.value = VA_RT_FORMAT_YUV420;

    INFO("base:the profile = %d", profile);
    vaStatus = vaCreateConfig(m_VADisplay,
                              profile,
                              VAEntrypointVLD, &attrib, 1, &m_VAConfig);
    checkVaapiStatus(vaStatus, "vaCreateConfig");

    m_configBuffer.surfaceNumber = numSurface;
    m_bufPool = new VaapiSurfaceBufferPool(m_VADisplay, &m_configBuffer);
    surfaces = new VASurfaceID[numSurface];
    for (i = 0; i < numSurface; i++) {
        surfaces[i] = VA_INVALID_SURFACE;
        buf = m_bufPool->getBufferByIndex(i);
        suf = m_bufPool->getVaapiSurface(buf);
        if (suf)
            surfaces[i] = suf->getID();
    }

    vaStatus = vaCreateContext(m_VADisplay,
                               m_VAConfig,
                               m_videoFormatInfo.width,
                               m_videoFormatInfo.height,
                               0, surfaces, numSurface, &m_VAContext);
    checkVaapiStatus(vaStatus, "vaCreateContext");

    VADisplayAttribute rotate;
    rotate.type = VADisplayAttribRotation;
    rotate.value = VA_ROTATION_NONE;
    if (m_configBuffer.rotationDegrees == 0)
        rotate.value = VA_ROTATION_NONE;
    else if (m_configBuffer.rotationDegrees == 90)
        rotate.value = VA_ROTATION_90;
    else if (m_configBuffer.rotationDegrees == 180)
        rotate.value = VA_ROTATION_180;
    else if (m_configBuffer.rotationDegrees == 270)
        rotate.value = VA_ROTATION_270;

    vaStatus = vaSetDisplayAttributes(m_VADisplay, &rotate, 1);

    m_videoFormatInfo.surfaceNumber = numSurface;
    m_videoFormatInfo.ctxSurfaces = surfaces;
    if (!(m_configBuffer.flag & USE_NATIVE_GRAPHIC_BUFFER)) {
        m_videoFormatInfo.surfaceWidth = m_videoFormatInfo.width;
        m_videoFormatInfo.surfaceHeight = m_videoFormatInfo.height;
    }

    m_VAStarted = true;
    return DECODE_SUCCESS;
}