1 /**************************************************************************
3 * Copyright 2010 Thomas Balling Sørensen.
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:
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
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.
26 **************************************************************************/
28 #include "vdpau_private.h"
29 #include "mpeg2_bitstream_parser.h"
30 #include <util/u_memory.h>
31 #include <util/u_math.h>
32 #include <pipe/p_video_context.h>
33 #include <util/u_debug.h>
36 vlVdpDecoderCreate(VdpDevice device
,
37 VdpDecoderProfile profile
,
38 uint32_t width
, uint32_t height
,
39 uint32_t max_references
,
42 return VDP_STATUS_NO_IMPLEMENTATION
;
45 enum pipe_video_profile p_profile
= PIPE_VIDEO_PROFILE_UNKNOWN
;
46 VdpStatus ret
= VDP_STATUS_OK
;
47 vlVdpDecoder
*vldecoder
= NULL
;
49 debug_printf("[VDPAU] Creating decoder\n");
52 return VDP_STATUS_INVALID_POINTER
;
54 if (!(width
&& height
))
55 return VDP_STATUS_INVALID_VALUE
;
57 vlVdpDevice
*dev
= vlGetDataHTAB(device
);
59 ret
= VDP_STATUS_INVALID_HANDLE
;
63 vldecoder
= CALLOC(1,sizeof(vlVdpDecoder
));
65 ret
= VDP_STATUS_RESOURCES
;
69 p_profile
= ProfileToPipe(profile
);
70 if (p_profile
== PIPE_VIDEO_PROFILE_UNKNOWN
) {
71 ret
= VDP_STATUS_INVALID_DECODER_PROFILE
;
75 // TODO: Define max_references. Used mainly for H264
77 vldecoder
->profile
= p_profile
;
78 vldecoder
->height
= height
;
79 vldecoder
->width
= width
;
80 vldecoder
->device
= dev
;
81 vldecoder
->vctx
= NULL
;
83 *decoder
= vlAddDataHTAB(vldecoder
);
85 ret
= VDP_STATUS_ERROR
;
88 debug_printf("[VDPAU] Decoder created succesfully\n");
103 vlVdpDecoderDestroy(VdpDecoder decoder
)
105 return VDP_STATUS_NO_IMPLEMENTATION
;
108 debug_printf("[VDPAU] Destroying decoder\n");
109 vlVdpDecoder
*vldecoder
;
111 vldecoder
= (vlVdpDecoder
*)vlGetDataHTAB(decoder
);
113 return VDP_STATUS_INVALID_HANDLE
;
116 if (vldecoder
->vctx
) {
117 if (vldecoder
->vctx
->vscreen
)
118 vl_screen_destroy(vldecoder
->vctx
->vscreen
);
122 vl_video_destroy(vldecoder
->vctx
);
126 return VDP_STATUS_OK
;
132 vlVdpCreateSurfaceTarget(vlVdpDecoder
*vldecoder
, vlVdpSurface
*vlsurf
)
134 struct pipe_surface surf_template
;
135 struct pipe_resource tmplt
;
136 struct pipe_resource
*surf_tex
;
137 struct pipe_video_context
*vctx
;
139 debug_printf("[VDPAU] Creating surface\n");
141 if(!(vldecoder
&& vlsurf
))
142 return VDP_STATUS_INVALID_POINTER
;
144 vctx
= vldecoder
->vctx
->vpipe
;
146 if (!vctx
->is_format_supported(vctx
, tmplt
.format
, PIPE_BIND_SAMPLER_VIEW
| PIPE_BIND_RENDER_TARGET
))
147 return VDP_STATUS_RESOURCES
;
149 memset(&tmplt
, 0, sizeof(struct pipe_resource
));
150 tmplt
.target
= PIPE_TEXTURE_2D
;
152 //tmplt.format = vctx->get_param(vctx,PIPE_CAP_DECODE_TARGET_PREFERRED_FORMAT);
153 tmplt
.last_level
= 0;
154 tmplt
.width0
= vlsurf
->width
;
155 tmplt
.height0
= vlsurf
->height
;
157 tmplt
.usage
= PIPE_USAGE_DEFAULT
;
158 tmplt
.bind
= PIPE_BIND_SAMPLER_VIEW
| PIPE_BIND_RENDER_TARGET
;
161 surf_tex
= vctx
->screen
->resource_create(vctx
->screen
, &tmplt
);
163 memset(&surf_template
, 0, sizeof(surf_template
));
164 surf_template
.format
= surf_tex
->format
;
165 surf_template
.usage
= PIPE_BIND_SAMPLER_VIEW
| PIPE_BIND_RENDER_TARGET
;
166 //vlsurf->psurface = vctx->create_surface(vctx->screen, surf_tex, &surf_template);
168 pipe_resource_reference(&surf_tex
, NULL
);
170 //if (!vlsurf->psurface)
171 // return VDP_STATUS_RESOURCES;
172 debug_printf("[VDPAU] Done creating surface\n");
174 return VDP_STATUS_OK
;
178 vlVdpDecoderRenderMpeg2(vlVdpDecoder
*vldecoder
,
179 vlVdpSurface
*vlsurf
,
180 VdpPictureInfoMPEG1Or2
*picture_info
,
181 uint32_t bitstream_buffer_count
,
182 VdpBitstreamBuffer
const *bitstream_buffers
)
184 struct pipe_video_context
*vpipe
;
185 vlVdpSurface
*t_vdp_surf
;
186 vlVdpSurface
*p_vdp_surf
;
187 vlVdpSurface
*f_vdp_surf
;
188 struct pipe_surface
*t_surf
;
189 struct pipe_surface
*p_surf
;
190 struct pipe_surface
*f_surf
;
191 uint32_t num_macroblocks
;
192 struct pipe_mpeg12_macroblock
*pipe_macroblocks
;
195 debug_printf("[VDPAU] Decoding MPEG2\n");
199 /* if surfaces equals VDP_STATUS_INVALID_HANDLE, they are not used */
200 if (picture_info
->backward_reference
== VDP_INVALID_HANDLE
)
203 p_vdp_surf
= (vlVdpSurface
*)vlGetDataHTAB(picture_info
->backward_reference
);
205 return VDP_STATUS_INVALID_HANDLE
;
208 if (picture_info
->forward_reference
== VDP_INVALID_HANDLE
)
211 f_vdp_surf
= (vlVdpSurface
*)vlGetDataHTAB(picture_info
->forward_reference
);
213 return VDP_STATUS_INVALID_HANDLE
;
216 if (f_vdp_surf
== VDP_INVALID_HANDLE
) f_vdp_surf
= NULL
;
218 ret
= vlVdpCreateSurfaceTarget(vldecoder
,t_vdp_surf
);
220 vpipe
= vldecoder
->vctx
->vpipe
;
222 if (vlVdpMPEG2BitstreamToMacroblock(vpipe
->screen
, bitstream_buffers
, bitstream_buffer_count
,
223 &num_macroblocks
, &pipe_macroblocks
))
225 debug_printf("[VDPAU] Error in frame-header. Skipping.\n");
232 //vpipe->set_decode_target(vpipe,t_surf);
233 //vpipe->decode_macroblocks(vpipe, p_surf, f_surf, num_macroblocks,
234 // (struct pipe_macroblock *)pipe_macroblocks, NULL);
242 vlVdpDecoderRender(VdpDecoder decoder
,
243 VdpVideoSurface target
,
244 VdpPictureInfo
const *picture_info
,
245 uint32_t bitstream_buffer_count
,
246 VdpBitstreamBuffer
const *bitstream_buffers
)
248 return VDP_STATUS_NO_IMPLEMENTATION
;
251 vlVdpDecoder
*vldecoder
;
252 vlVdpSurface
*vlsurf
;
253 struct vl_screen
*vscreen
;
256 debug_printf("[VDPAU] Decoding\n");
258 if (!(picture_info
&& bitstream_buffers
))
259 return VDP_STATUS_INVALID_POINTER
;
261 vldecoder
= (vlVdpDecoder
*)vlGetDataHTAB(decoder
);
263 return VDP_STATUS_INVALID_HANDLE
;
265 vlsurf
= (vlVdpSurface
*)vlGetDataHTAB(target
);
267 return VDP_STATUS_INVALID_HANDLE
;
269 if (vlsurf
->device
!= vldecoder
->device
)
270 return VDP_STATUS_HANDLE_DEVICE_MISMATCH
;
272 /* Test doesn't make sence */
273 /*if (vlsurf->chroma_format != vldecoder->chroma_format)
274 return VDP_STATUS_INVALID_CHROMA_TYPE;*/
276 vscreen
= vl_screen_create(vldecoder
->device
->display
, vldecoder
->device
->screen
);
278 return VDP_STATUS_RESOURCES
;
280 vldecoder
->vctx
= vl_video_create(vscreen
, vldecoder
->profile
, vlsurf
->chroma_format
, vldecoder
->width
, vldecoder
->height
);
281 if (!vldecoder
->vctx
)
282 return VDP_STATUS_RESOURCES
;
284 // TODO: Right now only mpeg2 is supported.
285 switch (vldecoder
->vctx
->vpipe
->profile
) {
286 case PIPE_VIDEO_PROFILE_MPEG2_SIMPLE
:
287 case PIPE_VIDEO_PROFILE_MPEG2_MAIN
:
288 ret
= vlVdpDecoderRenderMpeg2(vldecoder
,vlsurf
,(VdpPictureInfoMPEG1Or2
*)picture_info
,
289 bitstream_buffer_count
,bitstream_buffers
);
292 return VDP_STATUS_INVALID_DECODER_PROFILE
;
301 vlVdpGenerateCSCMatrix(VdpProcamp
*procamp
,
302 VdpColorStandard standard
,
303 VdpCSCMatrix
*csc_matrix
)
305 debug_printf("[VDPAU] Generating CSCMatrix\n");
306 if (!(csc_matrix
&& procamp
))
307 return VDP_STATUS_INVALID_POINTER
;
309 return VDP_STATUS_OK
;