~ubuntu-branches/ubuntu/precise/mesa-lts-quantal/precise-updates

« back to all changes in this revision

Viewing changes to src/gallium/state_trackers/vdpau/decode.c

  • Committer: Package Import Robot
  • Author(s): Maarten Lankhorst
  • Date: 2012-11-30 20:58:34 UTC
  • Revision ID: package-import@ubuntu.com-20121130205834-gazuvne3fpwlf012
Tags: upstream-9.0
ImportĀ upstreamĀ versionĀ 9.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
#include "util/u_video.h"
 
32
 
 
33
#include "vl/vl_vlc.h"
 
34
 
 
35
#include "vdpau_private.h"
 
36
 
 
37
/**
 
38
 * Create a VdpDecoder.
 
39
 */
 
40
VdpStatus
 
41
vlVdpDecoderCreate(VdpDevice device,
 
42
                   VdpDecoderProfile profile,
 
43
                   uint32_t width, uint32_t height,
 
44
                   uint32_t max_references,
 
45
                   VdpDecoder *decoder)
 
46
{
 
47
   enum pipe_video_profile p_profile;
 
48
   struct pipe_context *pipe;
 
49
   struct pipe_screen *screen;
 
50
   vlVdpDevice *dev;
 
51
   vlVdpDecoder *vldecoder;
 
52
   VdpStatus ret;
 
53
   bool supported;
 
54
 
 
55
   if (!decoder)
 
56
      return VDP_STATUS_INVALID_POINTER;
 
57
   *decoder = 0;
 
58
 
 
59
   if (!(width && height))
 
60
      return VDP_STATUS_INVALID_VALUE;
 
61
 
 
62
   p_profile = ProfileToPipe(profile);
 
63
   if (p_profile == PIPE_VIDEO_PROFILE_UNKNOWN)
 
64
      return VDP_STATUS_INVALID_DECODER_PROFILE;
 
65
 
 
66
   dev = vlGetDataHTAB(device);
 
67
   if (!dev)
 
68
      return VDP_STATUS_INVALID_HANDLE;
 
69
 
 
70
   pipe = dev->context;
 
71
   screen = dev->vscreen->pscreen;
 
72
 
 
73
   pipe_mutex_lock(dev->mutex);
 
74
 
 
75
   supported = screen->get_video_param
 
76
   (
 
77
      screen,
 
78
      p_profile,
 
79
      PIPE_VIDEO_CAP_SUPPORTED
 
80
   );
 
81
   if (!supported) {
 
82
      pipe_mutex_unlock(dev->mutex);
 
83
      return VDP_STATUS_INVALID_DECODER_PROFILE;
 
84
   }
 
85
 
 
86
   vldecoder = CALLOC(1,sizeof(vlVdpDecoder));
 
87
   if (!vldecoder) {
 
88
      pipe_mutex_unlock(dev->mutex);
 
89
      return VDP_STATUS_RESOURCES;
 
90
   }
 
91
 
 
92
   vldecoder->device = dev;
 
93
 
 
94
   vldecoder->decoder = pipe->create_video_decoder
 
95
   (
 
96
      pipe, p_profile,
 
97
      PIPE_VIDEO_ENTRYPOINT_BITSTREAM,
 
98
      PIPE_VIDEO_CHROMA_FORMAT_420,
 
99
      width, height, max_references,
 
100
      false
 
101
   );
 
102
 
 
103
   if (!vldecoder->decoder) {
 
104
      ret = VDP_STATUS_ERROR;
 
105
      goto error_decoder;
 
106
   }
 
107
 
 
108
   *decoder = vlAddDataHTAB(vldecoder);
 
109
   if (*decoder == 0) {
 
110
      ret = VDP_STATUS_ERROR;
 
111
      goto error_handle;
 
112
   }
 
113
   pipe_mutex_unlock(dev->mutex);
 
114
 
 
115
   return VDP_STATUS_OK;
 
116
 
 
117
error_handle:
 
118
   vldecoder->decoder->destroy(vldecoder->decoder);
 
119
 
 
120
error_decoder:
 
121
   pipe_mutex_unlock(dev->mutex);
 
122
   FREE(vldecoder);
 
123
   return ret;
 
124
}
 
125
 
 
126
/**
 
127
 * Destroy a VdpDecoder.
 
128
 */
 
129
VdpStatus
 
130
vlVdpDecoderDestroy(VdpDecoder decoder)
 
131
{
 
132
   vlVdpDecoder *vldecoder;
 
133
 
 
134
   vldecoder = (vlVdpDecoder *)vlGetDataHTAB(decoder);
 
135
   if (!vldecoder)
 
136
      return VDP_STATUS_INVALID_HANDLE;
 
137
 
 
138
   pipe_mutex_lock(vldecoder->device->mutex);
 
139
   vldecoder->decoder->destroy(vldecoder->decoder);
 
140
   pipe_mutex_unlock(vldecoder->device->mutex);
 
141
 
 
142
   FREE(vldecoder);
 
143
 
 
144
   return VDP_STATUS_OK;
 
145
}
 
146
 
 
147
/**
 
148
 * Retrieve the parameters used to create a VdpBitmapSurface.
 
149
 */
 
150
VdpStatus
 
151
vlVdpDecoderGetParameters(VdpDecoder decoder,
 
152
                          VdpDecoderProfile *profile,
 
153
                          uint32_t *width,
 
154
                          uint32_t *height)
 
155
{
 
156
   vlVdpDecoder *vldecoder;
 
157
 
 
158
   vldecoder = (vlVdpDecoder *)vlGetDataHTAB(decoder);
 
159
   if (!vldecoder)
 
160
      return VDP_STATUS_INVALID_HANDLE;
 
161
 
 
162
   *profile = PipeToProfile(vldecoder->decoder->profile);
 
163
   *width = vldecoder->decoder->width;
 
164
   *height = vldecoder->decoder->height;
 
165
 
 
166
   return VDP_STATUS_OK;
 
167
}
 
168
 
 
169
static VdpStatus
 
170
vlVdpGetReferenceFrame(VdpVideoSurface handle, struct pipe_video_buffer **ref_frame)
 
171
{
 
172
   vlVdpSurface *surface;
 
173
 
 
174
   /* if surfaces equals VDP_STATUS_INVALID_HANDLE, they are not used */
 
175
   if (handle ==  VDP_INVALID_HANDLE) {
 
176
      *ref_frame = NULL;
 
177
      return VDP_STATUS_OK;
 
178
   }
 
179
 
 
180
   surface = vlGetDataHTAB(handle);
 
181
   if (!surface)
 
182
      return VDP_STATUS_INVALID_HANDLE;
 
183
 
 
184
   *ref_frame = surface->video_buffer;
 
185
   if (!*ref_frame)
 
186
         return VDP_STATUS_INVALID_HANDLE;
 
187
 
 
188
   return VDP_STATUS_OK;
 
189
}
 
190
 
 
191
/**
 
192
 * Decode a mpeg 1/2 video.
 
193
 */
 
194
static VdpStatus
 
195
vlVdpDecoderRenderMpeg12(struct pipe_mpeg12_picture_desc *picture,
 
196
                         VdpPictureInfoMPEG1Or2 *picture_info)
 
197
{
 
198
   VdpStatus r;
 
199
 
 
200
   VDPAU_MSG(VDPAU_TRACE, "[VDPAU] Decoding MPEG12\n");
 
201
 
 
202
   r = vlVdpGetReferenceFrame(picture_info->forward_reference, &picture->ref[0]);
 
203
   if (r != VDP_STATUS_OK)
 
204
      return r;
 
205
 
 
206
   r = vlVdpGetReferenceFrame(picture_info->backward_reference, &picture->ref[1]);
 
207
   if (r != VDP_STATUS_OK)
 
208
      return r;
 
209
 
 
210
   picture->picture_coding_type = picture_info->picture_coding_type;
 
211
   picture->picture_structure = picture_info->picture_structure;
 
212
   picture->frame_pred_frame_dct = picture_info->frame_pred_frame_dct;
 
213
   picture->q_scale_type = picture_info->q_scale_type;
 
214
   picture->alternate_scan = picture_info->alternate_scan;
 
215
   picture->intra_vlc_format = picture_info->intra_vlc_format;
 
216
   picture->concealment_motion_vectors = picture_info->concealment_motion_vectors;
 
217
   picture->intra_dc_precision = picture_info->intra_dc_precision;
 
218
   picture->f_code[0][0] = picture_info->f_code[0][0] - 1;
 
219
   picture->f_code[0][1] = picture_info->f_code[0][1] - 1;
 
220
   picture->f_code[1][0] = picture_info->f_code[1][0] - 1;
 
221
   picture->f_code[1][1] = picture_info->f_code[1][1] - 1;
 
222
   picture->num_slices = picture_info->slice_count;
 
223
   picture->top_field_first = picture_info->top_field_first;
 
224
   picture->full_pel_forward_vector = picture_info->full_pel_forward_vector;
 
225
   picture->full_pel_backward_vector = picture_info->full_pel_backward_vector;
 
226
   picture->intra_matrix = picture_info->intra_quantizer_matrix;
 
227
   picture->non_intra_matrix = picture_info->non_intra_quantizer_matrix;
 
228
 
 
229
   return VDP_STATUS_OK;
 
230
}
 
231
 
 
232
/**
 
233
 * Decode a mpeg 4 video.
 
234
 */
 
235
static VdpStatus
 
236
vlVdpDecoderRenderMpeg4(struct pipe_mpeg4_picture_desc *picture,
 
237
                        VdpPictureInfoMPEG4Part2 *picture_info)
 
238
{
 
239
   VdpStatus r;
 
240
   unsigned i;
 
241
 
 
242
   VDPAU_MSG(VDPAU_TRACE, "[VDPAU] Decoding MPEG4\n");
 
243
 
 
244
   r = vlVdpGetReferenceFrame(picture_info->forward_reference, &picture->ref[0]);
 
245
   if (r != VDP_STATUS_OK)
 
246
      return r;
 
247
 
 
248
   r = vlVdpGetReferenceFrame(picture_info->backward_reference, &picture->ref[1]);
 
249
   if (r != VDP_STATUS_OK)
 
250
      return r;
 
251
 
 
252
   for (i = 0; i < 2; ++i) {
 
253
      picture->trd[i] = picture_info->trd[i];
 
254
      picture->trb[i] = picture_info->trb[i];
 
255
   }
 
256
   picture->vop_time_increment_resolution = picture_info->vop_time_increment_resolution;
 
257
   picture->vop_coding_type = picture_info->vop_coding_type;
 
258
   picture->vop_fcode_forward = picture_info->vop_fcode_forward;
 
259
   picture->vop_fcode_backward = picture_info->vop_fcode_backward;
 
260
   picture->resync_marker_disable = picture_info->resync_marker_disable;
 
261
   picture->interlaced = picture_info->interlaced;
 
262
   picture->quant_type = picture_info->quant_type;
 
263
   picture->quarter_sample = picture_info->quarter_sample;
 
264
   picture->short_video_header = picture_info->short_video_header;
 
265
   picture->rounding_control = picture_info->rounding_control;
 
266
   picture->alternate_vertical_scan_flag = picture_info->alternate_vertical_scan_flag;
 
267
   picture->top_field_first = picture_info->top_field_first;
 
268
   picture->intra_matrix = picture_info->intra_quantizer_matrix;
 
269
   picture->non_intra_matrix = picture_info->non_intra_quantizer_matrix;
 
270
 
 
271
   return VDP_STATUS_OK;
 
272
}
 
273
 
 
274
static VdpStatus
 
275
vlVdpDecoderRenderVC1(struct pipe_vc1_picture_desc *picture,
 
276
                      VdpPictureInfoVC1 *picture_info)
 
277
{
 
278
   VdpStatus r;
 
279
 
 
280
   VDPAU_MSG(VDPAU_TRACE, "[VDPAU] Decoding VC-1\n");
 
281
 
 
282
   r = vlVdpGetReferenceFrame(picture_info->forward_reference, &picture->ref[0]);
 
283
   if (r != VDP_STATUS_OK)
 
284
      return r;
 
285
 
 
286
   r = vlVdpGetReferenceFrame(picture_info->backward_reference, &picture->ref[1]);
 
287
   if (r != VDP_STATUS_OK)
 
288
      return r;
 
289
 
 
290
   picture->slice_count = picture_info->slice_count;
 
291
   picture->picture_type = picture_info->picture_type;
 
292
   picture->frame_coding_mode = picture_info->frame_coding_mode;
 
293
   picture->postprocflag = picture_info->postprocflag;
 
294
   picture->pulldown = picture_info->pulldown;
 
295
   picture->interlace = picture_info->interlace;
 
296
   picture->tfcntrflag = picture_info->tfcntrflag;
 
297
   picture->finterpflag = picture_info->finterpflag;
 
298
   picture->psf = picture_info->psf;
 
299
   picture->dquant = picture_info->dquant;
 
300
   picture->panscan_flag = picture_info->panscan_flag;
 
301
   picture->refdist_flag = picture_info->refdist_flag;
 
302
   picture->quantizer = picture_info->quantizer;
 
303
   picture->extended_mv = picture_info->extended_mv;
 
304
   picture->extended_dmv = picture_info->extended_dmv;
 
305
   picture->overlap = picture_info->overlap;
 
306
   picture->vstransform = picture_info->vstransform;
 
307
   picture->loopfilter = picture_info->loopfilter;
 
308
   picture->fastuvmc = picture_info->fastuvmc;
 
309
   picture->range_mapy_flag = picture_info->range_mapy_flag;
 
310
   picture->range_mapy = picture_info->range_mapy;
 
311
   picture->range_mapuv_flag = picture_info->range_mapuv_flag;
 
312
   picture->range_mapuv = picture_info->range_mapuv;
 
313
   picture->multires = picture_info->multires;
 
314
   picture->syncmarker = picture_info->syncmarker;
 
315
   picture->rangered = picture_info->rangered;
 
316
   picture->maxbframes = picture_info->maxbframes;
 
317
   picture->deblockEnable = picture_info->deblockEnable;
 
318
   picture->pquant = picture_info->pquant;
 
319
 
 
320
   return VDP_STATUS_OK;
 
321
}
 
322
 
 
323
static VdpStatus
 
324
vlVdpDecoderRenderH264(struct pipe_h264_picture_desc *picture,
 
325
                       VdpPictureInfoH264 *picture_info)
 
326
{
 
327
   unsigned i;
 
328
 
 
329
   VDPAU_MSG(VDPAU_TRACE, "[VDPAU] Decoding H264\n");
 
330
 
 
331
   picture->slice_count = picture_info->slice_count;
 
332
   picture->field_order_cnt[0] = picture_info->field_order_cnt[0];
 
333
   picture->field_order_cnt[1] = picture_info->field_order_cnt[1];
 
334
   picture->is_reference = picture_info->is_reference;
 
335
   picture->frame_num = picture_info->frame_num;
 
336
   picture->field_pic_flag = picture_info->field_pic_flag;
 
337
   picture->bottom_field_flag = picture_info->bottom_field_flag;
 
338
   picture->num_ref_frames = picture_info->num_ref_frames;
 
339
   picture->mb_adaptive_frame_field_flag = picture_info->mb_adaptive_frame_field_flag;
 
340
   picture->constrained_intra_pred_flag = picture_info->constrained_intra_pred_flag;
 
341
   picture->weighted_pred_flag = picture_info->weighted_pred_flag;
 
342
   picture->weighted_bipred_idc = picture_info->weighted_bipred_idc;
 
343
   picture->frame_mbs_only_flag = picture_info->frame_mbs_only_flag;
 
344
   picture->transform_8x8_mode_flag = picture_info->transform_8x8_mode_flag;
 
345
   picture->chroma_qp_index_offset = picture_info->chroma_qp_index_offset;
 
346
   picture->second_chroma_qp_index_offset = picture_info->second_chroma_qp_index_offset;
 
347
   picture->pic_init_qp_minus26 = picture_info->pic_init_qp_minus26;
 
348
   picture->num_ref_idx_l0_active_minus1 = picture_info->num_ref_idx_l0_active_minus1;
 
349
   picture->num_ref_idx_l1_active_minus1 = picture_info->num_ref_idx_l1_active_minus1;
 
350
   picture->log2_max_frame_num_minus4 = picture_info->log2_max_frame_num_minus4;
 
351
   picture->pic_order_cnt_type = picture_info->pic_order_cnt_type;
 
352
   picture->log2_max_pic_order_cnt_lsb_minus4 = picture_info->log2_max_pic_order_cnt_lsb_minus4;
 
353
   picture->delta_pic_order_always_zero_flag = picture_info->delta_pic_order_always_zero_flag;
 
354
   picture->direct_8x8_inference_flag = picture_info->direct_8x8_inference_flag;
 
355
   picture->entropy_coding_mode_flag = picture_info->entropy_coding_mode_flag;
 
356
   picture->pic_order_present_flag = picture_info->pic_order_present_flag;
 
357
   picture->deblocking_filter_control_present_flag = picture_info->deblocking_filter_control_present_flag;
 
358
   picture->redundant_pic_cnt_present_flag = picture_info->redundant_pic_cnt_present_flag;
 
359
 
 
360
   memcpy(picture->scaling_lists_4x4, picture_info->scaling_lists_4x4, 6*16);
 
361
   memcpy(picture->scaling_lists_8x8, picture_info->scaling_lists_8x8, 2*64);
 
362
 
 
363
   for (i = 0; i < 16; ++i) {
 
364
      VdpStatus ret = vlVdpGetReferenceFrame
 
365
      (
 
366
         picture_info->referenceFrames[i].surface,
 
367
         &picture->ref[i]
 
368
      );
 
369
      if (ret != VDP_STATUS_OK)
 
370
         return ret;
 
371
 
 
372
      picture->is_long_term[i] = picture_info->referenceFrames[i].is_long_term;
 
373
      picture->top_is_reference[i] = picture_info->referenceFrames[i].top_is_reference;
 
374
      picture->bottom_is_reference[i] = picture_info->referenceFrames[i].bottom_is_reference;
 
375
      picture->field_order_cnt_list[i][0] = picture_info->referenceFrames[i].field_order_cnt[0];
 
376
      picture->field_order_cnt_list[i][1] = picture_info->referenceFrames[i].field_order_cnt[1];
 
377
      picture->frame_num_list[i] = picture_info->referenceFrames[i].frame_idx;
 
378
   }
 
379
 
 
380
   return VDP_STATUS_OK;
 
381
}
 
382
 
 
383
static void
 
384
vlVdpDecoderFixVC1Startcode(uint32_t *num_buffers, const void *buffers[], unsigned sizes[])
 
385
{
 
386
   static const uint8_t vc1_startcode[] = { 0x00, 0x00, 0x01, 0x0D };
 
387
   struct vl_vlc vlc;
 
388
   unsigned i;
 
389
 
 
390
   /* search the first 64 bytes for a startcode */
 
391
   vl_vlc_init(&vlc, *num_buffers, buffers, sizes);
 
392
   for (i = 0; i < 64 && vl_vlc_bits_left(&vlc) >= 32; ++i) {
 
393
      uint32_t value = vl_vlc_peekbits(&vlc, 32);
 
394
      if (value == 0x0000010D ||
 
395
          value == 0x0000010C ||
 
396
          value == 0x0000010B)
 
397
         return;
 
398
      vl_vlc_eatbits(&vlc, 8);
 
399
      vl_vlc_fillbits(&vlc);
 
400
   }
 
401
 
 
402
   /* none found, ok add one manually */
 
403
   VDPAU_MSG(VDPAU_TRACE, "[VDPAU] Manually adding VC-1 startcode\n");
 
404
   for (i = *num_buffers; i > 0; --i) {
 
405
      buffers[i] = buffers[i - 1];
 
406
      sizes[i] = sizes[i - 1];
 
407
   }
 
408
   ++(*num_buffers);
 
409
   buffers[0] = vc1_startcode;
 
410
   sizes[0] = 4;
 
411
}
 
412
 
 
413
/**
 
414
 * Decode a compressed field/frame and render the result into a VdpVideoSurface.
 
415
 */
 
416
VdpStatus
 
417
vlVdpDecoderRender(VdpDecoder decoder,
 
418
                   VdpVideoSurface target,
 
419
                   VdpPictureInfo const *picture_info,
 
420
                   uint32_t bitstream_buffer_count,
 
421
                   VdpBitstreamBuffer const *bitstream_buffers)
 
422
{
 
423
   const void * buffers[bitstream_buffer_count + 1];
 
424
   unsigned sizes[bitstream_buffer_count + 1];
 
425
   vlVdpDecoder *vldecoder;
 
426
   vlVdpSurface *vlsurf;
 
427
   VdpStatus ret;
 
428
   struct pipe_screen *screen;
 
429
   struct pipe_video_decoder *dec;
 
430
   bool buffer_support[2];
 
431
   unsigned i;
 
432
   union {
 
433
      struct pipe_picture_desc base;
 
434
      struct pipe_mpeg12_picture_desc mpeg12;
 
435
      struct pipe_mpeg4_picture_desc mpeg4;
 
436
      struct pipe_vc1_picture_desc vc1;
 
437
      struct pipe_h264_picture_desc h264;
 
438
   } desc;
 
439
 
 
440
   if (!(picture_info && bitstream_buffers))
 
441
      return VDP_STATUS_INVALID_POINTER;
 
442
 
 
443
   vldecoder = (vlVdpDecoder *)vlGetDataHTAB(decoder);
 
444
   if (!vldecoder)
 
445
      return VDP_STATUS_INVALID_HANDLE;
 
446
   dec = vldecoder->decoder;
 
447
   screen = dec->context->screen;
 
448
 
 
449
   vlsurf = (vlVdpSurface *)vlGetDataHTAB(target);
 
450
   if (!vlsurf)
 
451
      return VDP_STATUS_INVALID_HANDLE;
 
452
 
 
453
   if (vlsurf->device != vldecoder->device)
 
454
      return VDP_STATUS_HANDLE_DEVICE_MISMATCH;
 
455
 
 
456
   if (vlsurf->video_buffer != NULL && vlsurf->video_buffer->chroma_format != dec->chroma_format)
 
457
      // TODO: Recreate decoder with correct chroma
 
458
      return VDP_STATUS_INVALID_CHROMA_TYPE;
 
459
 
 
460
   pipe_mutex_lock(vlsurf->device->mutex);
 
461
 
 
462
   buffer_support[0] = screen->get_video_param(screen, dec->profile, PIPE_VIDEO_CAP_SUPPORTS_PROGRESSIVE);
 
463
   buffer_support[1] = screen->get_video_param(screen, dec->profile, PIPE_VIDEO_CAP_SUPPORTS_INTERLACED);
 
464
 
 
465
   if (vlsurf->video_buffer == NULL ||
 
466
       !screen->is_video_format_supported(screen, vlsurf->video_buffer->buffer_format, dec->profile) ||
 
467
       !buffer_support[vlsurf->video_buffer->interlaced]) {
 
468
 
 
469
      /* destroy the old one */
 
470
      if (vlsurf->video_buffer)
 
471
         vlsurf->video_buffer->destroy(vlsurf->video_buffer);
 
472
 
 
473
      /* set the buffer format to the prefered one */
 
474
      vlsurf->templat.buffer_format = screen->get_video_param(screen, dec->profile, PIPE_VIDEO_CAP_PREFERED_FORMAT);
 
475
 
 
476
      /* also set interlacing to decoders preferences */
 
477
      vlsurf->templat.interlaced = screen->get_video_param(screen, dec->profile, PIPE_VIDEO_CAP_PREFERS_INTERLACED);
 
478
 
 
479
      /* and recreate the video buffer */
 
480
      vlsurf->video_buffer = dec->context->create_video_buffer(dec->context, &vlsurf->templat);
 
481
 
 
482
      /* still no luck? get me out of here... */
 
483
      if (!vlsurf->video_buffer) {
 
484
         pipe_mutex_unlock(vlsurf->device->mutex);
 
485
         return VDP_STATUS_NO_IMPLEMENTATION;
 
486
      }
 
487
      vlVdpVideoSurfaceClear(vlsurf);
 
488
   }
 
489
 
 
490
   for (i = 0; i < bitstream_buffer_count; ++i) {
 
491
      buffers[i] = bitstream_buffers[i].bitstream;
 
492
      sizes[i] = bitstream_buffers[i].bitstream_bytes;
 
493
   }
 
494
 
 
495
   memset(&desc, 0, sizeof(desc));
 
496
   desc.base.profile = dec->profile;
 
497
   switch (u_reduce_video_profile(dec->profile)) {
 
498
   case PIPE_VIDEO_CODEC_MPEG12:
 
499
      ret = vlVdpDecoderRenderMpeg12(&desc.mpeg12, (VdpPictureInfoMPEG1Or2 *)picture_info);
 
500
      break;
 
501
   case PIPE_VIDEO_CODEC_MPEG4:
 
502
      ret = vlVdpDecoderRenderMpeg4(&desc.mpeg4, (VdpPictureInfoMPEG4Part2 *)picture_info);
 
503
      break;
 
504
   case PIPE_VIDEO_CODEC_VC1:
 
505
      if (dec->profile == PIPE_VIDEO_PROFILE_VC1_ADVANCED)
 
506
         vlVdpDecoderFixVC1Startcode(&bitstream_buffer_count, buffers, sizes);
 
507
      ret = vlVdpDecoderRenderVC1(&desc.vc1, (VdpPictureInfoVC1 *)picture_info);
 
508
      break;
 
509
   case PIPE_VIDEO_CODEC_MPEG4_AVC:
 
510
      ret = vlVdpDecoderRenderH264(&desc.h264, (VdpPictureInfoH264 *)picture_info);
 
511
      break;
 
512
   default:
 
513
      pipe_mutex_unlock(vlsurf->device->mutex);
 
514
      return VDP_STATUS_INVALID_DECODER_PROFILE;
 
515
   }
 
516
 
 
517
   if (ret != VDP_STATUS_OK) {
 
518
      pipe_mutex_unlock(vlsurf->device->mutex);
 
519
      return ret;
 
520
   }
 
521
 
 
522
   dec->begin_frame(dec, vlsurf->video_buffer, &desc.base);
 
523
   dec->decode_bitstream(dec, vlsurf->video_buffer, &desc.base, bitstream_buffer_count, buffers, sizes);
 
524
   dec->end_frame(dec, vlsurf->video_buffer, &desc.base);
 
525
   pipe_mutex_unlock(vlsurf->device->mutex);
 
526
   return ret;
 
527
}