1 /**************************************************************************
3 * Copyright 2013 Advanced Micro Devices, Inc.
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 THE COPYRIGHT HOLDER(S) OR AUTHOR(S) 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 **************************************************************************/
30 * Christian König <christian.koenig@amd.com>
34 #include "pipe/p_video_codec.h"
35 #include "vl/vl_vlc.h"
36 #include "vl/vl_zscan.h"
40 static uint8_t default_intra_matrix
[64] = {
41 8, 16, 19, 22, 26, 27, 29, 34,
42 16, 16, 19, 22, 22, 22, 22, 26,
43 26, 27, 22, 26, 26, 27, 29, 24,
44 27, 27, 29, 32, 27, 29, 29, 32,
45 35, 29, 34, 34, 35, 40, 34, 34,
46 37, 40, 48, 37, 38, 40, 48, 58,
47 26, 27, 29, 34, 38, 46, 56, 69,
48 27, 29, 35, 38, 46, 56, 69, 83
51 static uint8_t default_non_intra_matrix
[64] = {
52 16, 16, 16, 16, 16, 16, 16, 16,
53 16, 16, 16, 16, 16, 16, 16, 16,
54 16, 16, 16, 16, 16, 16, 16, 16,
55 16, 16, 16, 16, 16, 16, 16, 16,
56 16, 16, 16, 16, 16, 16, 16, 16,
57 16, 16, 16, 16, 16, 16, 16, 16,
58 16, 16, 16, 16, 16, 16, 16, 16,
59 16, 16, 16, 16, 16, 16, 16, 16
62 static void vid_dec_mpeg12_Decode(vid_dec_PrivateType
*priv
, struct vl_vlc
*vlc
, unsigned min_bits_left
);
63 static void vid_dec_mpeg12_EndFrame(vid_dec_PrivateType
*priv
);
64 static struct pipe_video_buffer
*vid_dec_mpeg12_Flush(vid_dec_PrivateType
*priv
);
66 void vid_dec_mpeg12_Init(vid_dec_PrivateType
*priv
)
68 struct pipe_video_codec templat
= {};
69 omx_base_video_PortType
*port
;
71 port
= (omx_base_video_PortType
*)priv
->ports
[OMX_BASE_FILTER_INPUTPORT_INDEX
];
72 templat
.profile
= priv
->profile
;
73 templat
.entrypoint
= PIPE_VIDEO_ENTRYPOINT_BITSTREAM
;
74 templat
.chroma_format
= PIPE_VIDEO_CHROMA_FORMAT_420
;
75 templat
.max_references
= 2;
76 templat
.expect_chunked_decode
= true;
77 templat
.width
= port
->sPortParam
.format
.video
.nFrameWidth
;
78 templat
.height
= port
->sPortParam
.format
.video
.nFrameHeight
;
80 priv
->codec
= priv
->pipe
->create_video_codec(priv
->pipe
, &templat
);
82 priv
->picture
.base
.profile
= PIPE_VIDEO_PROFILE_MPEG2_MAIN
;
83 priv
->picture
.mpeg12
.intra_matrix
= default_intra_matrix
;
84 priv
->picture
.mpeg12
.non_intra_matrix
= default_non_intra_matrix
;
86 priv
->Decode
= vid_dec_mpeg12_Decode
;
87 priv
->EndFrame
= vid_dec_mpeg12_EndFrame
;
88 priv
->Flush
= vid_dec_mpeg12_Flush
;
91 static void BeginFrame(vid_dec_PrivateType
*priv
)
93 if (priv
->picture
.mpeg12
.picture_coding_type
!= PIPE_MPEG12_PICTURE_CODING_TYPE_B
) {
94 priv
->picture
.mpeg12
.ref
[0] = priv
->picture
.mpeg12
.ref
[1];
95 priv
->picture
.mpeg12
.ref
[1] = NULL
;
98 if (priv
->target
== priv
->picture
.mpeg12
.ref
[0]) {
99 struct pipe_video_buffer
*tmp
= priv
->target
;
100 priv
->target
= priv
->shadow
;
104 vid_dec_NeedTarget(priv
);
106 priv
->codec
->begin_frame(priv
->codec
, priv
->target
, &priv
->picture
.base
);
107 priv
->frame_started
= true;
110 static void vid_dec_mpeg12_EndFrame(vid_dec_PrivateType
*priv
)
112 struct pipe_video_buffer
*done
;
114 priv
->codec
->end_frame(priv
->codec
, priv
->target
, &priv
->picture
.base
);
115 priv
->frame_started
= false;
117 if (priv
->picture
.mpeg12
.picture_coding_type
!= PIPE_MPEG12_PICTURE_CODING_TYPE_B
) {
119 priv
->picture
.mpeg12
.ref
[1] = priv
->target
;
120 done
= priv
->picture
.mpeg12
.ref
[0];
129 priv
->frame_finished
= true;
130 priv
->target
= priv
->in_buffers
[0]->pInputPortPrivate
;
131 priv
->in_buffers
[0]->pInputPortPrivate
= done
;
134 static struct pipe_video_buffer
*vid_dec_mpeg12_Flush(vid_dec_PrivateType
*priv
)
136 struct pipe_video_buffer
*result
= priv
->picture
.mpeg12
.ref
[1];
137 priv
->picture
.mpeg12
.ref
[1] = NULL
;
141 static void vid_dec_mpeg12_Decode(vid_dec_PrivateType
*priv
, struct vl_vlc
*vlc
, unsigned min_bits_left
)
146 if (!vl_vlc_search_byte(vlc
, vl_vlc_bits_left(vlc
) - min_bits_left
, 0x00))
149 if (vl_vlc_peekbits(vlc
, 24) != 0x000001) {
150 vl_vlc_eatbits(vlc
, 8);
155 unsigned bytes
= priv
->bytes_left
- (vl_vlc_bits_left(vlc
) / 8);
156 priv
->codec
->decode_bitstream(priv
->codec
, priv
->target
, &priv
->picture
.base
,
157 1, &priv
->slice
, &bytes
);
161 vl_vlc_eatbits(vlc
, 24);
162 code
= vl_vlc_get_uimsbf(vlc
, 8);
164 if (priv
->frame_started
&& (code
== 0x00 || code
> 0xAF))
165 vid_dec_mpeg12_EndFrame(priv
);
168 /* sequence header code */
169 vl_vlc_fillbits(vlc
);
171 /* horizontal_size_value */
172 vl_vlc_get_uimsbf(vlc
, 12);
174 /* vertical_size_value */
175 vl_vlc_get_uimsbf(vlc
, 12);
177 /* aspect_ratio_information */
178 vl_vlc_get_uimsbf(vlc
, 4);
180 /* frame_rate_code */
181 vl_vlc_get_uimsbf(vlc
, 4);
183 vl_vlc_fillbits(vlc
);
186 vl_vlc_get_uimsbf(vlc
, 18);
189 vl_vlc_get_uimsbf(vlc
, 1);
191 /* vbv_buffer_size_value */
192 vl_vlc_get_uimsbf(vlc
, 10);
194 /* constrained_parameters_flag */
195 vl_vlc_get_uimsbf(vlc
, 1);
197 vl_vlc_fillbits(vlc
);
199 /* load_intra_quantiser_matrix */
200 if (vl_vlc_get_uimsbf(vlc
, 1)) {
201 /* intra_quantiser_matrix */
202 priv
->picture
.mpeg12
.intra_matrix
= priv
->codec_data
.mpeg12
.intra_matrix
;
203 for (i
= 0; i
< 64; ++i
) {
204 priv
->codec_data
.mpeg12
.intra_matrix
[vl_zscan_normal
[i
]] = vl_vlc_get_uimsbf(vlc
, 8);
205 vl_vlc_fillbits(vlc
);
208 priv
->picture
.mpeg12
.intra_matrix
= default_intra_matrix
;
210 /* load_non_intra_quantiser_matrix */
211 if (vl_vlc_get_uimsbf(vlc
, 1)) {
212 /* non_intra_quantiser_matrix */
213 priv
->picture
.mpeg12
.non_intra_matrix
= priv
->codec_data
.mpeg12
.non_intra_matrix
;
214 for (i
= 0; i
< 64; ++i
) {
215 priv
->codec_data
.mpeg12
.non_intra_matrix
[i
] = vl_vlc_get_uimsbf(vlc
, 8);
216 vl_vlc_fillbits(vlc
);
219 priv
->picture
.mpeg12
.non_intra_matrix
= default_non_intra_matrix
;
221 } else if (code
== 0x00) {
222 /* picture start code */
223 vl_vlc_fillbits(vlc
);
225 /* temporal_reference */
226 vl_vlc_get_uimsbf(vlc
, 10);
228 priv
->picture
.mpeg12
.picture_coding_type
= vl_vlc_get_uimsbf(vlc
, 3);
231 vl_vlc_get_uimsbf(vlc
, 16);
233 vl_vlc_fillbits(vlc
);
234 if (priv
->picture
.mpeg12
.picture_coding_type
== 2 ||
235 priv
->picture
.mpeg12
.picture_coding_type
== 3) {
236 priv
->picture
.mpeg12
.full_pel_forward_vector
= vl_vlc_get_uimsbf(vlc
, 1);
238 priv
->picture
.mpeg12
.f_code
[0][0] = vl_vlc_get_uimsbf(vlc
, 3) - 1;
239 priv
->picture
.mpeg12
.f_code
[0][1] = priv
->picture
.mpeg12
.f_code
[0][0];
241 priv
->picture
.mpeg12
.full_pel_forward_vector
= 0;
242 priv
->picture
.mpeg12
.f_code
[0][1] = priv
->picture
.mpeg12
.f_code
[0][0] = 14;
245 if (priv
->picture
.mpeg12
.picture_coding_type
== 3) {
246 priv
->picture
.mpeg12
.full_pel_backward_vector
= vl_vlc_get_uimsbf(vlc
, 1);
247 /* backward_f_code */
248 priv
->picture
.mpeg12
.f_code
[1][0] = vl_vlc_get_uimsbf(vlc
, 3) - 1;
249 priv
->picture
.mpeg12
.f_code
[1][1] = priv
->picture
.mpeg12
.f_code
[1][0];
251 priv
->picture
.mpeg12
.full_pel_backward_vector
= 0;
252 priv
->picture
.mpeg12
.f_code
[0][1] = priv
->picture
.mpeg12
.f_code
[0][0] = 14;
255 /* extra_bit_picture */
256 while (vl_vlc_get_uimsbf(vlc
, 1)) {
257 /* extra_information_picture */
258 vl_vlc_get_uimsbf(vlc
, 8);
259 vl_vlc_fillbits(vlc
);
262 } else if (code
== 0xB5) {
263 /* extension start code */
264 vl_vlc_fillbits(vlc
);
266 /* extension_start_code_identifier */
267 switch (vl_vlc_get_uimsbf(vlc
, 4)) {
268 case 0x3: /* quant matrix extension */
270 /* load_intra_quantiser_matrix */
271 if (vl_vlc_get_uimsbf(vlc
, 1)) {
272 /* intra_quantiser_matrix */
273 priv
->picture
.mpeg12
.intra_matrix
= priv
->codec_data
.mpeg12
.intra_matrix
;
274 for (i
= 0; i
< 64; ++i
) {
275 priv
->codec_data
.mpeg12
.intra_matrix
[vl_zscan_normal
[i
]] = vl_vlc_get_uimsbf(vlc
, 8);
276 vl_vlc_fillbits(vlc
);
279 priv
->picture
.mpeg12
.intra_matrix
= default_intra_matrix
;
281 /* load_non_intra_quantiser_matrix */
282 if (vl_vlc_get_uimsbf(vlc
, 1)) {
283 /* non_intra_quantiser_matrix */
284 priv
->picture
.mpeg12
.non_intra_matrix
= priv
->codec_data
.mpeg12
.non_intra_matrix
;
285 for (i
= 0; i
< 64; ++i
) {
286 priv
->codec_data
.mpeg12
.non_intra_matrix
[i
] = vl_vlc_get_uimsbf(vlc
, 8);
287 vl_vlc_fillbits(vlc
);
290 priv
->picture
.mpeg12
.intra_matrix
= default_non_intra_matrix
;
294 case 0x8: /* picture coding extension */
296 priv
->picture
.mpeg12
.f_code
[0][0] = vl_vlc_get_uimsbf(vlc
, 4) - 1;
297 priv
->picture
.mpeg12
.f_code
[0][1] = vl_vlc_get_uimsbf(vlc
, 4) - 1;
298 priv
->picture
.mpeg12
.f_code
[1][0] = vl_vlc_get_uimsbf(vlc
, 4) - 1;
299 priv
->picture
.mpeg12
.f_code
[1][1] = vl_vlc_get_uimsbf(vlc
, 4) - 1;
300 priv
->picture
.mpeg12
.intra_dc_precision
= vl_vlc_get_uimsbf(vlc
, 2);
301 priv
->picture
.mpeg12
.picture_structure
= vl_vlc_get_uimsbf(vlc
, 2);
302 priv
->picture
.mpeg12
.top_field_first
= vl_vlc_get_uimsbf(vlc
, 1);
303 priv
->picture
.mpeg12
.frame_pred_frame_dct
= vl_vlc_get_uimsbf(vlc
, 1);
304 priv
->picture
.mpeg12
.concealment_motion_vectors
= vl_vlc_get_uimsbf(vlc
, 1);
305 priv
->picture
.mpeg12
.q_scale_type
= vl_vlc_get_uimsbf(vlc
, 1);
306 priv
->picture
.mpeg12
.intra_vlc_format
= vl_vlc_get_uimsbf(vlc
, 1);
307 priv
->picture
.mpeg12
.alternate_scan
= vl_vlc_get_uimsbf(vlc
, 1);
309 /* repeat_first_field */
310 vl_vlc_get_uimsbf(vlc
, 1);
312 /* chroma_420_type */
313 vl_vlc_get_uimsbf(vlc
, 1);
315 vl_vlc_fillbits(vlc
);
317 /* progressive_frame */
318 vl_vlc_get_uimsbf(vlc
, 1);
320 /* composite_display_flag */
321 if (vl_vlc_get_uimsbf(vlc
, 1)) {
324 vl_vlc_get_uimsbf(vlc
, 1);
327 vl_vlc_get_uimsbf(vlc
, 3);
330 vl_vlc_get_uimsbf(vlc
, 1);
332 /* burst_amplitude */
333 vl_vlc_get_uimsbf(vlc
, 7);
335 /* sub_carrier_phase */
336 vl_vlc_get_uimsbf(vlc
, 8);
341 } else if (code
<= 0xAF) {
343 unsigned bytes
= (vl_vlc_valid_bits(vlc
) / 8) + 4;
345 const void *ptr
= buf
;
348 if (!priv
->frame_started
)
355 for (i
= 4; i
< bytes
; ++i
)
356 buf
[i
] = vl_vlc_get_uimsbf(vlc
, 8);
358 priv
->codec
->decode_bitstream(priv
->codec
, priv
->target
, &priv
->picture
.base
,
361 priv
->bytes_left
= vl_vlc_bits_left(vlc
) / 8;
362 priv
->slice
= vlc
->data
;
364 } else if (code
== 0xB2) {
365 /* user data start */
367 } else if (code
== 0xB4) {
369 } else if (code
== 0xB7) {
371 } else if (code
== 0xB8) {
373 } else if (code
>= 0xB9) {
379 /* resync to byte boundary */
380 vl_vlc_eatbits(vlc
, vl_vlc_valid_bits(vlc
) % 8);