/* * Copyright (c) 2009-2018, Intel Corporation * * 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, sublicense, * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS 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. */ /* * Video process test case based on LibVA. * This test covers different surface format copy. * Usage: ./vacopy process_copy.cfg */ #include #include #include #include #include #include #include #include #include #include "va_display.h" #ifndef VA_FOURCC_I420 #define VA_FOURCC_I420 0x30323449 #endif #define MAX_LEN 1024 #define CHECK_VASTATUS(va_status,func) \ if (va_status != VA_STATUS_SUCCESS) { \ fprintf(stderr,"%s:%s (%d) failed,exit\n", __func__, func, __LINE__); \ exit(1); \ } using namespace std; static VADisplay va_dpy = NULL; static VAContextID context_id = 0; typedef struct _SurfInfo { FILE *fd; char name[MAX_LEN]; uint32_t width; uint32_t height; uint32_t fourCC; uint32_t format; uint32_t memtype; uint32_t alignsize; void *pBuf; uint8_t *pBufBase; uintptr_t ptrb; }SurfInfo; static SurfInfo g_src; static SurfInfo g_dst; static VAConfigID config_id = 0; static FILE* g_config_file_fd = NULL; static char g_config_file_name[MAX_LEN]; static VASurfaceID g_in_surface_id = VA_INVALID_ID; static VASurfaceID g_out_surface_id = VA_INVALID_ID; static uint32_t g_src_file_fourcc = VA_FOURCC('I', '4', '2', '0'); static uint32_t g_dst_file_fourcc = VA_FOURCC('Y', 'V', '1', '2'); #define _FREE(p) \ if(p != NULL){ \ free(p); p = NULL; \ } static uint32_t g_frame_count = 0; static uint32_t g_copy_method = 0; //0 blance, 1 perf. 2 power_saving static int8_t parse_memtype_format(char *str,uint32_t *dst_memtype) { uint32_t tmemtype = VA_SURFACE_ATTRIB_MEM_TYPE_VA; if (!strcmp(str, "VA")){ tmemtype = VA_SURFACE_ATTRIB_MEM_TYPE_VA; } else if(!strcmp(str, "CPU")){ tmemtype = VA_SURFACE_ATTRIB_MEM_TYPE_USER_PTR; }else{ printf("Not supported format: %s! Currently only support following format: %s\n", str, "VA,CPU"); assert(0); } if(dst_memtype) *dst_memtype = tmemtype; return 0; } static int8_t read_value_string(FILE *fp, const char* field_name, char* value) { char strLine[MAX_LEN]; char* field = NULL; char* str = NULL; uint16_t i; if (!fp || !field_name || !value) { printf("Invalid fuction parameters\n"); return -1; } rewind(fp); while (!feof(fp)) { if (!fgets(strLine, MAX_LEN, fp)) continue; for (i = 0; i < MAX_LEN && strLine[i]; i++) if (strLine[i] != ' ') break; if (i == MAX_LEN || strLine[i] == '#' || strLine[i] == '\n') continue; field = strtok(&strLine[i], ":"); if (strncmp(field, field_name, strlen(field_name))) continue; if (!(str = strtok(NULL, ":"))) continue; /* skip blank space in string */ while (*str == ' ') str++; *(str + strlen(str)-1) = '\0'; strcpy(value, str); return 0; } return -1; } static int8_t read_value_uint32(FILE* fp, const char* field_name, uint32_t* value) { char str[MAX_LEN]; if (read_value_string(fp, field_name, str)) { printf("Failed to find integer field: %s", field_name); return -1; } *value = (uint32_t)atoi(str); return 0; } static VAStatus create_surface(VASurfaceID * p_surface_id,SurfInfo &surf) { VAStatus va_status = VA_STATUS_ERROR_INVALID_PARAMETER; if (surf.memtype == VA_SURFACE_ATTRIB_MEM_TYPE_VA) { VASurfaceAttrib surface_attrib; surface_attrib.type = VASurfaceAttribPixelFormat; surface_attrib.flags = VA_SURFACE_ATTRIB_SETTABLE; surface_attrib.value.type = VAGenericValueTypeInteger; surface_attrib.value.value.i = surf.fourCC; va_status = vaCreateSurfaces(va_dpy, surf.format, surf.width , surf.height, p_surface_id, 1, &surface_attrib, 1); } else if (surf.memtype == VA_SURFACE_ATTRIB_MEM_TYPE_USER_PTR) { VASurfaceAttrib surfaceAttrib[3]; VASurfaceAttribExternalBuffers extBuffer; uint32_t base_addr_align = 0x1000; uint32_t size = 0; surfaceAttrib[0].flags = VA_SURFACE_ATTRIB_SETTABLE; surfaceAttrib[0].type = VASurfaceAttribPixelFormat; surfaceAttrib[0].value.type = VAGenericValueTypeInteger; surfaceAttrib[0].value.value.i = surf.fourCC; surfaceAttrib[1].flags = VA_SURFACE_ATTRIB_SETTABLE; surfaceAttrib[1].type = VASurfaceAttribMemoryType; surfaceAttrib[1].value.type = VAGenericValueTypeInteger; surfaceAttrib[1].value.value.i = VA_SURFACE_ATTRIB_MEM_TYPE_USER_PTR; surfaceAttrib[2].flags = VA_SURFACE_ATTRIB_SETTABLE; surfaceAttrib[2].type = VASurfaceAttribExternalBufferDescriptor; surfaceAttrib[2].value.type = VAGenericValueTypePointer; surfaceAttrib[2].value.value.p = (void *)&extBuffer; memset(&extBuffer, 0, sizeof(extBuffer)); uint32_t pitch_align = surf.alignsize; switch(surf.fourCC) { case VA_FOURCC_NV12: extBuffer.pitches[0] = ((surf.width + pitch_align -1)/pitch_align) * pitch_align; size = (extBuffer.pitches[0] * surf.height) * 3/2;// frame size align with pitch. size = (size+base_addr_align-1)/base_addr_align*base_addr_align;// frame size align as 4K page. extBuffer.offsets[0] = 0;// Y channel extBuffer.offsets[1] = extBuffer.pitches[0] * surf.height; // UV channel. extBuffer.pitches[1] = extBuffer.pitches[0]; extBuffer.num_planes =2; break; case VA_FOURCC_RGBP: extBuffer.pitches[0] = ((surf.width + pitch_align -1)/pitch_align) * pitch_align; size = (extBuffer.pitches[0] * surf.height) * 3;// frame size align with pitch. size = (size+base_addr_align-1)/base_addr_align*base_addr_align;// frame size align as 4K page. extBuffer.offsets[0] = 0;// Y channel extBuffer.offsets[1] = extBuffer.pitches[0] * surf.height; // U channel. extBuffer.pitches[1] = extBuffer.pitches[0]; extBuffer.offsets[2] = extBuffer.pitches[0] * surf.height * 2; // V channel. extBuffer.pitches[2] = extBuffer.pitches[0]; extBuffer.num_planes = 3; break; default : std::cout << surf.fourCC <<"format doesn't support!"< Pre_time.tv_nsec) { duration += (Cur_time.tv_nsec - Pre_time.tv_nsec) / 1000000; } else { duration += (Cur_time.tv_nsec + 1000000000 - Pre_time.tv_nsec) / 1000000 - 1000; } printf("Finish processing, performance: \n" ); printf("%d frames processed in: %d ms, ave time = %d ms\n",g_frame_count, duration, duration/g_frame_count); if (g_src.fd) fclose(g_src.fd); if (g_dst.fd) fclose(g_dst.fd); if (g_config_file_fd) fclose(g_config_file_fd); vpp_context_destroy(); return 0; }