surface.c revision 4f3fb1586aebfe248321e935651b5af92b5a8261
1/**************************************************************************
2 *
3 * Copyright 2010 Thomas Balling Sørensen.
4 * Copyright 2011 Christian König.
5 * All Rights Reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the
9 * "Software"), to deal in the Software without restriction, including
10 * without limitation the rights to use, copy, modify, merge, publish,
11 * distribute, sub license, and/or sell copies of the Software, and to
12 * permit persons to whom the Software is furnished to do so, subject to
13 * the following conditions:
14 *
15 * The above copyright notice and this permission notice (including the
16 * next paragraph) shall be included in all copies or substantial portions
17 * of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
22 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
23 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 *
27 **************************************************************************/
28
29#include <assert.h>
30
31#include <pipe/p_video_context.h>
32#include <pipe/p_state.h>
33
34#include <util/u_memory.h>
35#include <util/u_debug.h>
36
37#include "vdpau_private.h"
38
39VdpStatus
40vlVdpVideoSurfaceCreate(VdpDevice device, VdpChromaType chroma_type,
41                        uint32_t width, uint32_t height,
42                        VdpVideoSurface *surface)
43{
44   const enum pipe_format resource_formats[3] = {
45      PIPE_FORMAT_R8_UNORM,
46      PIPE_FORMAT_R8_UNORM,
47      PIPE_FORMAT_R8_UNORM
48   };
49
50   vlVdpSurface *p_surf;
51   VdpStatus ret;
52
53   _debug_printf("[VDPAU] Creating a surface\n");
54
55   if (!(width && height)) {
56      ret = VDP_STATUS_INVALID_SIZE;
57      goto inv_size;
58   }
59
60   if (!vlCreateHTAB()) {
61      ret = VDP_STATUS_RESOURCES;
62      goto no_htab;
63   }
64
65   p_surf = CALLOC(1, sizeof(p_surf));
66   if (!p_surf) {
67      ret = VDP_STATUS_RESOURCES;
68      goto no_res;
69   }
70
71   vlVdpDevice *dev = vlGetDataHTAB(device);
72   if (!dev) {
73      ret = VDP_STATUS_INVALID_HANDLE;
74      goto inv_device;
75   }
76
77   p_surf->device = dev;
78   p_surf->video_buffer = dev->context->vpipe->create_buffer(dev->context->vpipe,
79                                                             PIPE_FORMAT_YV12, // most common used
80                                                             resource_formats,
81                                                             ChromaToPipe(chroma_type),
82                                                             width, height);
83
84   *surface = vlAddDataHTAB(p_surf);
85   if (*surface == 0) {
86      ret = VDP_STATUS_ERROR;
87      goto no_handle;
88   }
89
90   return VDP_STATUS_OK;
91
92no_handle:
93   p_surf->video_buffer->destroy(p_surf->video_buffer);
94
95inv_device:
96   FREE(p_surf);
97
98no_res:
99no_htab:
100inv_size:
101   return ret;
102}
103
104VdpStatus
105vlVdpVideoSurfaceDestroy(VdpVideoSurface surface)
106{
107   vlVdpSurface *p_surf;
108
109   p_surf = (vlVdpSurface *)vlGetDataHTAB((vlHandle)surface);
110   if (!p_surf)
111      return VDP_STATUS_INVALID_HANDLE;
112
113   if (p_surf->video_buffer)
114      p_surf->video_buffer->destroy(p_surf->video_buffer);
115
116   FREE(p_surf);
117   return VDP_STATUS_OK;
118}
119
120VdpStatus
121vlVdpVideoSurfaceGetParameters(VdpVideoSurface surface,
122                               VdpChromaType *chroma_type,
123                               uint32_t *width, uint32_t *height)
124{
125   if (!(width && height && chroma_type))
126      return VDP_STATUS_INVALID_POINTER;
127
128   vlVdpSurface *p_surf = vlGetDataHTAB(surface);
129   if (!p_surf)
130      return VDP_STATUS_INVALID_HANDLE;
131
132   *width = p_surf->video_buffer->width;
133   *height = p_surf->video_buffer->height;
134   *chroma_type = PipeToChroma(p_surf->video_buffer->chroma_format);
135
136   return VDP_STATUS_OK;
137}
138
139VdpStatus
140vlVdpVideoSurfaceGetBitsYCbCr(VdpVideoSurface surface,
141                              VdpYCbCrFormat destination_ycbcr_format,
142                              void *const *destination_data,
143                              uint32_t const *destination_pitches)
144{
145   if (!vlCreateHTAB())
146      return VDP_STATUS_RESOURCES;
147
148   vlVdpSurface *p_surf = vlGetDataHTAB(surface);
149   if (!p_surf)
150      return VDP_STATUS_INVALID_HANDLE;
151
152   //if (!p_surf->psurface)
153   //   return VDP_STATUS_RESOURCES;
154
155   //return VDP_STATUS_OK;
156   return VDP_STATUS_NO_IMPLEMENTATION;
157}
158
159VdpStatus
160vlVdpVideoSurfacePutBitsYCbCr(VdpVideoSurface surface,
161                              VdpYCbCrFormat source_ycbcr_format,
162                              void const *const *source_data,
163                              uint32_t const *source_pitches)
164{
165   enum pipe_format pformat = FormatToPipe(source_ycbcr_format);
166   struct pipe_video_context *context;
167   struct pipe_sampler_view **sampler_views;
168   unsigned i;
169
170   if (!vlCreateHTAB())
171      return VDP_STATUS_RESOURCES;
172
173   vlVdpSurface *p_surf = vlGetDataHTAB(surface);
174   if (!p_surf)
175      return VDP_STATUS_INVALID_HANDLE;
176
177   context = p_surf->device->context->vpipe;
178   if (!context)
179      return VDP_STATUS_INVALID_HANDLE;
180
181   if (p_surf->video_buffer == NULL || pformat != p_surf->video_buffer->buffer_format) {
182      assert(0); // TODO Recreate resource
183      return VDP_STATUS_NO_IMPLEMENTATION;
184   }
185
186   sampler_views = p_surf->video_buffer->get_sampler_views(p_surf->video_buffer);
187   if (!sampler_views)
188      return VDP_STATUS_RESOURCES;
189
190   for (i = 0; i < 3; ++i) { //TODO put nr of planes into util format
191      struct pipe_sampler_view *sv = sampler_views[i];
192      struct pipe_box dst_box = { 0, 0, 0, sv->texture->width0, sv->texture->height0, 1 };
193      context->upload_sampler(context, sv, &dst_box, source_data[i], source_pitches[i], 0, 0);
194   }
195
196   return VDP_STATUS_OK;
197}
198