st/vdpau: Various whitespace cleanups found while reading some code
[mesa.git] / src / gallium / state_trackers / vdpau / decode.c
1 /**************************************************************************
2 *
3 * Copyright 2010 Thomas Balling Sørensen.
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
16 * of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 *
26 **************************************************************************/
27
28 #include "util/u_memory.h"
29 #include "util/u_math.h"
30 #include "util/u_debug.h"
31
32 #include "vdpau_private.h"
33
34 VdpStatus
35 vlVdpDecoderCreate(VdpDevice device,
36 VdpDecoderProfile profile,
37 uint32_t width, uint32_t height,
38 uint32_t max_references,
39 VdpDecoder *decoder)
40 {
41 enum pipe_video_profile p_profile;
42 struct pipe_context *pipe;
43 vlVdpDevice *dev;
44 vlVdpDecoder *vldecoder;
45 VdpStatus ret;
46 unsigned i;
47
48 VDPAU_MSG(VDPAU_TRACE, "[VDPAU] Creating decoder\n");
49
50 if (!decoder)
51 return VDP_STATUS_INVALID_POINTER;
52
53 if (!(width && height))
54 return VDP_STATUS_INVALID_VALUE;
55
56 p_profile = ProfileToPipe(profile);
57 if (p_profile == PIPE_VIDEO_PROFILE_UNKNOWN)
58 return VDP_STATUS_INVALID_DECODER_PROFILE;
59
60 dev = vlGetDataHTAB(device);
61 if (!dev)
62 return VDP_STATUS_INVALID_HANDLE;
63
64 pipe = dev->context->pipe;
65
66 vldecoder = CALLOC(1,sizeof(vlVdpDecoder));
67 if (!vldecoder)
68 return VDP_STATUS_RESOURCES;
69
70 vldecoder->device = dev;
71
72 vldecoder->decoder = pipe->create_video_decoder
73 (
74 pipe, p_profile,
75 PIPE_VIDEO_ENTRYPOINT_BITSTREAM,
76 PIPE_VIDEO_CHROMA_FORMAT_420,
77 width, height, max_references
78 );
79
80 if (!vldecoder->decoder) {
81 ret = VDP_STATUS_ERROR;
82 goto error_decoder;
83 }
84
85 vldecoder->num_buffers = pipe->screen->get_video_param
86 (
87 pipe->screen, p_profile,
88 PIPE_VIDEO_CAP_NUM_BUFFERS_DESIRED
89 );
90 vldecoder->cur_buffer = 0;
91
92 vldecoder->buffers = CALLOC(vldecoder->num_buffers, sizeof(void*));
93 if (!vldecoder->buffers)
94 goto error_alloc_buffers;
95
96 for (i = 0; i < vldecoder->num_buffers; ++i) {
97 vldecoder->buffers[i] = vldecoder->decoder->create_buffer(vldecoder->decoder);
98 if (!vldecoder->buffers[i]) {
99 ret = VDP_STATUS_ERROR;
100 goto error_create_buffers;
101 }
102 }
103
104 *decoder = vlAddDataHTAB(vldecoder);
105 if (*decoder == 0) {
106 ret = VDP_STATUS_ERROR;
107 goto error_handle;
108 }
109
110 VDPAU_MSG(VDPAU_TRACE, "[VDPAU] Decoder created succesfully\n");
111
112 return VDP_STATUS_OK;
113
114 error_handle:
115 error_create_buffers:
116
117 for (i = 0; i < vldecoder->num_buffers; ++i)
118 if (vldecoder->buffers[i])
119 vldecoder->decoder->destroy_buffer(vldecoder->decoder, vldecoder->buffers[i]);
120
121 FREE(vldecoder->buffers);
122
123 error_alloc_buffers:
124
125 vldecoder->decoder->destroy(vldecoder->decoder);
126
127 error_decoder:
128 FREE(vldecoder);
129 return ret;
130 }
131
132 VdpStatus
133 vlVdpDecoderDestroy(VdpDecoder decoder)
134 {
135 vlVdpDecoder *vldecoder;
136 unsigned i;
137
138 VDPAU_MSG(VDPAU_TRACE, "[VDPAU] Destroying decoder\n");
139
140 vldecoder = (vlVdpDecoder *)vlGetDataHTAB(decoder);
141 if (!vldecoder)
142 return VDP_STATUS_INVALID_HANDLE;
143
144 for (i = 0; i < vldecoder->num_buffers; ++i)
145 if (vldecoder->buffers[i])
146 vldecoder->decoder->destroy_buffer(vldecoder->decoder, vldecoder->buffers[i]);
147
148 FREE(vldecoder->buffers);
149
150 vldecoder->decoder->destroy(vldecoder->decoder);
151
152 FREE(vldecoder);
153
154 return VDP_STATUS_OK;
155 }
156
157 VdpStatus
158 vlVdpDecoderGetParameters(VdpDecoder decoder,
159 VdpDecoderProfile *profile,
160 uint32_t *width,
161 uint32_t *height)
162 {
163 vlVdpDecoder *vldecoder;
164
165 VDPAU_MSG(VDPAU_TRACE, "[VDPAU] decoder get parameters called\n");
166
167 vldecoder = (vlVdpDecoder *)vlGetDataHTAB(decoder);
168 if (!vldecoder)
169 return VDP_STATUS_INVALID_HANDLE;
170
171 *profile = PipeToProfile(vldecoder->decoder->profile);
172 *width = vldecoder->decoder->width;
173 *height = vldecoder->decoder->height;
174
175 return VDP_STATUS_OK;
176 }
177
178 static VdpStatus
179 vlVdpDecoderRenderMpeg12(struct pipe_video_decoder *decoder,
180 VdpPictureInfoMPEG1Or2 *picture_info,
181 uint32_t bitstream_buffer_count,
182 VdpBitstreamBuffer const *bitstream_buffers)
183 {
184 struct pipe_mpeg12_picture_desc picture;
185 struct pipe_mpeg12_quant_matrix quant;
186 struct pipe_video_buffer *ref_frames[2];
187 unsigned i;
188
189 VDPAU_MSG(VDPAU_TRACE, "[VDPAU] Decoding MPEG2\n");
190
191 i = 0;
192
193 /* if surfaces equals VDP_STATUS_INVALID_HANDLE, they are not used */
194 if (picture_info->forward_reference != VDP_INVALID_HANDLE) {
195 ref_frames[i] = ((vlVdpSurface *)vlGetDataHTAB(picture_info->forward_reference))->video_buffer;
196 if (!ref_frames[i])
197 return VDP_STATUS_INVALID_HANDLE;
198 ++i;
199 }
200
201 if (picture_info->backward_reference != VDP_INVALID_HANDLE) {
202 ref_frames[i] = ((vlVdpSurface *)vlGetDataHTAB(picture_info->backward_reference))->video_buffer;
203 if (!ref_frames[i])
204 return VDP_STATUS_INVALID_HANDLE;
205 ++i;
206 }
207
208 decoder->set_reference_frames(decoder, ref_frames, i);
209
210 memset(&picture, 0, sizeof(picture));
211 picture.base.profile = decoder->profile;
212 picture.picture_coding_type = picture_info->picture_coding_type;
213 picture.picture_structure = picture_info->picture_structure;
214 picture.frame_pred_frame_dct = picture_info->frame_pred_frame_dct;
215 picture.q_scale_type = picture_info->q_scale_type;
216 picture.alternate_scan = picture_info->alternate_scan;
217 picture.intra_vlc_format = picture_info->intra_vlc_format;
218 picture.concealment_motion_vectors = picture_info->concealment_motion_vectors;
219 picture.intra_dc_precision = picture_info->intra_dc_precision;
220 picture.f_code[0][0] = picture_info->f_code[0][0] - 1;
221 picture.f_code[0][1] = picture_info->f_code[0][1] - 1;
222 picture.f_code[1][0] = picture_info->f_code[1][0] - 1;
223 picture.f_code[1][1] = picture_info->f_code[1][1] - 1;
224
225 decoder->set_picture_parameters(decoder, &picture.base);
226
227 memset(&quant, 0, sizeof(quant));
228 quant.base.codec = PIPE_VIDEO_CODEC_MPEG12;
229 quant.intra_matrix = picture_info->intra_quantizer_matrix;
230 quant.non_intra_matrix = picture_info->non_intra_quantizer_matrix;
231
232 decoder->set_quant_matrix(decoder, &quant.base);
233
234 decoder->begin_frame(decoder);
235
236 for (i = 0; i < bitstream_buffer_count; ++i)
237 decoder->decode_bitstream(decoder, bitstream_buffers[i].bitstream_bytes,
238 bitstream_buffers[i].bitstream);
239
240 decoder->end_frame(decoder);
241
242 return VDP_STATUS_OK;
243 }
244
245 VdpStatus
246 vlVdpDecoderRender(VdpDecoder decoder,
247 VdpVideoSurface target,
248 VdpPictureInfo const *picture_info,
249 uint32_t bitstream_buffer_count,
250 VdpBitstreamBuffer const *bitstream_buffers)
251 {
252 vlVdpDecoder *vldecoder;
253 vlVdpSurface *vlsurf;
254
255 VDPAU_MSG(VDPAU_TRACE, "[VDPAU] Decoding\n");
256
257 if (!(picture_info && bitstream_buffers))
258 return VDP_STATUS_INVALID_POINTER;
259
260 vldecoder = (vlVdpDecoder *)vlGetDataHTAB(decoder);
261 if (!vldecoder)
262 return VDP_STATUS_INVALID_HANDLE;
263
264 vlsurf = (vlVdpSurface *)vlGetDataHTAB(target);
265 if (!vlsurf)
266 return VDP_STATUS_INVALID_HANDLE;
267
268 if (vlsurf->device != vldecoder->device)
269 return VDP_STATUS_HANDLE_DEVICE_MISMATCH;
270
271 if (vlsurf->video_buffer->chroma_format != vldecoder->decoder->chroma_format)
272 // TODO: Recreate decoder with correct chroma
273 return VDP_STATUS_INVALID_CHROMA_TYPE;
274
275 // TODO: Right now only mpeg 1 & 2 is supported.
276 switch (vldecoder->decoder->profile) {
277 case PIPE_VIDEO_PROFILE_MPEG1:
278 case PIPE_VIDEO_PROFILE_MPEG2_SIMPLE:
279 case PIPE_VIDEO_PROFILE_MPEG2_MAIN:
280 ++vldecoder->cur_buffer;
281 vldecoder->cur_buffer %= vldecoder->num_buffers;
282
283 vldecoder->decoder->set_decode_buffer(vldecoder->decoder, vldecoder->buffers[vldecoder->cur_buffer]);
284 vldecoder->decoder->set_decode_target(vldecoder->decoder, vlsurf->video_buffer);
285
286 return vlVdpDecoderRenderMpeg12(vldecoder->decoder, (VdpPictureInfoMPEG1Or2 *)picture_info,
287 bitstream_buffer_count, bitstream_buffers);
288 break;
289
290 default:
291 return VDP_STATUS_INVALID_DECODER_PROFILE;
292 }
293 }