1 /*****************************************************************************
2 * picture.c: VDPAU instance management for VLC
3 *****************************************************************************
4 * Copyright (C) 2013 RĂ©mi Denis-Courmont
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU Lesser General Public License as published by
8 * the Free Software Foundation; either version 2.1 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with this program; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
19 *****************************************************************************/
29 #include <vlc_common.h>
30 #include <vlc_picture.h>
31 #include "vlc_vdpau.h"
33 #pragma GCC visibility push(default)
35 static void SurfaceDestroy(void *opaque)
37 vlc_vdp_video_field_t *field = opaque;
38 vlc_vdp_video_frame_t *frame = field->frame;
41 /* Destroy field-specific infos */
44 if (atomic_fetch_sub(&frame->refs, 1) != 1)
47 /* Destroy frame (video surface) */
48 err = vdp_video_surface_destroy(frame->vdp, frame->surface);
49 if (err != VDP_STATUS_OK)
50 fprintf(stderr, "video surface destruction failure: %s\n",
51 vdp_get_error_string(frame->vdp, err));
52 vdp_release_x11(frame->vdp);
56 static const VdpProcamp procamp_default =
58 .struct_version = VDP_PROCAMP_VERSION,
65 vlc_vdp_video_field_t *vlc_vdp_video_create(vdp_t *vdp,
66 VdpVideoSurface surface)
68 vlc_vdp_video_field_t *field = malloc(sizeof (*field));
69 vlc_vdp_video_frame_t *frame = malloc(sizeof (*frame));
71 if (unlikely(field == NULL || frame == NULL))
75 vdp_video_surface_destroy(vdp, surface);
79 field->destroy = SurfaceDestroy;
81 field->structure = VDP_VIDEO_MIXER_PICTURE_STRUCTURE_FRAME;
82 field->procamp = procamp_default;
85 atomic_init(&frame->refs, 1);
86 frame->surface = surface;
87 frame->vdp = vdp_hold_x11(vdp, &frame->device);
91 VdpStatus vlc_vdp_video_attach(vdp_t *vdp, VdpVideoSurface surface,
94 vlc_vdp_video_field_t *field = vlc_vdp_video_create(vdp, surface);
95 if (unlikely(field == NULL))
96 return VDP_STATUS_RESOURCES;
98 assert(pic->format.i_chroma == VLC_CODEC_VDPAU_VIDEO_420
99 || pic->format.i_chroma == VLC_CODEC_VDPAU_VIDEO_422
100 || pic->format.i_chroma == VLC_CODEC_VDPAU_VIDEO_444);
101 assert(!picture_IsReferenced(pic));
102 assert(pic->context == NULL);
103 pic->context = field;
104 return VDP_STATUS_OK;
107 vlc_vdp_video_field_t *vlc_vdp_video_copy(vlc_vdp_video_field_t *fold)
109 vlc_vdp_video_frame_t *frame = fold->frame;
110 vlc_vdp_video_field_t *fnew = malloc(sizeof (*fnew));
111 if (unlikely(fnew == NULL))
114 fnew->destroy = SurfaceDestroy;
116 fnew->structure = fold->structure;
117 fnew->procamp = fold->procamp;
118 fnew->sharpen = fold->sharpen;
120 atomic_fetch_add(&frame->refs, 1);