void test() { VAEntrypoint entrypoints[5]; int num_entrypoints,slice_entrypoint; VAConfigAttrib attrib[2]; VAConfigID config_id; unsigned int fourcc, luma_stride, chroma_u_stride, chroma_v_stride, luma_offset, chroma_u_offset; unsigned int chroma_v_offset, buffer_name; unsigned int *p_buffer; int i, ret; char c; int frame_width=640, frame_height=480; VASurfaceID surface_id; VAImage image_id; unsigned char *usrbuf; usrbuf = (unsigned char*)malloc(frame_width * frame_height * 2); ASSERT ( usrbuf != NULL); VASurfaceAttribExternalBuffers vaSurfaceExternBuf; VASurfaceAttrib attrib_list[2]; va_status = vaQueryConfigEntrypoints(va_dpy, VAProfileH264Baseline, entrypoints, &num_entrypoints); ASSERT( VA_STATUS_SUCCESS == va_status ); for (slice_entrypoint = 0; slice_entrypoint < num_entrypoints; slice_entrypoint++) { if (entrypoints[slice_entrypoint] == VAEntrypointEncSlice) break; } if (slice_entrypoint == num_entrypoints) { /* not find Slice entry point */ status("VAEntrypointEncSlice doesn't support, exit.\n"); ASSERT(0); } /* find out the format for the render target, and rate control mode */ attrib[0].type = VAConfigAttribRTFormat; attrib[1].type = VAConfigAttribRateControl; va_status = vaGetConfigAttributes(va_dpy, VAProfileH264Baseline, VAEntrypointEncSlice, &attrib[0], 2); ASSERT( VA_STATUS_SUCCESS == va_status ); if ((attrib[0].value & VA_RT_FORMAT_YUV420) == 0) { /* not find desired YUV420 RT format */ status("VA_RT_FORMAT_YUV420 doesn't support, exit\n"); ASSERT(0); } if ((attrib[1].value & VA_RC_VBR) == 0) { /* Can't find matched RC mode */ status("VBR mode doesn't found, exit\n"); ASSERT(0); } attrib[0].value = VA_RT_FORMAT_YUV420; /* set to desired RT format */ attrib[1].value = VA_RC_VBR; /* set to desired RC mode */ va_status = vaCreateConfig(va_dpy, VAProfileH264Baseline, VAEntrypointEncSlice, &attrib[0], 2, &config_id); ASSERT( VA_STATUS_SUCCESS == va_status ); attrib_list[1].type = (VASurfaceAttribType)VASurfaceAttribExternalBufferDescriptor; attrib_list[0].type = (VASurfaceAttribType)VASurfaceAttribMemoryType; va_status = vaGetSurfaceAttributes(va_dpy, config_id, attrib_list, 2); ASSERT( VA_STATUS_SUCCESS == va_status ); if (attrib_list[0].flags != VA_SURFACE_ATTRIB_NOT_SUPPORTED) { status("supported memory type:\n"); if (attrib_list[0].value.value.i & VA_SURFACE_ATTRIB_MEM_TYPE_VA) status("\tVA_SURFACE_ATTRIB_MEM_TYPE_VA\n"); if (attrib_list[0].value.value.i & VA_SURFACE_ATTRIB_MEM_TYPE_V4L2) status("\tVA_SURFACE_ATTRIB_MEM_TYPE_V4L2\n"); if (attrib_list[0].value.value.i & VA_SURFACE_ATTRIB_MEM_TYPE_USER_PTR) status("\tVA_SURFACE_ATTRIB_MEM_TYPE_USER_PTR\n"); if (attrib_list[0].value.value.i & VA_SURFACE_ATTRIB_MEM_TYPE_ANDROID_GRALLOC) status("\tVA_SURFACE_ATTRIB_MEM_TYPE_ANDROID_GRALLOC\n"); if (attrib_list[0].value.value.i & VA_SURFACE_ATTRIB_MEM_TYPE_ANDROID_ION) status("\tVA_SURFACE_ATTRIB_MEM_TYPE_ANDROID_ION\n"); if (attrib_list[0].value.value.i & VA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM) status("\tVA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM\n"); } if ((attrib_list[1].flags != VA_SURFACE_ATTRIB_NOT_SUPPORTED) && (attrib_list[0].value.value.i & VA_SURFACE_ATTRIB_MEM_TYPE_USER_PTR)) { status("vaCreateSurfaces from external usr pointer\n"); vaSurfaceExternBuf.buffers = (unsigned long*)malloc(sizeof(unsigned int)); vaSurfaceExternBuf.buffers[0] = usrbuf; vaSurfaceExternBuf.num_buffers = 1; vaSurfaceExternBuf.width = frame_width; vaSurfaceExternBuf.height = frame_height; vaSurfaceExternBuf.pitches[0] = vaSurfaceExternBuf.pitches[1] = vaSurfaceExternBuf.pitches[2] = frame_width; //vaSurfaceExternBuf.flags = VA_SURFACE_ATTRIB_MEM_TYPE_ANDROID_GRALLOC; vaSurfaceExternBuf.pixel_format = VA_FOURCC_NV12; //vaSurfaceExternBuf.pitches[0] = attribute_tpi->luma_stride; attrib_list[1].flags = VA_SURFACE_ATTRIB_SETTABLE; attrib_list[1].value.type = VAGenericValueTypePointer; attrib_list[1].value.value.p = (void *)&vaSurfaceExternBuf; attrib_list[0].flags = VA_SURFACE_ATTRIB_SETTABLE; attrib_list[0].value.type = VAGenericValueTypeInteger; attrib_list[0].value.value.i = VA_SURFACE_ATTRIB_MEM_TYPE_USER_PTR; va_status = vaCreateSurfaces(va_dpy, VA_RT_FORMAT_YUV420, frame_width, frame_height, &surface_id, 1, attrib_list, 2); ASSERT( VA_STATUS_SUCCESS == va_status ); va_status = vaDeriveImage(va_dpy, surface_id, &image_id); ASSERT( VA_STATUS_SUCCESS == va_status ); va_status = vaMapBuffer(va_dpy, image_id.buf, (void**)&p_buffer); ASSERT( VA_STATUS_SUCCESS == va_status ); memset(p_buffer, 0x80, image_id.width * image_id.height); va_status = vaUnmapBuffer(va_dpy, image_id.buf); ASSERT( VA_STATUS_SUCCESS == va_status ); va_status = vaDestroyImage(va_dpy, image_id.image_id); ASSERT( VA_STATUS_SUCCESS == va_status ); va_status = vaDestroySurfaces(va_dpy, &surface_id, 1); ASSERT( VA_STATUS_SUCCESS == va_status ); } va_status = vaDestroyConfig(va_dpy, config_id); ASSERT( VA_STATUS_SUCCESS == va_status ); free(usrbuf); }
int csc_preparation () { VAStatus va_status; // 1. make sure dst fourcc is supported for vaImage if (!lookup_image_format(csc_dst_fourcc)) { test_color_conversion = 0; printf("VA driver doesn't support %s image, skip additional color conversion\n", map_vafourcc_to_str(csc_dst_fourcc)); goto cleanup; } // 2. make sure src_fourcc is supported for vaSurface VASurfaceAttrib surface_attribs[1], * const s_attrib = &surface_attribs[0]; s_attrib->type = VASurfaceAttribPixelFormat; s_attrib->flags = VA_SURFACE_ATTRIB_SETTABLE; s_attrib->value.type = VAGenericValueTypeInteger; s_attrib->value.value.i = csc_src_fourcc; if (!lookup_surface_attrib(VASurfaceAttribPixelFormat, &s_attrib->value)) { printf("VA driver doesn't support %s surface, skip additional color conversion\n", map_vafourcc_to_str(csc_src_fourcc)); test_color_conversion = 0; goto cleanup; } // 3 create all objs required by csc // 3.1 vaSurface with src fourcc va_status = vaCreateSurfaces( va_dpy, VA_RT_FORMAT_YUV420, surface_width, surface_height, &surface_id[0], SURFACE_NUM, surface_attribs, 1 ); CHECK_VASTATUS(va_status,"vaCreateSurfaces"); // 3.2 vaImage with dst fourcc VAImageFormat image_format; image_format.fourcc = csc_dst_fourcc; image_format.byte_order = VA_LSB_FIRST; image_format.bits_per_pixel = 16; va_status = vaCreateImage(va_dpy, &image_format, surface_width, surface_height, &csc_dst_fourcc_image); CHECK_VASTATUS(va_status,"vaCreateImage"); // 3.3 create a temp VASurface for final rendering(vaPutSurface) s_attrib->value.value.i = VA_FOURCC_NV12; va_status = vaCreateSurfaces(va_dpy, VA_RT_FORMAT_YUV420, surface_width, surface_height, &csc_render_surface, 1, surface_attribs, 1); CHECK_VASTATUS(va_status,"vaCreateSurfaces"); cleanup: return test_color_conversion; }
static gboolean gst_vaapi_surface_create (GstVaapiSurface * surface, GstVaapiChromaType chroma_type, guint width, guint height) { GstVaapiDisplay *const display = GST_VAAPI_OBJECT_DISPLAY (surface); VASurfaceID surface_id; VAStatus status; guint va_chroma_format; va_chroma_format = from_GstVaapiChromaType (chroma_type); if (!va_chroma_format) goto error_unsupported_chroma_type; GST_VAAPI_DISPLAY_LOCK (display); status = vaCreateSurfaces (GST_VAAPI_DISPLAY_VADISPLAY (display), width, height, va_chroma_format, 1, &surface_id); GST_VAAPI_DISPLAY_UNLOCK (display); if (!vaapi_check_status (status, "vaCreateSurfaces()")) return FALSE; surface->format = GST_VIDEO_FORMAT_UNKNOWN; surface->chroma_type = chroma_type; surface->width = width; surface->height = height; GST_DEBUG ("surface %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS (surface_id)); GST_VAAPI_OBJECT_ID (surface) = surface_id; return TRUE; /* ERRORS */ error_unsupported_chroma_type: GST_ERROR ("unsupported chroma-type %u", chroma_type); return FALSE; }
bool VAAPIContext::InitBuffers(void) { if (!m_ctx.display) return false; MythXLocker locker(m_display->m_x_disp); m_surfaces = new VASurfaceID[m_numSurfaces]; m_surfaceData = new vaapi_surface[m_numSurfaces]; if (!m_surfaces || !m_surfaceData) return false; memset(m_surfaces, 0, m_numSurfaces * sizeof(VASurfaceID)); memset(m_surfaceData, 0, m_numSurfaces * sizeof(vaapi_surface)); INIT_ST; va_status = vaCreateSurfaces(m_ctx.display, m_size.width(), m_size.height(), VA_RT_FORMAT_YUV420, m_numSurfaces, m_surfaces); CHECK_ST; for (int i = 0; i < m_numSurfaces; i++) m_surfaceData[i].m_id = m_surfaces[i]; return ok; }
static bool app_ensure_filter_surface(App *app, uint32_t width, uint32_t height) { FFVASurface * const s = &app->filter_surface; VASurfaceID va_surface; VASurfaceAttrib attrib; VAStatus va_status; if (!app->filter) return true; // VPP not needed (checked in app_ensure_filter()) if (width == s->width && height == s->height) return true; attrib.flags = VA_SURFACE_ATTRIB_SETTABLE; attrib.type = VASurfaceAttribPixelFormat; attrib.value.type = VAGenericValueTypeInteger; attrib.value.value.i = app->filter_fourcc; va_destroy_surface(app->va_display, &s->id); va_status = vaCreateSurfaces(app->va_display, app->filter_chroma, width, height, &va_surface, 1, &attrib, 1); if (!va_check_status(va_status, "vaCreateSurfaces()")) return false; ffva_surface_init(s, va_surface, app->filter_chroma, width, height); s->fourcc = app->filter_fourcc; return true; }
static float run(const char* infile, const char* outfile1, const char* outfile2, bool doInterop) { VASurfaceID surface; VAStatus status; Timer t; // initialize CL context for CL/VA interop cv::va_intel::ocl::initializeContextFromVA(va::display, doInterop); // load input image cv::UMat u1 = readImage(infile); cv::Size size2 = u1.size(); status = vaCreateSurfaces(va::display, VA_RT_FORMAT_YUV420, size2.width, size2.height, &surface, 1, NULL, 0); CHECK_VASTATUS(status, "vaCreateSurfaces"); // transfer image into VA surface, make sure all CL initialization is done (kernels etc) cv::va_intel::convertToVASurface(va::display, u1, surface, size2); cv::va_intel::convertFromVASurface(va::display, surface, size2, u1); cv::UMat u2; cv::blur(u1, u2, cv::Size(7, 7), cv::Point(-3, -3)); // measure performance on some image processing writeImage(u1, outfile1, doInterop); t.start(); cv::va_intel::convertFromVASurface(va::display, surface, size2, u1); cv::blur(u1, u2, cv::Size(7, 7), cv::Point(-3, -3)); cv::va_intel::convertToVASurface(va::display, u2, surface, size2); t.stop(); writeImage(u2, outfile2, doInterop); vaDestroySurfaces(va::display, &surface,1); return t.time(Timer::MSEC); }
static enum AVPixelFormat prepare_vaapi_context(struct pp_video_decoder_s *vd, int width, int height) { VAStatus status; vd->va_context.display = display.va; vd->va_context.config_id = VA_INVALID_ID; vd->va_context.context_id = VA_INVALID_ID; // function is called from libavcodec internals which were already protected by mutex status = vaCreateConfig(display.va, VAProfileH264High, VAEntrypointVLD, NULL, 0, &vd->va_context.config_id); if (status != VA_STATUS_SUCCESS) { trace_error("%s, can't create VA config\n", __func__); goto err; } #if VA_CHECK_VERSION(0, 34, 0) status = vaCreateSurfaces(display.va, VA_RT_FORMAT_YUV420, width, height, vd->surfaces, MAX_VIDEO_SURFACES, NULL, 0); #else status = vaCreateSurfaces(display.va, width, height, VA_RT_FORMAT_YUV420, MAX_VIDEO_SURFACES, vd->surfaces); #endif if (status != VA_STATUS_SUCCESS) { trace_error("%s, can't create VA surfaces\n", __func__); goto err; } status = vaCreateContext(display.va, vd->va_context.config_id, width, height, VA_PROGRESSIVE, vd->surfaces, MAX_VIDEO_SURFACES, &vd->va_context.context_id); if (status != VA_STATUS_SUCCESS) { trace_error("%s, can't create VA context\n", __func__); goto err; } vd->avctx->hwaccel_context = &vd->va_context; return AV_PIX_FMT_VAAPI_VLD; err: vd->failed_state = 1; vd->ppp_video_decoder_dev->NotifyError(vd->instance->id, vd->self_id, PP_VIDEODECODERERROR_UNREADABLE_INPUT); return AV_PIX_FMT_NONE; }
SharedPtr<VideoFrame> V4l2Decoder::createVaSurface(const ANativeWindowBuffer* buf) { SharedPtr<VideoFrame> frame; intel_ufo_buffer_details_t info; memset(&info, 0, sizeof(info)); *reinterpret_cast<uint32_t*>(&info) = sizeof(info); int err = 0; if (m_pGralloc) err = m_pGralloc->perform(m_pGralloc, INTEL_UFO_GRALLOC_MODULE_PERFORM_GET_BO_INFO, (buffer_handle_t)buf->handle, &info); if (0 != err || !m_pGralloc) { fprintf(stderr, "create vaSurface failed\n"); return frame; } VASurfaceAttrib attrib; memset(&attrib, 0, sizeof(attrib)); VASurfaceAttribExternalBuffers external; memset(&external, 0, sizeof(external)); external.pixel_format = VA_FOURCC_NV12; external.width = buf->width; external.height = buf->height; external.pitches[0] = info.pitch; external.num_planes = 2; external.num_buffers = 1; uint8_t* handle = (uint8_t*)buf->handle; external.buffers = (long unsigned int*)&handle; //graphic handel external.flags = VA_SURFACE_ATTRIB_MEM_TYPE_ANDROID_GRALLOC; attrib.flags = VA_SURFACE_ATTRIB_SETTABLE; attrib.type = (VASurfaceAttribType)VASurfaceAttribExternalBufferDescriptor; attrib.value.type = VAGenericValueTypePointer; attrib.value.value.p = &external; VASurfaceID id; VAStatus vaStatus = vaCreateSurfaces(m_vaDisplay, VA_RT_FORMAT_YUV420, buf->width, buf->height, &id, 1, &attrib, 1); if (vaStatus != VA_STATUS_SUCCESS) return frame; frame.reset(new VideoFrame); memset(frame.get(), 0, sizeof(VideoFrame)); frame->surface = static_cast<intptr_t>(id); frame->crop.width = buf->width; frame->crop.height = buf->height; return frame; }
VAStatus vaCreateSurfaces_0_32_0( VADisplay dpy, int width, int height, int format, int num_surfaces, VASurfaceID *surfaces ) { return vaCreateSurfaces(dpy, format, width, height, surfaces, num_surfaces, NULL, 0); }
static gboolean gst_vaapi_surface_create(GstVaapiSurface *surface) { GstVaapiDisplay * const display = GST_VAAPI_OBJECT_DISPLAY(surface); GstVaapiSurfacePrivate * const priv = surface->priv; VASurfaceID surface_id; VAStatus status; guint format; switch (priv->chroma_type) { case GST_VAAPI_CHROMA_TYPE_YUV420: format = VA_RT_FORMAT_YUV420; break; case GST_VAAPI_CHROMA_TYPE_YUV422: format = VA_RT_FORMAT_YUV422; break; case GST_VAAPI_CHROMA_TYPE_YUV444: format = VA_RT_FORMAT_YUV444; break; default: GST_DEBUG("unsupported chroma-type %u\n", priv->chroma_type); return FALSE; } GST_VAAPI_DISPLAY_LOCK(display); status = vaCreateSurfaces( GST_VAAPI_DISPLAY_VADISPLAY(display), priv->width, priv->height, format, 1, &surface_id ); GST_VAAPI_DISPLAY_UNLOCK(display); if (!vaapi_check_status(status, "vaCreateSurfaces()")) return FALSE; GST_DEBUG("surface %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS(surface_id)); GST_VAAPI_OBJECT_ID(surface) = surface_id; return TRUE; }
static AVBufferRef *vaapi_pool_alloc(void *opaque, int size) { AVHWFramesContext *hwfc = opaque; VAAPIFramesContext *ctx = hwfc->internal->priv; AVVAAPIDeviceContext *hwctx = hwfc->device_ctx->hwctx; AVVAAPIFramesContext *avfc = hwfc->hwctx; VASurfaceID surface_id; VAStatus vas; AVBufferRef *ref; vas = vaCreateSurfaces(hwctx->display, ctx->rt_format, hwfc->width, hwfc->height, &surface_id, 1, ctx->attributes, ctx->nb_attributes); if (vas != VA_STATUS_SUCCESS) { av_log(hwfc, AV_LOG_ERROR, "Failed to create surface: " "%d (%s).\n", vas, vaErrorStr(vas)); return NULL; } av_log(hwfc, AV_LOG_DEBUG, "Created surface %#x.\n", surface_id); ref = av_buffer_create((uint8_t*)(uintptr_t)surface_id, sizeof(surface_id), &vaapi_buffer_free, hwfc, AV_BUFFER_FLAG_READONLY); if (!ref) { vaDestroySurfaces(hwctx->display, &surface_id, 1); return NULL; } if (hwfc->initial_pool_size > 0) { // This is a fixed-size pool, so we must still be in the initial // allocation sequence. av_assert0(avfc->nb_surfaces < hwfc->initial_pool_size); avfc->surface_ids[avfc->nb_surfaces] = surface_id; ++avfc->nb_surfaces; } return ref; }
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 HwAccX11Trait<IMGFMT_VAAPI>::createSurfaces(int width, int height, int format, QVector<SurfaceID> &ids) { return VaApiStatusChecker().isSuccess(vaCreateSurfaces(VaApi::glx(), width, height, format, ids.size(), ids.data())); }
static int CreateSurfaces( vlc_va_vaapi_t *p_va, void **pp_hw_ctx, vlc_fourcc_t *pi_chroma, int i_width, int i_height ) { assert( i_width > 0 && i_height > 0 ); /* */ p_va->p_surface = calloc( p_va->i_surface_count, sizeof(*p_va->p_surface) ); if( !p_va->p_surface ) return VLC_EGENERIC; p_va->image.image_id = VA_INVALID_ID; p_va->i_context_id = VA_INVALID_ID; /* Create surfaces */ VASurfaceID pi_surface_id[p_va->i_surface_count]; if( vaCreateSurfaces( p_va->p_display, i_width, i_height, VA_RT_FORMAT_YUV420, p_va->i_surface_count, pi_surface_id ) ) { for( int i = 0; i < p_va->i_surface_count; i++ ) p_va->p_surface[i].i_id = VA_INVALID_SURFACE; goto error; } for( int i = 0; i < p_va->i_surface_count; i++ ) { vlc_va_surface_t *p_surface = &p_va->p_surface[i]; p_surface->i_id = pi_surface_id[i]; p_surface->i_refcount = 0; p_surface->i_order = 0; } /* Create a context */ if( vaCreateContext( p_va->p_display, p_va->i_config_id, i_width, i_height, VA_PROGRESSIVE, pi_surface_id, p_va->i_surface_count, &p_va->i_context_id ) ) { p_va->i_context_id = VA_INVALID_ID; goto error; } /* Find and create a supported image chroma */ int i_fmt_count = vaMaxNumImageFormats( p_va->p_display ); VAImageFormat *p_fmt = calloc( i_fmt_count, sizeof(*p_fmt) ); if( !p_fmt ) goto error; if( vaQueryImageFormats( p_va->p_display, p_fmt, &i_fmt_count ) ) { free( p_fmt ); goto error; } VAImage testImage; if(vaDeriveImage(p_va->p_display, pi_surface_id[0], &testImage) == VA_STATUS_SUCCESS) { p_va->b_supports_derive = true; vaDestroyImage(p_va->p_display, testImage.image_id); } vlc_fourcc_t i_chroma = 0; VAImageFormat fmt; for( int i = 0; i < i_fmt_count; i++ ) { if( p_fmt[i].fourcc == VA_FOURCC( 'Y', 'V', '1', '2' ) || p_fmt[i].fourcc == VA_FOURCC( 'I', '4', '2', '0' ) || p_fmt[i].fourcc == VA_FOURCC( 'N', 'V', '1', '2' ) ) { if( vaCreateImage( p_va->p_display, &p_fmt[i], i_width, i_height, &p_va->image ) ) { p_va->image.image_id = VA_INVALID_ID; continue; } /* Validate that vaGetImage works with this format */ if( vaGetImage( p_va->p_display, pi_surface_id[0], 0, 0, i_width, i_height, p_va->image.image_id) ) { vaDestroyImage( p_va->p_display, p_va->image.image_id ); p_va->image.image_id = VA_INVALID_ID; continue; } i_chroma = VLC_CODEC_YV12; fmt = p_fmt[i]; break; } } free( p_fmt ); if( !i_chroma ) goto error; *pi_chroma = i_chroma; if(p_va->b_supports_derive) { vaDestroyImage( p_va->p_display, p_va->image.image_id ); p_va->image.image_id = VA_INVALID_ID; } if( unlikely(CopyInitCache( &p_va->image_cache, i_width )) ) goto error; /* Setup the ffmpeg hardware context */ *pp_hw_ctx = &p_va->hw_ctx; memset( &p_va->hw_ctx, 0, sizeof(p_va->hw_ctx) ); p_va->hw_ctx.display = p_va->p_display; p_va->hw_ctx.config_id = p_va->i_config_id; p_va->hw_ctx.context_id = p_va->i_context_id; /* */ p_va->i_surface_chroma = i_chroma; p_va->i_surface_width = i_width; p_va->i_surface_height = i_height; return VLC_SUCCESS; error: DestroySurfaces( p_va ); return VLC_EGENERIC; }
int main(int argc,char **argv) { int major_ver, minor_ver; VAStatus va_status; pthread_t thread1; int ret; char c; int i; char str_src_fmt[5], str_dst_fmt[5]; static struct option long_options[] = { {"fmt1", required_argument, NULL, '1'}, {"fmt2", required_argument, NULL, '2'}, {0, 0, 0, 0} }; while ((c =getopt_long(argc,argv,"w:h:g:r:d:f:tcep?n:1:2:v", long_options, NULL)) != EOF) { switch (c) { case '?': printf("putsurface <options>\n"); printf(" -g <widthxheight+x_location+y_location> window geometry\n"); printf(" -w/-h resolution of surface\n"); printf(" -r <framerate>\n"); printf(" -d the dimension of black/write square box, default is 32\n"); printf(" -t multi-threads\n"); printf(" -c test clipbox\n"); printf(" -f <1/2> top field, or bottom field\n"); printf(" -1 source format (fourcc) for color conversion test\n"); printf(" -2 dest format (fourcc) for color conversion test\n"); printf(" --fmt1 same to -1\n"); printf(" --fmt2 same to -2\n"); printf(" -v verbose output\n"); exit(0); break; case 'g': ret = sscanf(optarg, "%dx%d+%d+%d", &win_width, &win_height, &win_x, &win_y); if (ret != 4) { printf("invalid window geometry, must be widthxheight+x_location+y_location\n"); exit(0); } else printf("Create window at (%d, %d), width = %d, height = %d\n", win_x, win_y, win_width, win_height); break; case 'r': frame_rate = atoi(optarg); break; case 'w': surface_width = atoi(optarg); break; case 'h': surface_height = atoi(optarg); break; case 'n': frame_num_total = atoi(optarg); break; case 'd': box_width = atoi(optarg); break; case 't': multi_thread = 1; printf("Two threads to do vaPutSurface\n"); break; case 'e': check_event = 0; break; case 'p': put_pixmap = 1; break; case 'c': test_clip = 1; break; case 'f': if (atoi(optarg) == 1) { printf("Display TOP field\n"); display_field = VA_TOP_FIELD; } else if (atoi(optarg) == 2) { printf("Display BOTTOM field\n"); display_field = VA_BOTTOM_FIELD; } else printf("The validate input for -f is: 1(top field)/2(bottom field)\n"); break; case '1': sscanf(optarg, "%s", str_src_fmt); csc_src_fourcc = map_str_to_vafourcc (str_src_fmt); if (!csc_src_fourcc) { printf("invalid fmt1: %s\n", str_src_fmt ); exit(0); } break; case '2': sscanf(optarg, "%s", str_dst_fmt); csc_dst_fourcc = map_str_to_vafourcc (str_dst_fmt); if (!csc_dst_fourcc) { printf("invalid fmt1: %s\n", str_dst_fmt ); exit(0); } break; case 'v': verbose = 1; printf("Enable verbose output\n"); break; } } if (csc_src_fourcc && csc_dst_fourcc) { test_color_conversion = 1; } win_display = (void *)open_display(); if (win_display == NULL) { fprintf(stderr, "Can't open the connection of display!\n"); exit(-1); } create_window(win_display, win_x, win_y, win_width, win_height); va_dpy = vaGetDisplay(win_display); va_status = vaInitialize(va_dpy, &major_ver, &minor_ver); CHECK_VASTATUS(va_status, "vaInitialize"); if (test_color_conversion) { ret = csc_preparation(); } if (!test_color_conversion || !ret ) { va_status = vaCreateSurfaces( va_dpy, VA_RT_FORMAT_YUV420, surface_width, surface_height, &surface_id[0], SURFACE_NUM, NULL, 0 ); } CHECK_VASTATUS(va_status, "vaCreateSurfaces"); if (multi_thread == 0) /* upload the content for all surfaces */ upload_source_YUV_once_for_all(); if (check_event) pthread_mutex_init(&gmutex, NULL); for(i = 0; i< SURFACE_NUM; i++) pthread_mutex_init(&surface_mutex[i], NULL); if (multi_thread == 1) ret = pthread_create(&thread1, NULL, putsurface_thread, (void*)drawable_thread1); putsurface_thread((void *)drawable_thread0); if (multi_thread == 1) pthread_join(thread1, (void **)&ret); printf("thread1 is free\n"); if (test_color_conversion) { // destroy temp surface/image va_status = vaDestroySurfaces(va_dpy, &csc_render_surface, 1); CHECK_VASTATUS(va_status,"vaDestroySurfaces"); va_status = vaDestroyImage(va_dpy, csc_dst_fourcc_image.image_id); CHECK_VASTATUS(va_status,"vaDestroyImage"); } if (vpp_config_id != VA_INVALID_ID) { vaDestroyConfig (va_dpy, vpp_config_id); vpp_config_id = VA_INVALID_ID; } vaDestroySurfaces(va_dpy,&surface_id[0],SURFACE_NUM); vaTerminate(va_dpy); free(va_image_formats); free(va_surface_attribs); close_display(win_display); return 0; }
void VAApiWriter::init_vpp() { #ifdef HAVE_VPP use_vpp = true; if ( vaCreateConfig( VADisp, ( VAProfile )-1, VAEntrypointVideoProc, NULL, 0, &config_vpp ) == VA_STATUS_SUCCESS && vaCreateContext( VADisp, config_vpp, 0, 0, 0, NULL, 0, &context_vpp ) == VA_STATUS_SUCCESS && vaCreateSurfaces( &id_vpp, 1 ) ) { unsigned num_filters = VAProcFilterCount; VAProcFilterType filters[ VAProcFilterCount ]; if ( vaQueryVideoProcFilters( VADisp, context_vpp, filters, &num_filters ) != VA_STATUS_SUCCESS ) num_filters = 0; if ( num_filters ) { /* Creating dummy filter (some drivers/api versions crashes without any filter) */ VAProcFilterParameterBufferBase none_params = { VAProcFilterNone }; if ( vaCreateBuffer( VADisp, context_vpp, VAProcFilterParameterBufferType, sizeof none_params, 1, &none_params, &vpp_buffers[ VAProcFilterNone ] ) != VA_STATUS_SUCCESS ) vpp_buffers[ VAProcFilterNone ] = VA_INVALID_ID; /* Searching deinterlacing filter */ if ( vpp_deint_type != VAProcDeinterlacingNone ) for ( unsigned i = 0 ; i < num_filters ; ++i ) if ( filters[ i ] == VAProcFilterDeinterlacing ) { VAProcFilterCapDeinterlacing deinterlacing_caps[ VAProcDeinterlacingCount ]; unsigned num_deinterlacing_caps = VAProcDeinterlacingCount; if ( vaQueryVideoProcFilterCaps( VADisp, context_vpp, VAProcFilterDeinterlacing, &deinterlacing_caps, &num_deinterlacing_caps ) != VA_STATUS_SUCCESS ) num_deinterlacing_caps = 0; bool vpp_deint_types[ 2 ] = { false }; for ( unsigned j = 0 ; j < num_deinterlacing_caps ; ++j ) { switch ( deinterlacing_caps[ j ].type ) { case VAProcDeinterlacingMotionAdaptive: vpp_deint_types[ 0 ] = true; break; case VAProcDeinterlacingMotionCompensated: vpp_deint_types[ 1 ] = true; break; default: break; } } if ( vpp_deint_type == VAProcDeinterlacingMotionCompensated && !vpp_deint_types[ 1 ] ) { QMPlay2Core.log( tr( "Nie obsługiwany algorytm usuwania przeplotu" ) + " - Motion compensated", ErrorLog | LogOnce ); vpp_deint_type = VAProcDeinterlacingMotionAdaptive; } if ( vpp_deint_type == VAProcDeinterlacingMotionAdaptive && !vpp_deint_types[ 0 ] ) { QMPlay2Core.log( tr( "Nie obsługiwany algorytm usuwania przeplotu" ) + " - Motion adaptive", ErrorLog | LogOnce ); vpp_deint_type = VAProcDeinterlacingNone; } if ( vpp_deint_type != VAProcDeinterlacingNone ) { VAProcFilterParameterBufferDeinterlacing deint_params = { VAProcFilterDeinterlacing, vpp_deint_type, 0 }; if ( vaCreateBuffer( VADisp, context_vpp, VAProcFilterParameterBufferType, sizeof deint_params, 1, &deint_params, &vpp_buffers[ VAProcFilterDeinterlacing ] ) != VA_STATUS_SUCCESS ) vpp_buffers[ VAProcFilterDeinterlacing ] = VA_INVALID_ID; } break; } return; } } if ( vpp_deint_type != VAProcDeinterlacingNone ) //Show error only when filter is required QMPlay2Core.log( "VA-API :: " + tr( "Nie można otworzyć filtrów obrazu" ), ErrorLog | LogOnce ); clr_vpp(); #endif }
OMX_ERRORTYPE OMXVideoDecoderVP9HWR::ProcessorInit(void) { unsigned int i = 0; for (i = 0; i < MAX_NATIVE_BUFFER_COUNT; i++) { extMIDs[i] = (vaapiMemId*)malloc(sizeof(vaapiMemId)); extMIDs[i]->m_usrAddr = NULL; extMIDs[i]->m_surface = new VASurfaceID; } initDecoder(); if (RAWDATA_MODE == mWorkingMode) { OMX_PARAM_PORTDEFINITIONTYPE paramPortDefinitionInput; memcpy(¶mPortDefinitionInput, this->ports[INPORT_INDEX]->GetPortDefinition(), sizeof(paramPortDefinitionInput)); extNativeBufferSize = INTERNAL_MAX_FRAME_WIDTH * INTERNAL_MAX_FRAME_HEIGHT * 1.5; extActualBufferStride = INTERNAL_MAX_FRAME_WIDTH; extActualBufferHeightStride = INTERNAL_MAX_FRAME_HEIGHT; for (i = 0; i < OUTPORT_ACTUAL_BUFFER_COUNT; i++ ) { extMIDs[i]->m_usrAddr = (unsigned char*)malloc(sizeof(unsigned char) * extNativeBufferSize); extMIDs[i]->m_render_done = true; extMIDs[i]->m_released = true; } extMappedNativeBufferCount = OUTPORT_ACTUAL_BUFFER_COUNT; return OMX_ErrorNone; } #ifdef DECODE_WITH_GRALLOC_BUFFER if (mOMXBufferHeaderTypePtrNum > MAX_NATIVE_BUFFER_COUNT) { LOGE("Actual OMX outport buffer header type num (%d) > MAX_NATIVE_BUFFER_COUNT (%d)", mOMXBufferHeaderTypePtrNum, MAX_NATIVE_BUFFER_COUNT); return OMX_ErrorOverflow; } OMX_PARAM_PORTDEFINITIONTYPE paramPortDefinitionInput; memcpy(¶mPortDefinitionInput, this->ports[INPORT_INDEX]->GetPortDefinition(), sizeof(paramPortDefinitionInput)); int surfaceWidth = mGraphicBufferParam.graphicBufferWidth; int surfaceHeight = mGraphicBufferParam.graphicBufferHeight; int surfaceStride = mGraphicBufferParam.graphicBufferStride; extNativeBufferSize = mGraphicBufferParam.graphicBufferStride * mGraphicBufferParam.graphicBufferHeight * 1.5; extActualBufferStride = surfaceStride; extActualBufferHeightStride = surfaceHeight; for (i = 0; i < mOMXBufferHeaderTypePtrNum; i++) { OMX_BUFFERHEADERTYPE *buf_hdr = mOMXBufferHeaderTypePtrArray[i]; extMIDs[i]->m_key = (unsigned int)(buf_hdr->pBuffer); extMIDs[i]->m_render_done = false; extMIDs[i]->m_released = true; VAStatus va_res; unsigned int buffer; VASurfaceAttrib attribs[2]; VASurfaceAttribExternalBuffers* surfExtBuf = new VASurfaceAttribExternalBuffers; int32_t format = VA_RT_FORMAT_YUV420; surfExtBuf->buffers= (unsigned long *)&buffer; surfExtBuf->num_buffers = 1; surfExtBuf->pixel_format = VA_FOURCC_NV12; surfExtBuf->width = surfaceWidth; surfExtBuf->height = surfaceHeight; surfExtBuf->data_size = surfaceStride * surfaceHeight * 1.5; surfExtBuf->num_planes = 2; surfExtBuf->pitches[0] = surfaceStride; surfExtBuf->pitches[1] = surfaceStride; surfExtBuf->pitches[2] = 0; surfExtBuf->pitches[3] = 0; surfExtBuf->offsets[0] = 0; surfExtBuf->offsets[1] = surfaceStride * surfaceHeight; surfExtBuf->offsets[2] = 0; surfExtBuf->offsets[3] = 0; surfExtBuf->flags = VA_SURFACE_ATTRIB_MEM_TYPE_ANDROID_GRALLOC; surfExtBuf->buffers[0] = (unsigned int)buf_hdr->pBuffer; attribs[0].type = (VASurfaceAttribType)VASurfaceAttribMemoryType; attribs[0].flags = VA_SURFACE_ATTRIB_SETTABLE; attribs[0].value.type = VAGenericValueTypeInteger; attribs[0].value.value.i = VA_SURFACE_ATTRIB_MEM_TYPE_ANDROID_GRALLOC; attribs[1].type = (VASurfaceAttribType)VASurfaceAttribExternalBufferDescriptor; attribs[1].flags = VA_SURFACE_ATTRIB_SETTABLE; attribs[1].value.type = VAGenericValueTypePointer; attribs[1].value.value.p = (void *)surfExtBuf; va_res = vaCreateSurfaces(mVADisplay, format, surfaceWidth, surfaceHeight, extMIDs[i]->m_surface, 1, attribs, 2); if (va_res != VA_STATUS_SUCCESS) { LOGE("Failed to create vaSurface!"); return OMX_ErrorUndefined; } delete surfExtBuf; VAImage image; unsigned char* usrptr; va_res = vaDeriveImage(mVADisplay, *(extMIDs[i]->m_surface), &image); if (VA_STATUS_SUCCESS == va_res) { va_res = vaMapBuffer(mVADisplay, image.buf, (void **) &usrptr); if (VA_STATUS_SUCCESS == va_res) { extMIDs[i]->m_usrAddr = usrptr; vaUnmapBuffer(mVADisplay, image.buf); } vaDestroyImage(mVADisplay, image.image_id); } extMappedNativeBufferCount++; } return OMX_ErrorNone; #endif }
mfxStatus vaapiFrameAllocator::AllocImpl(mfxFrameAllocRequest *request, mfxFrameAllocResponse *response) { mfxStatus mfx_res = MFX_ERR_NONE; VAStatus va_res = VA_STATUS_SUCCESS; unsigned int va_fourcc = 0; VASurfaceID* surfaces = NULL; VASurfaceAttrib attrib; vaapiMemId *vaapi_mids = NULL, *vaapi_mid = NULL; mfxMemId* mids = NULL; mfxU32 fourcc = request->Info.FourCC; mfxU16 surfaces_num = request->NumFrameSuggested, numAllocated = 0, i = 0; bool bCreateSrfSucceeded = false; memset(response, 0, sizeof(mfxFrameAllocResponse)); va_fourcc = ConvertMfxFourccToVAFormat(fourcc); if (!va_fourcc || ((VA_FOURCC_NV12 != va_fourcc) && (VA_FOURCC_YV12 != va_fourcc) && (VA_FOURCC_YUY2 != va_fourcc) && (VA_FOURCC_ARGB != va_fourcc) && (VA_FOURCC_P208 != va_fourcc))) { return MFX_ERR_MEMORY_ALLOC; } if (!surfaces_num) { return MFX_ERR_MEMORY_ALLOC; } if (MFX_ERR_NONE == mfx_res) { surfaces = (VASurfaceID*)calloc(surfaces_num, sizeof(VASurfaceID)); vaapi_mids = (vaapiMemId*)calloc(surfaces_num, sizeof(vaapiMemId)); mids = (mfxMemId*)calloc(surfaces_num, sizeof(mfxMemId)); if ((NULL == surfaces) || (NULL == vaapi_mids) || (NULL == mids)) mfx_res = MFX_ERR_MEMORY_ALLOC; } if (MFX_ERR_NONE == mfx_res) { if( VA_FOURCC_P208 != va_fourcc ) { attrib.type = VASurfaceAttribPixelFormat; attrib.value.type = VAGenericValueTypeInteger; attrib.value.value.i = va_fourcc; attrib.flags = VA_SURFACE_ATTRIB_SETTABLE; va_res = vaCreateSurfaces(m_dpy, VA_RT_FORMAT_YUV420, request->Info.Width, request->Info.Height, surfaces, surfaces_num, &attrib, 1); mfx_res = va_to_mfx_status(va_res); bCreateSrfSucceeded = (MFX_ERR_NONE == mfx_res); } else { VAContextID context_id = request->reserved[0]; int codedbuf_size = static_cast<int>((request->Info.Width * request->Info.Height) * 400LL / (16 * 16)); for (numAllocated = 0; numAllocated < surfaces_num; numAllocated++) { VABufferID coded_buf; va_res = vaCreateBuffer(m_dpy, context_id, VAEncCodedBufferType, codedbuf_size, 1, NULL, &coded_buf); mfx_res = va_to_mfx_status(va_res); if (MFX_ERR_NONE != mfx_res) break; surfaces[numAllocated] = coded_buf; } } } if (MFX_ERR_NONE == mfx_res) { for (i = 0; i < surfaces_num; ++i) { vaapi_mid = &(vaapi_mids[i]); vaapi_mid->m_fourcc = fourcc; vaapi_mid->m_surface = &(surfaces[i]); mids[i] = vaapi_mid; } } if (MFX_ERR_NONE == mfx_res) { response->mids = mids; response->NumFrameActual = surfaces_num; } else // i.e. MFX_ERR_NONE != mfx_res { response->mids = NULL; response->NumFrameActual = 0; if (VA_FOURCC_P208 != va_fourcc) { if (bCreateSrfSucceeded) vaDestroySurfaces(m_dpy, surfaces, surfaces_num); } else { for (i = 0; i < numAllocated; i++) vaDestroyBuffer(m_dpy, surfaces[i]); } if (mids) { free(mids); mids = NULL; } if (vaapi_mids) { free(vaapi_mids); vaapi_mids = NULL; } if (surfaces) { free(surfaces); surfaces = NULL; } } return mfx_res; }
static void h264_init_decoder(int width, int height) { VAStatus va_status; if (va_context_id) { rfbClientLog("%s: va_dpy already initialized\n", __FUNCTION__); } if (va_dpy != NULL) { rfbClientLog("%s: Re-initializing H.264 decoder\n", __FUNCTION__); } else { rfbClientLog("%s: initializing H.264 decoder\n", __FUNCTION__); /* Attach VA display to local X display */ Display *win_display = (Display *)XOpenDisplay(":0.0"); if (win_display == NULL) { rfbClientErr("Can't connect to local display\n"); exit(-1); } int major_ver, minor_ver; va_dpy = vaGetDisplay(win_display); va_status = vaInitialize(va_dpy, &major_ver, &minor_ver); CHECK_VASTATUS(va_status, "vaInitialize"); rfbClientLog("%s: libva version %d.%d found\n", __FUNCTION__, major_ver, minor_ver); } /* Check for VLD entrypoint */ int num_entrypoints; VAEntrypoint entrypoints[5]; int vld_entrypoint_found = 0; /* Change VAProfileH264High if needed */ VAProfile profile = VAProfileH264High; va_status = vaQueryConfigEntrypoints(va_dpy, profile, entrypoints, &num_entrypoints); CHECK_VASTATUS(va_status, "vaQueryConfigEntrypoints"); int i; for (i = 0; i < num_entrypoints; ++i) { if (entrypoints[i] == VAEntrypointVLD) { vld_entrypoint_found = 1; break; } } if (vld_entrypoint_found == 0) { rfbClientErr("VLD entrypoint not found\n"); exit(1); } /* Create configuration for the decode pipeline */ VAConfigAttrib attrib; attrib.type = VAConfigAttribRTFormat; va_status = vaCreateConfig(va_dpy, profile, VAEntrypointVLD, &attrib, 1, &va_config_id); CHECK_VASTATUS(va_status, "vaCreateConfig"); /* Create VA surfaces */ for (i = 0; i < SURFACE_NUM; ++i) { va_surface_id[i] = VA_INVALID_ID; va_pic_param_buf_id[i] = VA_INVALID_ID; va_mat_param_buf_id[i] = VA_INVALID_ID; va_sp_param_buf_id[i] = VA_INVALID_ID; va_d_param_buf_id[i] = VA_INVALID_ID; } va_status = vaCreateSurfaces(va_dpy, width, height, VA_RT_FORMAT_YUV420, SURFACE_NUM, &va_surface_id[0]); CHECK_VASTATUS(va_status, "vaCreateSurfaces"); for (i = 0; i < SURFACE_NUM; ++i) { DebugLog(("%s: va_surface_id[%d] = %p\n", __FUNCTION__, i, va_surface_id[i])); } /* Create VA context */ va_status = vaCreateContext(va_dpy, va_config_id, width, height, 0/*VA_PROGRESSIVE*/, &va_surface_id[0], SURFACE_NUM, &va_context_id); CHECK_VASTATUS(va_status, "vaCreateContext"); DebugLog(("%s: VA context created (id: %d)\n", __FUNCTION__, va_context_id)); /* Instantiate decode pipeline */ va_status = vaBeginPicture(va_dpy, va_context_id, va_surface_id[0]); CHECK_VASTATUS(va_status, "vaBeginPicture"); rfbClientLog("%s: H.264 decoder initialized\n", __FUNCTION__); }
int vaapi_init_decoder(VAProfile profile, VAEntrypoint entrypoint, unsigned int picture_width, unsigned int picture_height) { VAAPIContext * const vaapi = vaapi_get_context(); VAConfigAttrib attrib; VAConfigID config_id = 0; VAContextID context_id = 0; VASurfaceID surface_id = 0; VAStatus status; if (!vaapi) return -1; #if 0 if (common_init_decoder(picture_width, picture_height) < 0) return -1; #endif if (!has_profile(vaapi, profile)) return -1; if (!has_entrypoint(vaapi, profile, entrypoint)) return -1; if (vaapi->profile != profile || vaapi->entrypoint != entrypoint) { if (vaapi->config_id) vaDestroyConfig(vaapi->display, vaapi->config_id); attrib.type = VAConfigAttribRTFormat; status = vaGetConfigAttributes(vaapi->display, profile, entrypoint, &attrib, 1); if (!vaapi_check_status(status, "vaGetConfigAttributes()")) return -1; if ((attrib.value & VA_RT_FORMAT_YUV420) == 0) return -1; status = vaCreateConfig(vaapi->display, profile, entrypoint, &attrib, 1, &config_id); if (!vaapi_check_status(status, "vaCreateConfig()")) return -1; } else config_id = vaapi->config_id; if (vaapi->picture_width != picture_width || vaapi->picture_height != picture_height) { if (vaapi->surface_id) vaDestroySurfaces(vaapi->display, &vaapi->surface_id, 1); status = vaCreateSurfaces(vaapi->display, picture_width, picture_height, VA_RT_FORMAT_YUV420, 1, &surface_id); if (!vaapi_check_status(status, "vaCreateSurfaces()")) return -1; if (vaapi->context_id) vaDestroyContext(vaapi->display, vaapi->context_id); status = vaCreateContext(vaapi->display, config_id, picture_width, picture_height, VA_PROGRESSIVE, &surface_id, 1, &context_id); if (!vaapi_check_status(status, "vaCreateContext()")) return -1; } else { context_id = vaapi->context_id; surface_id = vaapi->surface_id; } vaapi->config_id = config_id; vaapi->context_id = context_id; vaapi->surface_id = surface_id; vaapi->profile = profile; vaapi->entrypoint = entrypoint; vaapi->picture_width = picture_width; vaapi->picture_height = picture_height; return 0; }
bool VAApiWriter::HWAccellInit( int W, int H, const char *codec_name ) { VAProfile p = ( VAProfile )-1; //VAProfileNone if ( !qstrcmp( codec_name, "h264" ) ) { if ( profileList.contains( VAProfileH264High ) ) p = VAProfileH264High; else if ( profileList.contains( VAProfileH264Main ) ) p = VAProfileH264Main; else if ( profileList.contains( VAProfileH264Baseline ) ) p = VAProfileH264Baseline; } else if ( !qstrcmp( codec_name, "mpeg2video" ) ) { if ( profileList.contains( VAProfileMPEG2Main ) ) p = VAProfileMPEG2Main; else if ( profileList.contains( VAProfileMPEG2Simple ) ) p = VAProfileMPEG2Simple; } else if ( !qstrcmp( codec_name, "mpeg4" ) ) { if ( profileList.contains( VAProfileMPEG4Main ) ) p = VAProfileMPEG4Main; else if ( profileList.contains( VAProfileMPEG4Simple ) ) p = VAProfileMPEG4Simple; } else if ( !qstrcmp( codec_name, "vc1" ) ) { if ( profileList.contains( VAProfileVC1Advanced ) ) p = VAProfileVC1Advanced; else if ( profileList.contains( VAProfileVC1Main ) ) p = VAProfileVC1Main; else if ( profileList.contains( VAProfileVC1Simple ) ) p = VAProfileVC1Simple; } else if ( !qstrcmp( codec_name, "h263" ) && profileList.contains( VAProfileH263Baseline ) ) p = VAProfileH263Baseline; if ( !ok || profile != p || outW != W || outH != H ) { clr(); profile = p; outW = W; outH = H; if ( !vaCreateSurfaces( surfaces, surfacesCount ) ) return false; surfacesCreated = true; if ( !vaCreateConfigAndContext() ) return false; for ( int i = 0 ; i < surfacesCount ; i++ ) surfacesQueue.enqueue( surfaces[ i ] ); unsigned numSubpicFmts = vaMaxNumSubpictureFormats( VADisp ); VAImageFormat subpicFmtList[ numSubpicFmts ]; unsigned subpic_flags[ numSubpicFmts ]; if ( vaQuerySubpictureFormats( VADisp, subpicFmtList, subpic_flags, &numSubpicFmts ) == VA_STATUS_SUCCESS ) { for ( unsigned i = 0 ; i < numSubpicFmts ; ++i ) if ( !qstrncmp( ( const char * )&subpicFmtList[ i ].fourcc, "BGRA", 4 ) ) { subpict_dest_is_screen_coord = subpic_flags[ i ] & VA_SUBPICTURE_DESTINATION_IS_SCREEN_COORD; rgbImgFmt = new VAImageFormat( subpicFmtList[ i ] ); break; } } init_vpp(); if ( isXvBA ) { QWidget::destroy(); QWidget::create(); } ok = true; } else { #ifdef HAVE_VPP forward_reference = VA_INVALID_SURFACE; vpp_second = false; #endif if ( isVDPAU ) { if ( context ) { vaDestroyContext( VADisp, context ); context = 0; } if ( config ) { vaDestroyConfig( VADisp, config ); config = 0; } if ( !vaCreateConfigAndContext() ) return false; } } return ok; }
static gboolean gst_vaapi_surface_create_full (GstVaapiSurface * surface, const GstVideoInfo * vip, guint flags) { #if VA_CHECK_VERSION(0,34,0) GstVaapiDisplay *const display = GST_VAAPI_OBJECT_DISPLAY (surface); const GstVideoFormat format = GST_VIDEO_INFO_FORMAT (vip); VASurfaceID surface_id; VAStatus status; guint chroma_type, va_chroma_format, i; const VAImageFormat *va_format; VASurfaceAttrib attribs[3], *attrib; VASurfaceAttribExternalBuffers extbuf; gboolean extbuf_needed = FALSE; va_format = gst_vaapi_video_format_to_va_format (format); if (!va_format) goto error_unsupported_format; chroma_type = gst_vaapi_video_format_get_chroma_type (format); if (!chroma_type) goto error_unsupported_format; va_chroma_format = from_GstVaapiChromaType (chroma_type); if (!va_chroma_format) goto error_unsupported_format; memset (&extbuf, 0, sizeof (extbuf)); extbuf.pixel_format = va_format->fourcc; extbuf.width = GST_VIDEO_INFO_WIDTH (vip); extbuf.height = GST_VIDEO_INFO_HEIGHT (vip); extbuf_needed = ! !(flags & GST_VAAPI_SURFACE_ALLOC_FLAG_LINEAR_STORAGE); extbuf.num_planes = GST_VIDEO_INFO_N_PLANES (vip); if (flags & GST_VAAPI_SURFACE_ALLOC_FLAG_FIXED_STRIDES) { for (i = 0; i < extbuf.num_planes; i++) extbuf.pitches[i] = GST_VIDEO_INFO_PLANE_STRIDE (vip, i); extbuf_needed = TRUE; } if (flags & GST_VAAPI_SURFACE_ALLOC_FLAG_FIXED_OFFSETS) { for (i = 0; i < extbuf.num_planes; i++) extbuf.offsets[i] = GST_VIDEO_INFO_PLANE_OFFSET (vip, i); extbuf_needed = TRUE; } attrib = attribs; attrib->flags = VA_SURFACE_ATTRIB_SETTABLE; attrib->type = VASurfaceAttribPixelFormat; attrib->value.type = VAGenericValueTypeInteger; attrib->value.value.i = va_format->fourcc; attrib++; if (extbuf_needed) { attrib->flags = VA_SURFACE_ATTRIB_SETTABLE; attrib->type = VASurfaceAttribMemoryType; attrib->value.type = VAGenericValueTypeInteger; attrib->value.value.i = VA_SURFACE_ATTRIB_MEM_TYPE_VA; attrib++; attrib->flags = VA_SURFACE_ATTRIB_SETTABLE; attrib->type = VASurfaceAttribExternalBufferDescriptor; attrib->value.type = VAGenericValueTypePointer; attrib->value.value.p = &extbuf; attrib++; } GST_VAAPI_DISPLAY_LOCK (display); status = vaCreateSurfaces (GST_VAAPI_DISPLAY_VADISPLAY (display), va_chroma_format, extbuf.width, extbuf.height, &surface_id, 1, attribs, attrib - attribs); GST_VAAPI_DISPLAY_UNLOCK (display); if (!vaapi_check_status (status, "vaCreateSurfaces()")) return FALSE; surface->format = format; surface->chroma_type = chroma_type; surface->width = extbuf.width; surface->height = extbuf.height; GST_DEBUG ("surface %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS (surface_id)); GST_VAAPI_OBJECT_ID (surface) = surface_id; return TRUE; /* ERRORS */ error_unsupported_format: GST_ERROR ("unsupported format %s", gst_vaapi_video_format_to_string (format)); return FALSE; #else return FALSE; #endif }
void VAApiWriter::init_vpp() { #ifdef HAVE_VPP use_vpp = true; if ( vaCreateConfig( VADisp, ( VAProfile )-1, VAEntrypointVideoProc, NULL, 0, &config_vpp ) == VA_STATUS_SUCCESS && vaCreateContext( VADisp, config_vpp, 0, 0, 0, NULL, 0, &context_vpp ) == VA_STATUS_SUCCESS && vaCreateSurfaces( &id_vpp, 1 ) ) { unsigned num_filters = VAProcFilterCount; VAProcFilterType filters[ VAProcFilterCount ]; if ( vaQueryVideoProcFilters( VADisp, context_vpp, filters, &num_filters ) != VA_STATUS_SUCCESS ) num_filters = 0; if ( num_filters ) { if ( vpp_deint_type != VAProcDeinterlacingNone ) for ( unsigned i = 0 ; i < num_filters ; ++i ) if ( filters[ i ] == VAProcFilterDeinterlacing ) { VAProcFilterCapDeinterlacing deinterlacing_caps[ VAProcDeinterlacingCount ]; unsigned num_deinterlacing_caps = VAProcDeinterlacingCount; if ( vaQueryVideoProcFilterCaps( VADisp, context_vpp, VAProcFilterDeinterlacing, &deinterlacing_caps, &num_deinterlacing_caps ) != VA_STATUS_SUCCESS ) num_deinterlacing_caps = 0; bool vpp_deint_types[ 2 ] = { false }; for ( unsigned j = 0 ; j < num_deinterlacing_caps ; ++j ) { switch ( deinterlacing_caps[ j ].type ) { case VAProcDeinterlacingMotionAdaptive: vpp_deint_types[ 0 ] = true; break; case VAProcDeinterlacingMotionCompensated: vpp_deint_types[ 1 ] = true; break; default: break; } } if ( vpp_deint_type == VAProcDeinterlacingMotionCompensated && !vpp_deint_types[ 1 ] ) { QMPlay2Core.log( tr( "Nie obsługiwany algorytm usuwania przeplotu" ) + " - Motion compensated", ErrorLog | LogOnce ); vpp_deint_type = VAProcDeinterlacingMotionAdaptive; } if ( vpp_deint_type == VAProcDeinterlacingMotionAdaptive && !vpp_deint_types[ 0 ] ) { QMPlay2Core.log( tr( "Nie obsługiwany algorytm usuwania przeplotu" ) + " - Motion adaptive", ErrorLog | LogOnce ); vpp_deint_type = VAProcDeinterlacingNone; } if ( vpp_deint_type != VAProcDeinterlacingNone ) { VAProcFilterParameterBufferDeinterlacing deint_params = { VAProcFilterDeinterlacing, vpp_deint_type, VPP_TFF }; if ( vaCreateBuffer( VADisp, context_vpp, VAProcFilterParameterBufferType, sizeof deint_params, 1, &deint_params, &vpp_deint ) != VA_STATUS_SUCCESS ) vpp_deint = VA_INVALID_ID; } break; } return; } } if ( vpp_deint_type != VAProcDeinterlacingNone ) QMPlay2Core.log( tr( "Nie można otworzyć filtrów usuwających przeplot" ), ErrorLog | LogOnce ); clr_vpp(); #endif }
static gboolean gst_vaapi_surface_create_from_buffer_proxy (GstVaapiSurface * surface, GstVaapiBufferProxy * proxy, const GstVideoInfo * vip) { #if VA_CHECK_VERSION (0,36,0) GstVaapiDisplay *const display = GST_VAAPI_OBJECT_DISPLAY (surface); GstVideoFormat format; VASurfaceID surface_id; VAStatus status; guint chroma_type, va_chroma_format; const VAImageFormat *va_format; VASurfaceAttrib attribs[2], *attrib; VASurfaceAttribExternalBuffers extbuf; unsigned long extbuf_handle; guint i, width, height; format = GST_VIDEO_INFO_FORMAT (vip); width = GST_VIDEO_INFO_WIDTH (vip); height = GST_VIDEO_INFO_HEIGHT (vip); gst_vaapi_buffer_proxy_replace (&surface->extbuf_proxy, proxy); va_format = gst_vaapi_video_format_to_va_format (format); if (!va_format) goto error_unsupported_format; chroma_type = gst_vaapi_video_format_get_chroma_type (format); if (!chroma_type) goto error_unsupported_format; va_chroma_format = from_GstVaapiChromaType (chroma_type); if (!va_chroma_format) goto error_unsupported_format; extbuf_handle = GST_VAAPI_BUFFER_PROXY_HANDLE (proxy); extbuf.pixel_format = va_format->fourcc; extbuf.width = width; extbuf.height = height; extbuf.data_size = GST_VAAPI_BUFFER_PROXY_SIZE (proxy); extbuf.num_planes = GST_VIDEO_INFO_N_PLANES (vip); for (i = 0; i < extbuf.num_planes; i++) { extbuf.pitches[i] = GST_VIDEO_INFO_PLANE_STRIDE (vip, i); extbuf.offsets[i] = GST_VIDEO_INFO_PLANE_OFFSET (vip, i); } extbuf.buffers = &extbuf_handle; extbuf.num_buffers = 1; extbuf.flags = 0; extbuf.private_data = NULL; attrib = attribs; attrib->type = VASurfaceAttribExternalBufferDescriptor; attrib->flags = VA_SURFACE_ATTRIB_SETTABLE; attrib->value.type = VAGenericValueTypePointer; attrib->value.value.p = &extbuf; attrib++; attrib->type = VASurfaceAttribMemoryType; attrib->flags = VA_SURFACE_ATTRIB_SETTABLE; attrib->value.type = VAGenericValueTypeInteger; attrib->value.value.i = from_GstVaapiBufferMemoryType (GST_VAAPI_BUFFER_PROXY_TYPE (proxy)); attrib++; GST_VAAPI_DISPLAY_LOCK (display); status = vaCreateSurfaces (GST_VAAPI_DISPLAY_VADISPLAY (display), va_chroma_format, width, height, &surface_id, 1, attribs, attrib - attribs); GST_VAAPI_DISPLAY_UNLOCK (display); if (!vaapi_check_status (status, "vaCreateSurfaces()")) return FALSE; surface->format = format; surface->chroma_type = chroma_type; surface->width = width; surface->height = height; GST_DEBUG ("surface %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS (surface_id)); GST_VAAPI_OBJECT_ID (surface) = surface_id; return TRUE; /* ERRORS */ error_unsupported_format: GST_ERROR ("unsupported format %s", gst_vaapi_video_format_to_string (format)); return FALSE; #else return FALSE; #endif }
static int Create( vlc_va_t *va, AVCodecContext *ctx, enum PixelFormat pix_fmt, const es_format_t *fmt, picture_sys_t *p_sys ) { if( pix_fmt != AV_PIX_FMT_VAAPI_VLD ) return VLC_EGENERIC; (void) fmt; (void) p_sys; #ifdef VLC_VA_BACKEND_XLIB if( !vlc_xlib_init( VLC_OBJECT(va) ) ) { msg_Warn( va, "Ignoring VA-X11 API" ); return VLC_EGENERIC; } #endif VAProfile i_profile, *p_profiles_list; bool b_supported_profile = false; int i_profiles_nb = 0; unsigned count = 3; /* */ switch( ctx->codec_id ) { case AV_CODEC_ID_MPEG1VIDEO: case AV_CODEC_ID_MPEG2VIDEO: i_profile = VAProfileMPEG2Main; count = 4; break; case AV_CODEC_ID_MPEG4: i_profile = VAProfileMPEG4AdvancedSimple; break; case AV_CODEC_ID_WMV3: i_profile = VAProfileVC1Main; break; case AV_CODEC_ID_VC1: i_profile = VAProfileVC1Advanced; break; case AV_CODEC_ID_H264: i_profile = VAProfileH264High; count = 18; break;; default: return VLC_EGENERIC; } count += ctx->thread_count; vlc_va_sys_t *sys; void *mem; assert(popcount(sizeof (sys->surfaces)) == 1); if (unlikely(posix_memalign(&mem, sizeof (sys->surfaces), sizeof (*sys)))) return VLC_ENOMEM; sys = mem; memset(sys, 0, sizeof (*sys)); /* */ sys->hw_ctx.display = NULL; sys->hw_ctx.config_id = VA_INVALID_ID; sys->hw_ctx.context_id = VA_INVALID_ID; sys->width = ctx->coded_width; sys->height = ctx->coded_height; sys->count = count; sys->available = (1 << sys->count) - 1; assert(count < sizeof (sys->available) * CHAR_BIT); assert(count * sizeof (sys->surfaces[0]) <= sizeof (sys->surfaces)); /* Create a VA display */ #ifdef VLC_VA_BACKEND_XLIB sys->p_display_x11 = XOpenDisplay(NULL); if( !sys->p_display_x11 ) { msg_Err( va, "Could not connect to X server" ); goto error; } sys->hw_ctx.display = vaGetDisplay(sys->p_display_x11); #endif #ifdef VLC_VA_BACKEND_DRM sys->drm_fd = vlc_open("/dev/dri/card0", O_RDWR); if( sys->drm_fd == -1 ) { msg_Err( va, "Could not access rendering device: %m" ); goto error; } sys->hw_ctx.display = vaGetDisplayDRM(sys->drm_fd); #endif if (sys->hw_ctx.display == NULL) { msg_Err( va, "Could not get a VAAPI device" ); goto error; } int major, minor; if (vaInitialize(sys->hw_ctx.display, &major, &minor)) { msg_Err( va, "Failed to initialize the VAAPI device" ); goto error; } /* Check if the selected profile is supported */ i_profiles_nb = vaMaxNumProfiles(sys->hw_ctx.display); p_profiles_list = calloc( i_profiles_nb, sizeof( VAProfile ) ); if( !p_profiles_list ) goto error; if (vaQueryConfigProfiles(sys->hw_ctx.display, p_profiles_list, &i_profiles_nb) == VA_STATUS_SUCCESS) { for( int i = 0; i < i_profiles_nb; i++ ) { if ( p_profiles_list[i] == i_profile ) { b_supported_profile = true; break; } } } free( p_profiles_list ); if ( !b_supported_profile ) { msg_Dbg( va, "Codec and profile not supported by the hardware" ); goto error; } /* Create a VA configuration */ VAConfigAttrib attrib; memset( &attrib, 0, sizeof(attrib) ); attrib.type = VAConfigAttribRTFormat; if (vaGetConfigAttributes(sys->hw_ctx.display, i_profile, VAEntrypointVLD, &attrib, 1)) goto error; /* Not sure what to do if not, I don't have a way to test */ if( (attrib.value & VA_RT_FORMAT_YUV420) == 0 ) goto error; if (vaCreateConfig(sys->hw_ctx.display, i_profile, VAEntrypointVLD, &attrib, 1, &sys->hw_ctx.config_id)) { sys->hw_ctx.config_id = VA_INVALID_ID; goto error; } /* Create surfaces */ assert(ctx->coded_width > 0 && ctx->coded_height > 0); if (vaCreateSurfaces(sys->hw_ctx.display, VA_RT_FORMAT_YUV420, ctx->coded_width, ctx->coded_height, sys->surfaces, sys->count, NULL, 0)) { goto error; } /* Create a context */ if (vaCreateContext(sys->hw_ctx.display, sys->hw_ctx.config_id, ctx->coded_width, ctx->coded_height, VA_PROGRESSIVE, sys->surfaces, sys->count, &sys->hw_ctx.context_id)) { sys->hw_ctx.context_id = VA_INVALID_ID; vaDestroySurfaces(sys->hw_ctx.display, sys->surfaces, sys->count); goto error; } if (FindFormat(sys)) goto error; if (unlikely(CopyInitCache(&sys->image_cache, ctx->coded_width))) goto error; vlc_mutex_init(&sys->lock); msg_Dbg(va, "using %s image format 0x%08x", sys->do_derive ? "derive" : "get", sys->format.fourcc); ctx->hwaccel_context = &sys->hw_ctx; va->sys = sys; va->description = vaQueryVendorString(sys->hw_ctx.display); va->get = Get; va->release = Release; va->extract = Extract; return VLC_SUCCESS; error: if (sys->hw_ctx.context_id != VA_INVALID_ID) { vaDestroyContext(sys->hw_ctx.display, sys->hw_ctx.context_id); vaDestroySurfaces(sys->hw_ctx.display, sys->surfaces, sys->count); } if (sys->hw_ctx.config_id != VA_INVALID_ID) vaDestroyConfig(sys->hw_ctx.display, sys->hw_ctx.config_id); if (sys->hw_ctx.display != NULL) vaTerminate(sys->hw_ctx.display); #ifdef VLC_VA_BACKEND_XLIB if( sys->p_display_x11 != NULL ) XCloseDisplay( sys->p_display_x11 ); #endif #ifdef VLC_VA_BACKEND_DRM if( sys->drm_fd != -1 ) close( sys->drm_fd ); #endif free( sys ); return VLC_EGENERIC; }
VdpStatus softVdpDecoderCreate(VdpDevice device, VdpDecoderProfile profile, uint32_t width, uint32_t height, uint32_t max_references, VdpDecoder *decoder) { VdpStatus err_code; if (!decoder) return VDP_STATUS_INVALID_POINTER; VdpDeviceData *deviceData = handle_acquire(device, HANDLETYPE_DEVICE); if (NULL == deviceData) return VDP_STATUS_INVALID_HANDLE; if (!deviceData->va_available) { err_code = VDP_STATUS_INVALID_DECODER_PROFILE; goto quit; } VADisplay va_dpy = deviceData->va_dpy; VdpDecoderData *data = calloc(1, sizeof(VdpDecoderData)); if (NULL == data) { err_code = VDP_STATUS_RESOURCES; goto quit; } data->type = HANDLETYPE_DECODER; data->device = deviceData; data->profile = profile; data->width = width; data->height = height; data->max_references = max_references; // initialize free_list. Initially they all free data->free_list_head = -1; for (int k = 0; k < MAX_RENDER_TARGETS; k ++) { free_list_push(data->free_list, &data->free_list_head, k); } VAProfile va_profile; VAStatus status; int final_try = 0; VdpDecoderProfile next_profile = profile; // Try to create decoder for asked profile. On failure try to create more advanced one while (! final_try) { profile = next_profile; switch (profile) { case VDP_DECODER_PROFILE_H264_BASELINE: va_profile = VAProfileH264Baseline; data->num_render_targets = NUM_RENDER_TARGETS_H264; next_profile = VDP_DECODER_PROFILE_H264_MAIN; break; case VDP_DECODER_PROFILE_H264_MAIN: va_profile = VAProfileH264Main; data->num_render_targets = NUM_RENDER_TARGETS_H264; next_profile = VDP_DECODER_PROFILE_H264_HIGH; break; case VDP_DECODER_PROFILE_H264_HIGH: va_profile = VAProfileH264High; data->num_render_targets = NUM_RENDER_TARGETS_H264; // there is no more advanced profile, so it's final try final_try = 1; break; default: traceError("error (softVdpDecoderCreate): decoder %s not implemented\n", reverse_decoder_profile(profile)); err_code = VDP_STATUS_INVALID_DECODER_PROFILE; goto quit_free_data; } status = vaCreateConfig(va_dpy, va_profile, VAEntrypointVLD, NULL, 0, &data->config_id); if (VA_STATUS_SUCCESS == status) // break loop if decoder created break; } if (VA_STATUS_SUCCESS != status) { err_code = VDP_STATUS_ERROR; goto quit_free_data; } // Create surfaces. All video surfaces created here, rather than in VdpVideoSurfaceCreate. // VAAPI requires surfaces to be bound with context on its creation time, while VDPAU allows // to do it later. So here is a trick: VDP video surfaces get their va_surf dynamically in // DecoderRender. // TODO: check format of surfaces created #if VA_CHECK_VERSION(0, 34, 0) status = vaCreateSurfaces(va_dpy, VA_RT_FORMAT_YUV420, width, height, data->render_targets, data->num_render_targets, NULL, 0); #else status = vaCreateSurfaces(va_dpy, width, height, VA_RT_FORMAT_YUV420, data->num_render_targets, data->render_targets); #endif if (VA_STATUS_SUCCESS != status) { err_code = VDP_STATUS_ERROR; goto quit_free_data; } status = vaCreateContext(va_dpy, data->config_id, width, height, VA_PROGRESSIVE, data->render_targets, data->num_render_targets, &data->context_id); if (VA_STATUS_SUCCESS != status) { err_code = VDP_STATUS_ERROR; goto quit_free_data; } deviceData->refcount ++; *decoder = handle_insert(data); err_code = VDP_STATUS_OK; goto quit; quit_free_data: free(data); quit: handle_release(device); return err_code; }
int main(int argc,char **argv) { int major_ver, minor_ver; VAStatus va_status; pthread_t thread1; int ret; char c; int i; while ((c =getopt(argc,argv,"w:h:g:r:d:f:tcep?n:v") ) != EOF) { switch (c) { case '?': printf("putsurface <options>\n"); printf(" -g <widthxheight+x_location+y_location> window geometry\n"); printf(" -w/-h resolution of surface\n"); printf(" -r <framerate>\n"); printf(" -d the dimension of black/write square box, default is 32\n"); printf(" -t multi-threads\n"); printf(" -c test clipbox\n"); printf(" -f <1/2> top field, or bottom field\n"); printf(" -v verbose output\n"); exit(0); break; case 'g': ret = sscanf(optarg, "%dx%d+%d+%d", &win_width, &win_height, &win_x, &win_y); if (ret != 4) { printf("invalid window geometry, must be widthxheight+x_location+y_location\n"); exit(0); } else printf("Create window at (%d, %d), width = %d, height = %d\n", win_x, win_y, win_width, win_height); break; case 'r': frame_rate = atoi(optarg); break; case 'w': surface_width = atoi(optarg); break; case 'h': surface_height = atoi(optarg); break; case 'n': frame_num_total = atoi(optarg); break; case 'd': box_width = atoi(optarg); break; case 't': multi_thread = 1; printf("Two threads to do vaPutSurface\n"); break; case 'e': check_event = 0; break; case 'p': put_pixmap = 1; break; case 'c': test_clip = 1; break; case 'f': if (atoi(optarg) == 1) { printf("Display TOP field\n"); display_field = VA_TOP_FIELD; } else if (atoi(optarg) == 2) { printf("Display BOTTOM field\n"); display_field = VA_BOTTOM_FIELD; } else printf("The validate input for -f is: 1(top field)/2(bottom field)\n"); break; case 'v': verbose = 1; printf("Enable verbose output\n"); break; } } win_display = (void *)open_display(); if (win_display == NULL) { fprintf(stderr, "Can't open the connection of display!\n"); exit(-1); } create_window(win_display, win_x, win_y, win_width, win_height); va_dpy = vaGetDisplay(win_display); va_status = vaInitialize(va_dpy, &major_ver, &minor_ver); CHECK_VASTATUS(va_status, "vaInitialize"); va_status = vaCreateSurfaces(va_dpy,surface_width, surface_height, VA_RT_FORMAT_YUV420, SURFACE_NUM, &surface_id[0]); CHECK_VASTATUS(va_status, "vaCreateSurfaces"); if (multi_thread == 0) /* upload the content for all surfaces */ upload_source_YUV_once_for_all(); if (check_event) pthread_mutex_init(&gmutex, NULL); for(i = 0; i< SURFACE_NUM; i++) pthread_mutex_init(&surface_mutex[i], NULL); if (multi_thread == 1) ret = pthread_create(&thread1, NULL, putsurface_thread, (void*)drawable_thread1); putsurface_thread((void *)drawable_thread0); if (multi_thread == 1) pthread_join(thread1, (void **)&ret); printf("thread1 is free\n"); vaDestroySurfaces(va_dpy,&surface_id[0],SURFACE_NUM); vaTerminate(va_dpy); close_display(win_display); return 0; }