decode.c revision 725e4ada3062c80623abf51477dfdc73fe294f3f
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 "vdpau_private.h"
29#include <util/u_memory.h>
30#include <pipe/p_video_context.h>
31
32VdpStatus
33vlVdpDecoderCreate ( 	VdpDevice device,
34						VdpDecoderProfile profile,
35						uint32_t width, uint32_t height,
36						uint32_t max_references,
37						VdpDecoder *decoder
38)
39{
40	enum pipe_video_profile p_profile;
41	VdpStatus ret;
42	vlVdpDecoder *vldecoder;
43
44	if (!decoder)
45		return VDP_STATUS_INVALID_POINTER;
46
47	if (!(width && height))
48		return VDP_STATUS_INVALID_VALUE;
49
50   vlVdpDevice *dev = vlGetDataHTAB(device);
51   if (!dev)  {
52      ret = VDP_STATUS_INVALID_HANDLE;
53      goto inv_device;
54   }
55
56   vldecoder = CALLOC(1,sizeof(vlVdpDecoder));
57   if (!vldecoder)   {
58	   ret = VDP_STATUS_RESOURCES;
59	   goto no_decoder;
60   }
61
62   vldecoder->vlscreen = vl_screen_create(dev->display, dev->screen);
63   if (!vldecoder->vlscreen)
64      ret = VDP_STATUS_RESOURCES;
65	  goto no_screen;
66
67
68   p_profile = ProfileToPipe(profile);
69   if (p_profile == PIPE_VIDEO_PROFILE_UNKNOWN)	{
70	   ret = VDP_STATUS_INVALID_DECODER_PROFILE;
71	   goto inv_profile;
72   }
73
74	// TODO: Define max_references. Used mainly for H264
75
76	vldecoder->chroma_format = p_profile;
77	vldecoder->device = dev;
78
79	*decoder = vlAddDataHTAB(vldecoder);
80	if (*decoder == 0) {
81      ret = VDP_STATUS_ERROR;
82      goto no_handle;
83	}
84
85	return VDP_STATUS_OK;
86
87	no_handle:
88	FREE(vldecoder);
89	inv_profile:
90	no_screen:
91	no_decoder:
92	inv_device:
93    return ret;
94}
95
96VdpStatus
97vlVdpDecoderDestroy  (VdpDecoder decoder
98)
99{
100	vlVdpDecoder *vldecoder;
101
102	vldecoder = (vlVdpDecoder *)vlGetDataHTAB(decoder);
103	if (!vldecoder)  {
104      return VDP_STATUS_INVALID_HANDLE;
105	}
106
107	if (vldecoder->vctx)
108		vl_video_destroy(vldecoder->vctx);
109
110	if (vldecoder->vlscreen)
111		vl_screen_destroy(vldecoder->vlscreen);
112
113	FREE(vldecoder);
114
115	return VDP_STATUS_OK;
116}
117
118VdpStatus
119vlVdpCreateSurface		   (vlVdpDecoder *vldecoder,
120							vlVdpSurface *vlsurf
121)
122{
123
124	return VDP_STATUS_OK;
125}
126
127VdpStatus
128vlVdpDecoderRenderMpeg2    (vlVdpDecoder *vldecoder,
129							vlVdpSurface *vlsurf,
130							VdpPictureInfoMPEG1Or2 *picture_info,
131							uint32_t bitstream_buffer_count,
132							VdpBitstreamBuffer const *bitstream_buffers
133							)
134{
135	struct pipe_video_context *vpipe;
136	vlVdpSurface *t_vdp_surf;
137	vlVdpSurface *p_vdp_surf;
138	vlVdpSurface *f_vdp_surf;
139	struct pipe_surface *t_surf;
140	struct pipe_surface *p_surf;
141	struct pipe_surface *f_surf;
142	uint32_t num_macroblocks;
143
144	vpipe = vldecoder->vctx->vpipe;
145	t_vdp_surf = vlsurf;
146    p_vdp_surf = (vlVdpSurface *)vlGetDataHTAB(picture_info->backward_reference);
147	if (p_vdp_surf)
148		return VDP_STATUS_INVALID_HANDLE;
149
150	f_vdp_surf = (vlVdpSurface *)vlGetDataHTAB(picture_info->forward_reference);
151	if (f_vdp_surf)
152		return VDP_STATUS_INVALID_HANDLE;
153
154	/* if surfaces equals VDP_STATUS_INVALID_HANDLE, they are not used */
155	if (p_vdp_surf ==  VDP_INVALID_HANDLE) p_vdp_surf = NULL;
156	if (f_vdp_surf ==  VDP_INVALID_HANDLE) f_vdp_surf = NULL;
157
158	vlVdpCreateSurface(vldecoder,t_vdp_surf);
159
160	num_macroblocks = picture_info->slice_count;
161	struct pipe_mpeg12_macroblock pipe_macroblocks[num_macroblocks];
162
163	/*VdpMacroBlocksToPipe(vpipe->screen, macroblocks, blocks, first_macroblock,
164                     num_macroblocks, pipe_macroblocks);*/
165
166	vpipe->set_decode_target(vpipe,t_surf);
167	/*vpipe->decode_macroblocks(vpipe, p_surf, f_surf, num_macroblocks,
168		&pipe_macroblocks->base, &target_surface_priv->render_fence);*/
169}
170
171VdpStatus
172vlVdpDecoderRender (VdpDecoder decoder,
173					VdpVideoSurface target,
174					VdpPictureInfo const *picture_info,
175					uint32_t bitstream_buffer_count,
176					VdpBitstreamBuffer const *bitstream_buffers
177)
178{
179	vlVdpDecoder *vldecoder;
180	vlVdpSurface *vlsurf;
181	VdpStatus ret;
182
183	if (!(picture_info && bitstream_buffers))
184		return VDP_STATUS_INVALID_POINTER;
185
186
187	vldecoder = (vlVdpDecoder *)vlGetDataHTAB(decoder);
188	if (!vldecoder)
189		return VDP_STATUS_INVALID_HANDLE;
190
191	vlsurf = (vlVdpSurface *)vlGetDataHTAB(target);
192	if (!vlsurf)
193		return VDP_STATUS_INVALID_HANDLE;
194
195	if (vlsurf->device != vldecoder->device)
196		return VDP_STATUS_HANDLE_DEVICE_MISMATCH;
197
198	if (vlsurf->chroma_format != vldecoder->chroma_format)
199		return VDP_STATUS_INVALID_CHROMA_TYPE;
200
201    // TODO: Right now only mpeg2 is supported.
202	switch (vldecoder->vctx->vpipe->profile)   {
203		case PIPE_VIDEO_PROFILE_MPEG2_SIMPLE:
204		case PIPE_VIDEO_PROFILE_MPEG2_MAIN:
205			ret = vlVdpDecoderRenderMpeg2(vldecoder,vlsurf,(VdpPictureInfoMPEG1Or2 *)picture_info,
206											bitstream_buffer_count,bitstream_buffers);
207			break;
208		default:
209			return VDP_STATUS_INVALID_DECODER_PROFILE;
210	}
211	assert(0);
212
213	return ret;
214}