st/omx/dec: separate create_video_codec to different codecs
[mesa.git] / src / gallium / state_trackers / omx / vid_dec_mpeg12.c
1 /**************************************************************************
2 *
3 * Copyright 2013 Advanced Micro Devices, Inc.
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 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.
25 *
26 **************************************************************************/
27
28 /*
29 * Authors:
30 * Christian König <christian.koenig@amd.com>
31 *
32 */
33
34 #include "pipe/p_video_codec.h"
35 #include "vl/vl_vlc.h"
36 #include "vl/vl_zscan.h"
37
38 #include "vid_dec.h"
39
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
49 };
50
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
60 };
61
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);
65
66 void vid_dec_mpeg12_Init(vid_dec_PrivateType *priv)
67 {
68 struct pipe_video_codec templat = {};
69 omx_base_video_PortType *port;
70
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;
79
80 priv->codec = priv->pipe->create_video_codec(priv->pipe, &templat);
81
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;
85
86 priv->Decode = vid_dec_mpeg12_Decode;
87 priv->EndFrame = vid_dec_mpeg12_EndFrame;
88 priv->Flush = vid_dec_mpeg12_Flush;
89 }
90
91 static void BeginFrame(vid_dec_PrivateType *priv)
92 {
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;
96 }
97
98 if (priv->target == priv->picture.mpeg12.ref[0]) {
99 struct pipe_video_buffer *tmp = priv->target;
100 priv->target = priv->shadow;
101 priv->shadow = tmp;
102 }
103
104 vid_dec_NeedTarget(priv);
105
106 priv->codec->begin_frame(priv->codec, priv->target, &priv->picture.base);
107 priv->frame_started = true;
108 }
109
110 static void vid_dec_mpeg12_EndFrame(vid_dec_PrivateType *priv)
111 {
112 struct pipe_video_buffer *done;
113
114 priv->codec->end_frame(priv->codec, priv->target, &priv->picture.base);
115 priv->frame_started = false;
116
117 if (priv->picture.mpeg12.picture_coding_type != PIPE_MPEG12_PICTURE_CODING_TYPE_B) {
118
119 priv->picture.mpeg12.ref[1] = priv->target;
120 done = priv->picture.mpeg12.ref[0];
121 if (!done) {
122 priv->target = NULL;
123 return;
124 }
125
126 } else
127 done = priv->target;
128
129 priv->frame_finished = true;
130 priv->target = priv->in_buffers[0]->pInputPortPrivate;
131 priv->in_buffers[0]->pInputPortPrivate = done;
132 }
133
134 static struct pipe_video_buffer *vid_dec_mpeg12_Flush(vid_dec_PrivateType *priv)
135 {
136 struct pipe_video_buffer *result = priv->picture.mpeg12.ref[1];
137 priv->picture.mpeg12.ref[1] = NULL;
138 return result;
139 }
140
141 static void vid_dec_mpeg12_Decode(vid_dec_PrivateType *priv, struct vl_vlc *vlc, unsigned min_bits_left)
142 {
143 uint8_t code;
144 unsigned i;
145
146 if (!vl_vlc_search_byte(vlc, vl_vlc_bits_left(vlc) - min_bits_left, 0x00))
147 return;
148
149 if (vl_vlc_peekbits(vlc, 24) != 0x000001) {
150 vl_vlc_eatbits(vlc, 8);
151 return;
152 }
153
154 if (priv->slice) {
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);
158 priv->slice = NULL;
159 }
160
161 vl_vlc_eatbits(vlc, 24);
162 code = vl_vlc_get_uimsbf(vlc, 8);
163
164 if (priv->frame_started && (code == 0x00 || code > 0xAF))
165 vid_dec_mpeg12_EndFrame(priv);
166
167 if (code == 0xB3) {
168 /* sequence header code */
169 vl_vlc_fillbits(vlc);
170
171 /* horizontal_size_value */
172 vl_vlc_get_uimsbf(vlc, 12);
173
174 /* vertical_size_value */
175 vl_vlc_get_uimsbf(vlc, 12);
176
177 /* aspect_ratio_information */
178 vl_vlc_get_uimsbf(vlc, 4);
179
180 /* frame_rate_code */
181 vl_vlc_get_uimsbf(vlc, 4);
182
183 vl_vlc_fillbits(vlc);
184
185 /* bit_rate_value */
186 vl_vlc_get_uimsbf(vlc, 18);
187
188 /* marker_bit */
189 vl_vlc_get_uimsbf(vlc, 1);
190
191 /* vbv_buffer_size_value */
192 vl_vlc_get_uimsbf(vlc, 10);
193
194 /* constrained_parameters_flag */
195 vl_vlc_get_uimsbf(vlc, 1);
196
197 vl_vlc_fillbits(vlc);
198
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);
206 }
207 } else
208 priv->picture.mpeg12.intra_matrix = default_intra_matrix;
209
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);
217 }
218 } else
219 priv->picture.mpeg12.non_intra_matrix = default_non_intra_matrix;
220
221 } else if (code == 0x00) {
222 /* picture start code */
223 vl_vlc_fillbits(vlc);
224
225 /* temporal_reference */
226 vl_vlc_get_uimsbf(vlc, 10);
227
228 priv->picture.mpeg12.picture_coding_type = vl_vlc_get_uimsbf(vlc, 3);
229
230 /* vbv_delay */
231 vl_vlc_get_uimsbf(vlc, 16);
232
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);
237 /* forward_f_code */
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];
240 } else {
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;
243 }
244
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];
250 } else {
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;
253 }
254
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);
260 }
261
262 } else if (code == 0xB5) {
263 /* extension start code */
264 vl_vlc_fillbits(vlc);
265
266 /* extension_start_code_identifier */
267 switch (vl_vlc_get_uimsbf(vlc, 4)) {
268 case 0x3: /* quant matrix extension */
269
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);
277 }
278 } else
279 priv->picture.mpeg12.intra_matrix = default_intra_matrix;
280
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);
288 }
289 } else
290 priv->picture.mpeg12.intra_matrix = default_non_intra_matrix;
291
292 break;
293
294 case 0x8: /* picture coding extension */
295
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);
308
309 /* repeat_first_field */
310 vl_vlc_get_uimsbf(vlc, 1);
311
312 /* chroma_420_type */
313 vl_vlc_get_uimsbf(vlc, 1);
314
315 vl_vlc_fillbits(vlc);
316
317 /* progressive_frame */
318 vl_vlc_get_uimsbf(vlc, 1);
319
320 /* composite_display_flag */
321 if (vl_vlc_get_uimsbf(vlc, 1)) {
322
323 /* v_axis */
324 vl_vlc_get_uimsbf(vlc, 1);
325
326 /* field_sequence */
327 vl_vlc_get_uimsbf(vlc, 3);
328
329 /* sub_carrier */
330 vl_vlc_get_uimsbf(vlc, 1);
331
332 /* burst_amplitude */
333 vl_vlc_get_uimsbf(vlc, 7);
334
335 /* sub_carrier_phase */
336 vl_vlc_get_uimsbf(vlc, 8);
337 }
338 break;
339 }
340
341 } else if (code <= 0xAF) {
342 /* slice start */
343 unsigned bytes = (vl_vlc_valid_bits(vlc) / 8) + 4;
344 uint8_t buf[12];
345 const void *ptr = buf;
346 unsigned i;
347
348 if (!priv->frame_started)
349 BeginFrame(priv);
350
351 buf[0] = 0x00;
352 buf[1] = 0x00;
353 buf[2] = 0x01;
354 buf[3] = code;
355 for (i = 4; i < bytes; ++i)
356 buf[i] = vl_vlc_get_uimsbf(vlc, 8);
357
358 priv->codec->decode_bitstream(priv->codec, priv->target, &priv->picture.base,
359 1, &ptr, &bytes);
360
361 priv->bytes_left = vl_vlc_bits_left(vlc) / 8;
362 priv->slice = vlc->data;
363
364 } else if (code == 0xB2) {
365 /* user data start */
366
367 } else if (code == 0xB4) {
368 /* sequence error */
369 } else if (code == 0xB7) {
370 /* sequence end */
371 } else if (code == 0xB8) {
372 /* group start */
373 } else if (code >= 0xB9) {
374 /* system start */
375 } else {
376 /* reserved */
377 }
378
379 /* resync to byte boundary */
380 vl_vlc_eatbits(vlc, vl_vlc_valid_bits(vlc) % 8);
381 }