decode.c revision c4d47f065ae2a015a9d2e9a060d71e04d5935c2b
12c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha/**************************************************************************
22c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha *
32c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha * Copyright 2010 Thomas Balling Sørensen.
42c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha * All Rights Reserved.
52c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha *
62c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha * Permission is hereby granted, free of charge, to any person obtaining a
72c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha * copy of this software and associated documentation files (the
82c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha * "Software"), to deal in the Software without restriction, including
92c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha * without limitation the rights to use, copy, modify, merge, publish,
102c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha * distribute, sub license, and/or sell copies of the Software, and to
112c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha * permit persons to whom the Software is furnished to do so, subject to
122c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha * the following conditions:
132c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha *
142c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha * The above copyright notice and this permission notice (including the
152c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha * next paragraph) shall be included in all copies or substantial portions
162c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha * of the Software.
172c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha *
182c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
192c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
202c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
212c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
222c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
232c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
242c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
252c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha *
262c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha **************************************************************************/
272c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha
282c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha#include "util/u_memory.h"
292c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha#include "util/u_math.h"
302c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha#include "util/u_debug.h"
312c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha
322c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha#include "vdpau_private.h"
332c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha
342c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha/**
352c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha * Create a VdpDecoder.
362c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha */
372c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed BougachaVdpStatus
382c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed BougachavlVdpDecoderCreate(VdpDevice device,
392c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha                   VdpDecoderProfile profile,
402c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha                   uint32_t width, uint32_t height,
412c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha                   uint32_t max_references,
422c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha                   VdpDecoder *decoder)
432c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha{
442c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha   enum pipe_video_profile p_profile;
452c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha   struct pipe_context *pipe;
4636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines   vlVdpDevice *dev;
4736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines   vlVdpDecoder *vldecoder;
4836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines   VdpStatus ret;
4936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines   unsigned i;
5036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
5136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines   VDPAU_MSG(VDPAU_TRACE, "[VDPAU] Creating decoder\n");
5236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
5336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines   if (!decoder)
5436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      return VDP_STATUS_INVALID_POINTER;
5536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
5636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines   if (!(width && height))
572c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha      return VDP_STATUS_INVALID_VALUE;
5836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
592c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha   p_profile = ProfileToPipe(profile);
602c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha   if (p_profile == PIPE_VIDEO_PROFILE_UNKNOWN)
612c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha      return VDP_STATUS_INVALID_DECODER_PROFILE;
622c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha
632c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha   dev = vlGetDataHTAB(device);
642c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha   if (!dev)
652c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha      return VDP_STATUS_INVALID_HANDLE;
662c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha
672c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha   pipe = dev->context->pipe;
682c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha
692c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha   vldecoder = CALLOC(1,sizeof(vlVdpDecoder));
7036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines   if (!vldecoder)
7136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      return VDP_STATUS_RESOURCES;
7236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
732c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha   vldecoder->device = dev;
742c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha
752c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha   vldecoder->decoder = pipe->create_video_decoder
762c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha   (
772c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha      pipe, p_profile,
782c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha      PIPE_VIDEO_ENTRYPOINT_BITSTREAM,
792c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha      PIPE_VIDEO_CHROMA_FORMAT_420,
806f45b1f0d689d2cafd3a64be9b548bb8bb0927b0Kevin Enderby      width, height, max_references
816f45b1f0d689d2cafd3a64be9b548bb8bb0927b0Kevin Enderby   );
822c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha
832c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha   if (!vldecoder->decoder) {
842c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha      ret = VDP_STATUS_ERROR;
852c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha      goto error_decoder;
86dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines   }
872c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha
882c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha   vldecoder->num_buffers = pipe->screen->get_video_param
892c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha   (
902c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha      pipe->screen, p_profile,
912c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha      PIPE_VIDEO_CAP_NUM_BUFFERS_DESIRED
922c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha   );
932c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha   vldecoder->cur_buffer = 0;
942c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha
952c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha   vldecoder->buffers = CALLOC(vldecoder->num_buffers, sizeof(void*));
962c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha   if (!vldecoder->buffers)
97dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines         goto error_alloc_buffers;
982c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha
992c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha   for (i = 0; i < vldecoder->num_buffers; ++i) {
1002c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha      vldecoder->buffers[i] = vldecoder->decoder->create_buffer(vldecoder->decoder);
1012c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha      if (!vldecoder->buffers[i]) {
1022c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha         ret = VDP_STATUS_ERROR;
1032c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha         goto error_create_buffers;
1042c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha      }
1052c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha   }
1062c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha
1072c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha   *decoder = vlAddDataHTAB(vldecoder);
108dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines   if (*decoder == 0) {
1092c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha      ret = VDP_STATUS_ERROR;
1102c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha      goto error_handle;
1112c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha   }
1122c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha
1132c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha   VDPAU_MSG(VDPAU_TRACE, "[VDPAU] Decoder created succesfully\n");
1142c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha
1152c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha   return VDP_STATUS_OK;
1162c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha
1172c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougachaerror_handle:
1182c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougachaerror_create_buffers:
119dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
1202c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha   for (i = 0; i < vldecoder->num_buffers; ++i)
1212c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha      if (vldecoder->buffers[i])
1222c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha         vldecoder->decoder->destroy_buffer(vldecoder->decoder, vldecoder->buffers[i]);
1232c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha
124dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines   FREE(vldecoder->buffers);
1252c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha
1262c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougachaerror_alloc_buffers:
1272c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha
1282c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha   vldecoder->decoder->destroy(vldecoder->decoder);
129dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
1302c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougachaerror_decoder:
1312c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha   FREE(vldecoder);
1322c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha   return ret;
1332c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha}
1342c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha
1352c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha/**
1362c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha * Destroy a VdpDecoder.
1372c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha */
1382c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed BougachaVdpStatus
1392c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed BougachavlVdpDecoderDestroy(VdpDecoder decoder)
1402c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha{
1412c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha   vlVdpDecoder *vldecoder;
1422c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha   unsigned i;
1432c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha
1442c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha   VDPAU_MSG(VDPAU_TRACE, "[VDPAU] Destroying decoder\n");
1452c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha
1462c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha   vldecoder = (vlVdpDecoder *)vlGetDataHTAB(decoder);
1472c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha   if (!vldecoder)
1482c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha      return VDP_STATUS_INVALID_HANDLE;
1492c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha
1502c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha   for (i = 0; i < vldecoder->num_buffers; ++i)
1516f45b1f0d689d2cafd3a64be9b548bb8bb0927b0Kevin Enderby      if (vldecoder->buffers[i])
1526f45b1f0d689d2cafd3a64be9b548bb8bb0927b0Kevin Enderby         vldecoder->decoder->destroy_buffer(vldecoder->decoder, vldecoder->buffers[i]);
1532c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha
1542c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha   FREE(vldecoder->buffers);
1552c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha
1562c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha   vldecoder->decoder->destroy(vldecoder->decoder);
1572c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha
1582c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha   FREE(vldecoder);
1592c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha
1606f45b1f0d689d2cafd3a64be9b548bb8bb0927b0Kevin Enderby   return VDP_STATUS_OK;
1616f45b1f0d689d2cafd3a64be9b548bb8bb0927b0Kevin Enderby}
1626f45b1f0d689d2cafd3a64be9b548bb8bb0927b0Kevin Enderby
16336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/**
16436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines * Retrieve the parameters used to create a VdpBitmapSurface.
16536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines */
16636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen HinesVdpStatus
16736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen HinesvlVdpDecoderGetParameters(VdpDecoder decoder,
1686f45b1f0d689d2cafd3a64be9b548bb8bb0927b0Kevin Enderby                          VdpDecoderProfile *profile,
1696f45b1f0d689d2cafd3a64be9b548bb8bb0927b0Kevin Enderby                          uint32_t *width,
1706f45b1f0d689d2cafd3a64be9b548bb8bb0927b0Kevin Enderby                          uint32_t *height)
1716f45b1f0d689d2cafd3a64be9b548bb8bb0927b0Kevin Enderby{
1726f45b1f0d689d2cafd3a64be9b548bb8bb0927b0Kevin Enderby   vlVdpDecoder *vldecoder;
1736f45b1f0d689d2cafd3a64be9b548bb8bb0927b0Kevin Enderby
1746f45b1f0d689d2cafd3a64be9b548bb8bb0927b0Kevin Enderby   VDPAU_MSG(VDPAU_TRACE, "[VDPAU] Decoder get parameters called\n");
1756f45b1f0d689d2cafd3a64be9b548bb8bb0927b0Kevin Enderby
1766f45b1f0d689d2cafd3a64be9b548bb8bb0927b0Kevin Enderby   vldecoder = (vlVdpDecoder *)vlGetDataHTAB(decoder);
1776f45b1f0d689d2cafd3a64be9b548bb8bb0927b0Kevin Enderby   if (!vldecoder)
1786f45b1f0d689d2cafd3a64be9b548bb8bb0927b0Kevin Enderby      return VDP_STATUS_INVALID_HANDLE;
1796f45b1f0d689d2cafd3a64be9b548bb8bb0927b0Kevin Enderby
1806f45b1f0d689d2cafd3a64be9b548bb8bb0927b0Kevin Enderby   *profile = PipeToProfile(vldecoder->decoder->profile);
1816f45b1f0d689d2cafd3a64be9b548bb8bb0927b0Kevin Enderby   *width = vldecoder->decoder->width;
1826f45b1f0d689d2cafd3a64be9b548bb8bb0927b0Kevin Enderby   *height = vldecoder->decoder->height;
1832c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha
1842c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha   return VDP_STATUS_OK;
185de7cbbfcce5c068f0699bdcb6dac093c0c91ba6fQuentin Colombet}
186de7cbbfcce5c068f0699bdcb6dac093c0c91ba6fQuentin Colombet
187de7cbbfcce5c068f0699bdcb6dac093c0c91ba6fQuentin Colombet/**
188de7cbbfcce5c068f0699bdcb6dac093c0c91ba6fQuentin Colombet * Decode a mpeg 1/2 video.
189de7cbbfcce5c068f0699bdcb6dac093c0c91ba6fQuentin Colombet */
190de7cbbfcce5c068f0699bdcb6dac093c0c91ba6fQuentin Colombetstatic VdpStatus
191de7cbbfcce5c068f0699bdcb6dac093c0c91ba6fQuentin ColombetvlVdpDecoderRenderMpeg12(struct pipe_video_decoder *decoder,
192dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                         VdpPictureInfoMPEG1Or2 *picture_info,
193de7cbbfcce5c068f0699bdcb6dac093c0c91ba6fQuentin Colombet                         uint32_t bitstream_buffer_count,
19436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                         VdpBitstreamBuffer const *bitstream_buffers)
19536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines{
19636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines   struct pipe_mpeg12_picture_desc picture;
197de7cbbfcce5c068f0699bdcb6dac093c0c91ba6fQuentin Colombet   struct pipe_mpeg12_quant_matrix quant;
198de7cbbfcce5c068f0699bdcb6dac093c0c91ba6fQuentin Colombet   struct pipe_video_buffer *ref_frames[2];
199   unsigned i;
200
201   VDPAU_MSG(VDPAU_TRACE, "[VDPAU] Decoding MPEG12\n");
202
203   i = 0;
204
205   /* if surfaces equals VDP_STATUS_INVALID_HANDLE, they are not used */
206   if (picture_info->forward_reference !=  VDP_INVALID_HANDLE) {
207      ref_frames[i] = ((vlVdpSurface *)vlGetDataHTAB(picture_info->forward_reference))->video_buffer;
208      if (!ref_frames[i])
209         return VDP_STATUS_INVALID_HANDLE;
210      ++i;
211   }
212
213   if (picture_info->backward_reference !=  VDP_INVALID_HANDLE) {
214      ref_frames[i] = ((vlVdpSurface *)vlGetDataHTAB(picture_info->backward_reference))->video_buffer;
215      if (!ref_frames[i])
216         return VDP_STATUS_INVALID_HANDLE;
217      ++i;
218   }
219
220   decoder->set_reference_frames(decoder, ref_frames, i);
221
222   memset(&picture, 0, sizeof(picture));
223   picture.base.profile = decoder->profile;
224   picture.picture_coding_type = picture_info->picture_coding_type;
225   picture.picture_structure = picture_info->picture_structure;
226   picture.frame_pred_frame_dct = picture_info->frame_pred_frame_dct;
227   picture.q_scale_type = picture_info->q_scale_type;
228   picture.alternate_scan = picture_info->alternate_scan;
229   picture.intra_vlc_format = picture_info->intra_vlc_format;
230   picture.concealment_motion_vectors = picture_info->concealment_motion_vectors;
231   picture.intra_dc_precision = picture_info->intra_dc_precision;
232   picture.f_code[0][0] = picture_info->f_code[0][0] - 1;
233   picture.f_code[0][1] = picture_info->f_code[0][1] - 1;
234   picture.f_code[1][0] = picture_info->f_code[1][0] - 1;
235   picture.f_code[1][1] = picture_info->f_code[1][1] - 1;
236   picture.num_slices = picture_info->slice_count;
237
238   decoder->set_picture_parameters(decoder, &picture.base);
239
240   memset(&quant, 0, sizeof(quant));
241   quant.base.codec = PIPE_VIDEO_CODEC_MPEG12;
242   quant.intra_matrix = picture_info->intra_quantizer_matrix;
243   quant.non_intra_matrix = picture_info->non_intra_quantizer_matrix;
244
245   decoder->set_quant_matrix(decoder, &quant.base);
246
247   decoder->begin_frame(decoder);
248
249   for (i = 0; i < bitstream_buffer_count; ++i)
250      decoder->decode_bitstream(decoder, bitstream_buffers[i].bitstream_bytes,
251                                bitstream_buffers[i].bitstream);
252
253   decoder->end_frame(decoder);
254
255   return VDP_STATUS_OK;
256}
257
258/**
259 * Decode a compressed field/frame and render the result into a VdpVideoSurface.
260 */
261VdpStatus
262vlVdpDecoderRender(VdpDecoder decoder,
263                   VdpVideoSurface target,
264                   VdpPictureInfo const *picture_info,
265                   uint32_t bitstream_buffer_count,
266                   VdpBitstreamBuffer const *bitstream_buffers)
267{
268   vlVdpDecoder *vldecoder;
269   vlVdpSurface *vlsurf;
270
271   VDPAU_MSG(VDPAU_TRACE, "[VDPAU] Decoding\n");
272
273   if (!(picture_info && bitstream_buffers))
274      return VDP_STATUS_INVALID_POINTER;
275
276   vldecoder = (vlVdpDecoder *)vlGetDataHTAB(decoder);
277   if (!vldecoder)
278      return VDP_STATUS_INVALID_HANDLE;
279
280   vlsurf = (vlVdpSurface *)vlGetDataHTAB(target);
281   if (!vlsurf)
282      return VDP_STATUS_INVALID_HANDLE;
283
284   if (vlsurf->device != vldecoder->device)
285      return VDP_STATUS_HANDLE_DEVICE_MISMATCH;
286
287   if (vlsurf->video_buffer->chroma_format != vldecoder->decoder->chroma_format)
288      // TODO: Recreate decoder with correct chroma
289      return VDP_STATUS_INVALID_CHROMA_TYPE;
290
291   // TODO: Right now only mpeg 1 & 2 videos are supported.
292   switch (vldecoder->decoder->profile) {
293   case PIPE_VIDEO_PROFILE_MPEG1:
294   case PIPE_VIDEO_PROFILE_MPEG2_SIMPLE:
295   case PIPE_VIDEO_PROFILE_MPEG2_MAIN:
296      ++vldecoder->cur_buffer;
297      vldecoder->cur_buffer %= vldecoder->num_buffers;
298
299      vldecoder->decoder->set_decode_buffer(vldecoder->decoder, vldecoder->buffers[vldecoder->cur_buffer]);
300      vldecoder->decoder->set_decode_target(vldecoder->decoder, vlsurf->video_buffer);
301
302      return vlVdpDecoderRenderMpeg12(vldecoder->decoder, (VdpPictureInfoMPEG1Or2 *)picture_info,
303                                      bitstream_buffer_count, bitstream_buffers);
304      break;
305
306   default:
307      return VDP_STATUS_INVALID_DECODER_PROFILE;
308   }
309}
310