Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mesa
Path: blob/21.2-virgl/src/gallium/frontends/omx/bellagio/vid_dec_mpeg12.c
4565 views
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 <[email protected]>
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, 22, 24, 27, 29, 34, 37,
43
19, 22, 26, 27, 29, 34, 34, 38,
44
22, 22, 26, 27, 29, 34, 37, 40,
45
22, 26, 27, 29, 32, 35, 40, 48,
46
26, 27, 29, 32, 35, 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, OMX_TICKS *timestamp);
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, OMX_TICKS *timestamp)
135
{
136
struct pipe_video_buffer *result = priv->picture.mpeg12.ref[1];
137
priv->picture.mpeg12.ref[1] = NULL;
138
if (timestamp)
139
*timestamp = OMX_VID_DEC_TIMESTAMP_INVALID;
140
return result;
141
}
142
143
static void vid_dec_mpeg12_Decode(vid_dec_PrivateType *priv, struct vl_vlc *vlc, unsigned min_bits_left)
144
{
145
uint8_t code;
146
unsigned i;
147
148
if (!vl_vlc_search_byte(vlc, vl_vlc_bits_left(vlc) - min_bits_left, 0x00))
149
return;
150
151
if (vl_vlc_peekbits(vlc, 24) != 0x000001) {
152
vl_vlc_eatbits(vlc, 8);
153
return;
154
}
155
156
if (priv->slice) {
157
unsigned bytes = priv->bytes_left - (vl_vlc_bits_left(vlc) / 8);
158
priv->codec->decode_bitstream(priv->codec, priv->target, &priv->picture.base,
159
1, &priv->slice, &bytes);
160
priv->slice = NULL;
161
}
162
163
vl_vlc_eatbits(vlc, 24);
164
code = vl_vlc_get_uimsbf(vlc, 8);
165
166
if (priv->frame_started && (code == 0x00 || code > 0xAF))
167
vid_dec_mpeg12_EndFrame(priv);
168
169
if (code == 0xB3) {
170
/* sequence header code */
171
vl_vlc_fillbits(vlc);
172
173
/* horizontal_size_value */
174
vl_vlc_get_uimsbf(vlc, 12);
175
176
/* vertical_size_value */
177
vl_vlc_get_uimsbf(vlc, 12);
178
179
/* aspect_ratio_information */
180
vl_vlc_get_uimsbf(vlc, 4);
181
182
/* frame_rate_code */
183
vl_vlc_get_uimsbf(vlc, 4);
184
185
vl_vlc_fillbits(vlc);
186
187
/* bit_rate_value */
188
vl_vlc_get_uimsbf(vlc, 18);
189
190
/* marker_bit */
191
vl_vlc_get_uimsbf(vlc, 1);
192
193
/* vbv_buffer_size_value */
194
vl_vlc_get_uimsbf(vlc, 10);
195
196
/* constrained_parameters_flag */
197
vl_vlc_get_uimsbf(vlc, 1);
198
199
vl_vlc_fillbits(vlc);
200
201
/* load_intra_quantiser_matrix */
202
if (vl_vlc_get_uimsbf(vlc, 1)) {
203
/* intra_quantiser_matrix */
204
priv->picture.mpeg12.intra_matrix = priv->codec_data.mpeg12.intra_matrix;
205
for (i = 0; i < 64; ++i) {
206
priv->codec_data.mpeg12.intra_matrix[vl_zscan_normal[i]] = vl_vlc_get_uimsbf(vlc, 8);
207
vl_vlc_fillbits(vlc);
208
}
209
} else
210
priv->picture.mpeg12.intra_matrix = default_intra_matrix;
211
212
/* load_non_intra_quantiser_matrix */
213
if (vl_vlc_get_uimsbf(vlc, 1)) {
214
/* non_intra_quantiser_matrix */
215
priv->picture.mpeg12.non_intra_matrix = priv->codec_data.mpeg12.non_intra_matrix;
216
for (i = 0; i < 64; ++i) {
217
priv->codec_data.mpeg12.non_intra_matrix[i] = vl_vlc_get_uimsbf(vlc, 8);
218
vl_vlc_fillbits(vlc);
219
}
220
} else
221
priv->picture.mpeg12.non_intra_matrix = default_non_intra_matrix;
222
223
} else if (code == 0x00) {
224
/* picture start code */
225
vl_vlc_fillbits(vlc);
226
227
/* temporal_reference */
228
vl_vlc_get_uimsbf(vlc, 10);
229
230
priv->picture.mpeg12.picture_coding_type = vl_vlc_get_uimsbf(vlc, 3);
231
232
/* vbv_delay */
233
vl_vlc_get_uimsbf(vlc, 16);
234
235
vl_vlc_fillbits(vlc);
236
if (priv->picture.mpeg12.picture_coding_type == 2 ||
237
priv->picture.mpeg12.picture_coding_type == 3) {
238
priv->picture.mpeg12.full_pel_forward_vector = vl_vlc_get_uimsbf(vlc, 1);
239
/* forward_f_code */
240
priv->picture.mpeg12.f_code[0][0] = vl_vlc_get_uimsbf(vlc, 3) - 1;
241
priv->picture.mpeg12.f_code[0][1] = priv->picture.mpeg12.f_code[0][0];
242
} else {
243
priv->picture.mpeg12.full_pel_forward_vector = 0;
244
priv->picture.mpeg12.f_code[0][1] = priv->picture.mpeg12.f_code[0][0] = 14;
245
}
246
247
if (priv->picture.mpeg12.picture_coding_type == 3) {
248
priv->picture.mpeg12.full_pel_backward_vector = vl_vlc_get_uimsbf(vlc, 1);
249
/* backward_f_code */
250
priv->picture.mpeg12.f_code[1][0] = vl_vlc_get_uimsbf(vlc, 3) - 1;
251
priv->picture.mpeg12.f_code[1][1] = priv->picture.mpeg12.f_code[1][0];
252
} else {
253
priv->picture.mpeg12.full_pel_backward_vector = 0;
254
priv->picture.mpeg12.f_code[0][1] = priv->picture.mpeg12.f_code[0][0] = 14;
255
}
256
257
/* extra_bit_picture */
258
while (vl_vlc_get_uimsbf(vlc, 1)) {
259
/* extra_information_picture */
260
vl_vlc_get_uimsbf(vlc, 8);
261
vl_vlc_fillbits(vlc);
262
}
263
264
} else if (code == 0xB5) {
265
/* extension start code */
266
vl_vlc_fillbits(vlc);
267
268
/* extension_start_code_identifier */
269
switch (vl_vlc_get_uimsbf(vlc, 4)) {
270
case 0x3: /* quant matrix extension */
271
272
/* load_intra_quantiser_matrix */
273
if (vl_vlc_get_uimsbf(vlc, 1)) {
274
/* intra_quantiser_matrix */
275
priv->picture.mpeg12.intra_matrix = priv->codec_data.mpeg12.intra_matrix;
276
for (i = 0; i < 64; ++i) {
277
priv->codec_data.mpeg12.intra_matrix[vl_zscan_normal[i]] = vl_vlc_get_uimsbf(vlc, 8);
278
vl_vlc_fillbits(vlc);
279
}
280
} else
281
priv->picture.mpeg12.intra_matrix = default_intra_matrix;
282
283
/* load_non_intra_quantiser_matrix */
284
if (vl_vlc_get_uimsbf(vlc, 1)) {
285
/* non_intra_quantiser_matrix */
286
priv->picture.mpeg12.non_intra_matrix = priv->codec_data.mpeg12.non_intra_matrix;
287
for (i = 0; i < 64; ++i) {
288
priv->codec_data.mpeg12.non_intra_matrix[i] = vl_vlc_get_uimsbf(vlc, 8);
289
vl_vlc_fillbits(vlc);
290
}
291
} else
292
priv->picture.mpeg12.intra_matrix = default_non_intra_matrix;
293
294
break;
295
296
case 0x8: /* picture coding extension */
297
298
priv->picture.mpeg12.f_code[0][0] = vl_vlc_get_uimsbf(vlc, 4) - 1;
299
priv->picture.mpeg12.f_code[0][1] = vl_vlc_get_uimsbf(vlc, 4) - 1;
300
priv->picture.mpeg12.f_code[1][0] = vl_vlc_get_uimsbf(vlc, 4) - 1;
301
priv->picture.mpeg12.f_code[1][1] = vl_vlc_get_uimsbf(vlc, 4) - 1;
302
priv->picture.mpeg12.intra_dc_precision = vl_vlc_get_uimsbf(vlc, 2);
303
priv->picture.mpeg12.picture_structure = vl_vlc_get_uimsbf(vlc, 2);
304
priv->picture.mpeg12.top_field_first = vl_vlc_get_uimsbf(vlc, 1);
305
priv->picture.mpeg12.frame_pred_frame_dct = vl_vlc_get_uimsbf(vlc, 1);
306
priv->picture.mpeg12.concealment_motion_vectors = vl_vlc_get_uimsbf(vlc, 1);
307
priv->picture.mpeg12.q_scale_type = vl_vlc_get_uimsbf(vlc, 1);
308
priv->picture.mpeg12.intra_vlc_format = vl_vlc_get_uimsbf(vlc, 1);
309
priv->picture.mpeg12.alternate_scan = vl_vlc_get_uimsbf(vlc, 1);
310
311
/* repeat_first_field */
312
vl_vlc_get_uimsbf(vlc, 1);
313
314
/* chroma_420_type */
315
vl_vlc_get_uimsbf(vlc, 1);
316
317
vl_vlc_fillbits(vlc);
318
319
/* progressive_frame */
320
vl_vlc_get_uimsbf(vlc, 1);
321
322
/* composite_display_flag */
323
if (vl_vlc_get_uimsbf(vlc, 1)) {
324
325
/* v_axis */
326
vl_vlc_get_uimsbf(vlc, 1);
327
328
/* field_sequence */
329
vl_vlc_get_uimsbf(vlc, 3);
330
331
/* sub_carrier */
332
vl_vlc_get_uimsbf(vlc, 1);
333
334
/* burst_amplitude */
335
vl_vlc_get_uimsbf(vlc, 7);
336
337
/* sub_carrier_phase */
338
vl_vlc_get_uimsbf(vlc, 8);
339
}
340
break;
341
}
342
343
} else if (code <= 0xAF) {
344
/* slice start */
345
unsigned bytes = (vl_vlc_valid_bits(vlc) / 8) + 4;
346
uint8_t buf[12];
347
const void *ptr = buf;
348
unsigned i;
349
350
if (!priv->frame_started)
351
BeginFrame(priv);
352
353
buf[0] = 0x00;
354
buf[1] = 0x00;
355
buf[2] = 0x01;
356
buf[3] = code;
357
for (i = 4; i < bytes; ++i)
358
buf[i] = vl_vlc_get_uimsbf(vlc, 8);
359
360
priv->codec->decode_bitstream(priv->codec, priv->target, &priv->picture.base,
361
1, &ptr, &bytes);
362
363
priv->bytes_left = vl_vlc_bits_left(vlc) / 8;
364
priv->slice = vlc->data;
365
366
} else if (code == 0xB2) {
367
/* user data start */
368
369
} else if (code == 0xB4) {
370
/* sequence error */
371
} else if (code == 0xB7) {
372
/* sequence end */
373
} else if (code == 0xB8) {
374
/* group start */
375
} else if (code >= 0xB9) {
376
/* system start */
377
} else {
378
/* reserved */
379
}
380
381
/* resync to byte boundary */
382
vl_vlc_eatbits(vlc, vl_vlc_valid_bits(vlc) % 8);
383
}
384
385