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