/*
* Copyright 2016 Intel Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "interface/VideoCommonDefs.h"
#include "VaapiUtils.h"
namespace YamiMediaCodec {
uint8_t* mapSurfaceToImage(VADisplay display, intptr_t surface, VAImage& image)
{
uint8_t* p = NULL;
VAStatus status = vaDeriveImage(display, (VASurfaceID)surface, &image);
if (!checkVaapiStatus(status, "vaDeriveImage"))
return NULL;
status = vaMapBuffer(display, image.buf, (void**)&p);
if (!checkVaapiStatus(status, "vaMapBuffer")) {
checkVaapiStatus(vaDestroyImage(display, image.image_id), "vaDestroyImage");
return NULL;
}
return p;
}
void unmapImage(VADisplay display, const VAImage& image)
{
checkVaapiStatus(vaUnmapBuffer(display, image.buf), "vaUnmapBuffer");
checkVaapiStatus(vaDestroyImage(display, image.image_id), "vaDestroyImage");
}
//return rt format, 0 for unsupported
uint32_t getRtFormat(uint32_t fourcc)
{
switch (fourcc) {
case YAMI_FOURCC_Y800:
return VA_RT_FORMAT_YUV400;
case YAMI_FOURCC_NV12:
case YAMI_FOURCC_I420:
case YAMI_FOURCC_YV12:
case YAMI_FOURCC_IMC3:
return VA_RT_FORMAT_YUV420;
case YAMI_FOURCC_422H:
case YAMI_FOURCC_422V:
case YAMI_FOURCC_YUY2:
return VA_RT_FORMAT_YUV422;
case YAMI_FOURCC_444P:
return VA_RT_FORMAT_YUV444;
#if VA_CHECK_VERSION(0, 38, 1)
case YAMI_FOURCC_P010:
return VA_RT_FORMAT_YUV420_10BPP;
#endif
case YAMI_FOURCC_RGBX:
case YAMI_FOURCC_RGBA:
case YAMI_FOURCC_BGRX:
case YAMI_FOURCC_BGRA:
case YAMI_FOURCC_XRGB:
case YAMI_FOURCC_ARGB:
case YAMI_FOURCC_XBGR:
case YAMI_FOURCC_ABGR:
return VA_RT_FORMAT_RGB32;
case YAMI_FOURCC_RGB565:
return VA_RT_FORMAT_RGB16;
#ifdef VA_RT_FORMAT_RGB32_10BPP
case YAMI_FOURCC_R210:
return VA_RT_FORMAT_RGB32_10BPP;
#endif
}
ERROR("get rt format for %.4s failed", (char*)&fourcc);
return 0;
}
bool dumpSurface(VADisplay display, intptr_t surface)
{
static uint32_t _frameCount = 0;
const uint8_t* p = NULL;
uint32_t fourcc = 0;
const char* ptrC = (char*)(&fourcc);
char fileName[256];
VAImage image;
static FILE* fp = NULL;
bool useSingleFile = true;
memset(&image, 0, sizeof(VAImage));
p = mapSurfaceToImage(display, surface, image);
fourcc = image.format.fourcc;
if (fourcc != VA_FOURCC_NV12) {
WARNING("format: (%c%c%c%c, 0x%x) is not support to dump surface", ptrC[0], ptrC[1], ptrC[2], ptrC[3], fourcc);
return false;
}
if (!image.width || !image.height) {
WARNING("invalid surface/image width: %d, height: %d", image.width, image.height);
return false;
}
if (!fp) {
memset(fileName, 0, sizeof(fileName));
if (useSingleFile) {
sprintf(fileName, "%s/%c%c%c%c_%dx%d", "/tmp/yami", ptrC[0], ptrC[1], ptrC[2], ptrC[3], image.width, image.height);
}
else {
sprintf(fileName, "%s/%04d_%c%c%c%c_%dx%d", "/tmp/yami", _frameCount, ptrC[0], ptrC[1], ptrC[2], ptrC[3], image.width, image.height);
_frameCount++;
}
fp = fopen(fileName, "w+");
}
if (!fp)
return false;
int widths[3], heights[3];
widths[0] = image.width;
widths[1] = ((image.width + 1) / 2) * 2;
widths[2] = 0;
heights[0] = image.height;
heights[1] = (image.height + 1) / 2;
heights[2] = 0;
uint32_t plane = 0;
for (plane = 0; plane < image.num_planes; plane++) {
int h = 0;
for (h = 0; h < heights[plane]; h++) {
fwrite(p + image.offsets[plane] + image.pitches[plane] * h, widths[plane], 1, fp);
}
}
if (!useSingleFile) {
fclose(fp);
fp = NULL;
}
unmapImage(display, image);
return true;
}
}