/* * 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; } }