/**
 * gst_vaapi_surface_put_image:
 * @surface: a #GstVaapiSurface
 * @image: a #GstVaapiImage
 *
 * Copies data from a #GstVaapiImage into a @surface. The @image must
 * have a format supported by the @surface.
 *
 * Return value: %TRUE on success
 */
gboolean
gst_vaapi_surface_put_image (GstVaapiSurface * surface, GstVaapiImage * image)
{
  GstVaapiDisplay *display;
  VAImageID image_id;
  VAStatus status;
  guint width, height;

  g_return_val_if_fail (surface != NULL, FALSE);
  g_return_val_if_fail (image != NULL, FALSE);

  display = GST_VAAPI_OBJECT_DISPLAY (surface);
  if (!display)
    return FALSE;

  width = GST_VAAPI_IMAGE_WIDTH (image);
  height = GST_VAAPI_IMAGE_HEIGHT (image);
  if (width != surface->width || height != surface->height)
    return FALSE;

  image_id = GST_VAAPI_OBJECT_ID (image);
  if (image_id == VA_INVALID_ID)
    return FALSE;

  GST_VAAPI_DISPLAY_LOCK (display);
  status = vaPutImage (GST_VAAPI_DISPLAY_VADISPLAY (display),
      GST_VAAPI_OBJECT_ID (surface), image_id, 0, 0, width, height,
      0, 0, width, height);
  GST_VAAPI_DISPLAY_UNLOCK (display);
  if (!vaapi_check_status (status, "vaPutImage()"))
    return FALSE;

  return TRUE;
}
예제 #2
0
static void vaapi_unmap_frame(void *opaque, uint8_t *data)
{
    AVHWFramesContext *hwfc = opaque;
    AVVAAPIDeviceContext *hwctx = hwfc->device_ctx->hwctx;
    VAAPISurfaceMap *map = (VAAPISurfaceMap*)data;
    const AVFrame *src;
    VASurfaceID surface_id;
    VAStatus vas;

    src = map->source;
    surface_id = (VASurfaceID)(uintptr_t)src->data[3];
    av_log(hwfc, AV_LOG_DEBUG, "Unmap surface %#x.\n", surface_id);

    vas = vaUnmapBuffer(hwctx->display, map->image.buf);
    if (vas != VA_STATUS_SUCCESS) {
        av_log(hwfc, AV_LOG_ERROR, "Failed to unmap image from surface "
               "%#x: %d (%s).\n", surface_id, vas, vaErrorStr(vas));
    }

    if ((map->flags & VAAPI_MAP_WRITE) &&
        !(map->flags & VAAPI_MAP_DIRECT)) {
        vas = vaPutImage(hwctx->display, surface_id, map->image.image_id,
                         0, 0, hwfc->width, hwfc->height,
                         0, 0, hwfc->width, hwfc->height);
        if (vas != VA_STATUS_SUCCESS) {
            av_log(hwfc, AV_LOG_ERROR, "Failed to write image to surface "
                   "%#x: %d (%s).\n", surface_id, vas, vaErrorStr(vas));
        }
    }

    vas = vaDestroyImage(hwctx->display, map->image.image_id);
    if (vas != VA_STATUS_SUCCESS) {
        av_log(hwfc, AV_LOG_ERROR, "Failed to destroy image from surface "
               "%#x: %d (%s).\n", surface_id, vas, vaErrorStr(vas));
    }

    av_free(map);
}
예제 #3
0
static void* putsurface_thread(void *data)
{
    int width=win_width, height=win_height;
    void *drawable = data;
    int quit = 0;
    VAStatus vaStatus;
    int row_shift = 0;
    int index = 0;
    unsigned int frame_num=0, start_time, putsurface_time;
    VARectangle cliprects[2]; /* client supplied clip list */
    int continue_display = 0;
    
    if (drawable == drawable_thread0)
        printf("Enter into thread0\n\n");
    if (drawable == drawable_thread1)
        printf("Enter into thread1\n\n");
    
    putsurface_time = 0;
    while (!quit) {
        VASurfaceID surface_id = VA_INVALID_SURFACE;
        
        while (surface_id == VA_INVALID_SURFACE)
            surface_id = get_next_free_surface(&index);

        if (verbose) printf("Thread: %p Display surface 0x%x,\n", drawable, surface_id);

        if (multi_thread)
            upload_surface(va_dpy, surface_id, box_width, row_shift, display_field);

        if (check_event)
            pthread_mutex_lock(&gmutex);
        
        start_time = get_tick_count();
	if ((continue_display == 0) && getenv("FRAME_STOP")) {
            char c;
            printf("Press any key to display frame %d...(c/C to continue)\n", frame_num);
            c = getchar();
            if (c == 'c' || c == 'C')
                continue_display = 1;
        }
        if (test_color_conversion) {
            static int _put_surface_count = 0;
            if (_put_surface_count++ %50 == 0) {
                printf("do additional colorcoversion from %s to %s\n", map_vafourcc_to_str(csc_src_fourcc), map_vafourcc_to_str(csc_dst_fourcc));
            }
            // get image from surface, csc_src_fourcc to csc_dst_fourcc conversion happens
            vaStatus = vaGetImage(va_dpy, surface_id, 0, 0, 
                surface_width, surface_height, csc_dst_fourcc_image.image_id);
            CHECK_VASTATUS(vaStatus,"vaGetImage");
            
            // render csc_dst_fourcc image to temp surface
            vaStatus = vaPutImage(va_dpy, csc_render_surface, csc_dst_fourcc_image.image_id,
                                    0, 0, surface_width, surface_height, 
                                    0, 0, surface_width, surface_height);
            CHECK_VASTATUS(vaStatus,"vaPutImage");
            
            // render the temp surface, it should be same with original surface without color conversion test
            vaStatus = vaPutSurface(va_dpy, csc_render_surface, CAST_DRAWABLE(drawable),
                                    0,0,surface_width,surface_height,
                                    0,0,width,height,
                                    (test_clip==0)?NULL:&cliprects[0],
                                    (test_clip==0)?0:2,
                                    display_field);
            CHECK_VASTATUS(vaStatus,"vaPutSurface");
    
        }
        else {
            vaStatus = vaPutSurface(va_dpy, surface_id, CAST_DRAWABLE(drawable),
                                    0,0,surface_width,surface_height,
                                    0,0,width,height,
                                    (test_clip==0)?NULL:&cliprects[0],
                                    (test_clip==0)?0:2,
                                    display_field);
            CHECK_VASTATUS(vaStatus,"vaPutSurface");
        }
    
        putsurface_time += (get_tick_count() - start_time);
        
        if (check_event)
            pthread_mutex_unlock(&gmutex);
        
        pthread_mutex_unlock(&surface_mutex[index]); /* locked in get_next_free_surface */
        
        if ((frame_num % 0xff) == 0) {
            fprintf(stderr, "%.2f FPS             \r", 256000.0 / (float)putsurface_time);
            putsurface_time = 0;
            update_clipbox(cliprects, width, height);
        }
        
        if (check_event)
            check_window_event(win_display, drawable, &width, &height, &quit);

        if (multi_thread) { /* reload surface content */
            row_shift++;
            if (row_shift==(2*box_width)) row_shift= 0;
        }
        
        if (frame_rate != 0) /* rough framerate control */
            usleep(1000/frame_rate*1000);

        frame_num++;
        if (frame_num >= frame_num_total)
            quit = 1;
    }
    
    if (drawable == drawable_thread1)    
        pthread_exit(NULL);
    
    return 0;
}