• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "util/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 
vid_dec_mpeg12_Init(vid_dec_PrivateType * priv)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 
BeginFrame(vid_dec_PrivateType * priv)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 
vid_dec_mpeg12_EndFrame(vid_dec_PrivateType * priv)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 
vid_dec_mpeg12_Flush(vid_dec_PrivateType * priv,OMX_TICKS * timestamp)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 
vid_dec_mpeg12_Decode(vid_dec_PrivateType * priv,struct vl_vlc * vlc,unsigned min_bits_left)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