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
40static 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
51static 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
62static void vid_dec_mpeg12_Decode(vid_dec_PrivateType *priv, struct vl_vlc *vlc, unsigned min_bits_left);
63static void vid_dec_mpeg12_EndFrame(vid_dec_PrivateType *priv);
64static struct pipe_video_buffer *vid_dec_mpeg12_Flush(vid_dec_PrivateType *priv, OMX_TICKS *timestamp);
65
66void 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
91static 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
110static 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
134static 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
143static 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