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#if ENABLE_ST_OMX_TIZONIA
29#include <tizkernel.h>
30#endif
31
32#include "util/u_memory.h"
33
34#include "vid_dec_h264_common.h"
35
36static void vid_dec_h264_BeginFrame(vid_dec_PrivateType *priv)
37{
38   //TODO: sane buffer handling
39
40   if (priv->frame_started)
41      return;
42
43   if (!priv->codec) {
44      struct pipe_video_codec templat = {};
45      templat.profile = priv->profile;
46      templat.entrypoint = PIPE_VIDEO_ENTRYPOINT_BITSTREAM;
47      templat.chroma_format = PIPE_VIDEO_CHROMA_FORMAT_420;
48      templat.max_references = priv->picture.h264.num_ref_frames;
49      templat.expect_chunked_decode = true;
50#if ENABLE_ST_OMX_BELLAGIO
51      omx_base_video_PortType *port;
52      port = (omx_base_video_PortType *)priv->ports[OMX_BASE_FILTER_INPUTPORT_INDEX];
53      templat.width = port->sPortParam.format.video.nFrameWidth;
54      templat.height = port->sPortParam.format.video.nFrameHeight;
55#else
56      templat.width = priv->out_port_def_.format.video.nFrameWidth;
57      templat.height = priv->out_port_def_.format.video.nFrameHeight;
58#endif
59      templat.level = priv->picture.h264.pps->sps->level_idc;
60
61      priv->codec = priv->pipe->create_video_codec(priv->pipe, &templat);
62   }
63
64   vid_dec_NeedTarget(priv);
65
66   if (priv->first_buf_in_frame)
67      priv->timestamp = priv->timestamps[0];
68   priv->first_buf_in_frame = false;
69
70   priv->picture.h264.num_ref_frames = priv->picture.h264.pps->sps->max_num_ref_frames;
71
72   priv->picture.h264.slice_count = 0;
73   priv->codec->begin_frame(priv->codec, priv->target, &priv->picture.base);
74   priv->frame_started = true;
75}
76
77struct pipe_video_buffer *vid_dec_h264_Flush(vid_dec_PrivateType *priv,
78                                             OMX_TICKS *timestamp)
79{
80   struct dpb_list *entry, *result = NULL;
81   struct pipe_video_buffer *buf;
82
83   /* search for the lowest poc and break on zeros */
84   LIST_FOR_EACH_ENTRY(entry, &priv->codec_data.h264.dpb_list, list) {
85
86      if (result && entry->poc == 0)
87         break;
88
89      if (!result || entry->poc < result->poc)
90         result = entry;
91   }
92
93   if (!result)
94      return NULL;
95
96   buf = result->buffer;
97   if (timestamp)
98      *timestamp = result->timestamp;
99
100   --priv->codec_data.h264.dpb_num;
101   list_del(&result->list);
102   FREE(result);
103
104   return buf;
105}
106
107void vid_dec_h264_EndFrame(vid_dec_PrivateType *priv)
108{
109   struct dpb_list *entry;
110   struct pipe_video_buffer *tmp;
111   bool top_field_first;
112   OMX_TICKS timestamp = 0;
113
114   if (!priv->frame_started)
115      return;
116
117   priv->codec->end_frame(priv->codec, priv->target, &priv->picture.base);
118   priv->frame_started = false;
119
120   // TODO: implement frame number handling
121   priv->picture.h264.frame_num_list[0] = priv->picture.h264.frame_num;
122   priv->picture.h264.field_order_cnt_list[0][0] = priv->picture.h264.frame_num;
123   priv->picture.h264.field_order_cnt_list[0][1] = priv->picture.h264.frame_num;
124
125   top_field_first = priv->picture.h264.field_order_cnt[0] <  priv->picture.h264.field_order_cnt[1];
126
127   if (priv->picture.h264.field_pic_flag && priv->picture.h264.bottom_field_flag != top_field_first)
128      return;
129
130   /* add the decoded picture to the dpb list */
131   entry = CALLOC_STRUCT(dpb_list);
132   if (!entry)
133      return;
134
135   priv->first_buf_in_frame = true;
136   entry->buffer = priv->target;
137   entry->timestamp = priv->timestamp;
138   entry->poc = MIN2(priv->picture.h264.field_order_cnt[0], priv->picture.h264.field_order_cnt[1]);
139   list_addtail(&entry->list, &priv->codec_data.h264.dpb_list);
140   ++priv->codec_data.h264.dpb_num;
141   priv->target = NULL;
142   priv->picture.h264.field_order_cnt[0] = priv->picture.h264.field_order_cnt[1] = INT_MAX;
143
144   if (priv->codec_data.h264.dpb_num <= DPB_MAX_SIZE)
145      return;
146
147   tmp = priv->in_buffers[0]->pInputPortPrivate;
148   priv->in_buffers[0]->pInputPortPrivate = vid_dec_h264_Flush(priv, &timestamp);
149   priv->in_buffers[0]->nTimeStamp = timestamp;
150   priv->target = tmp;
151   priv->frame_finished = priv->in_buffers[0]->pInputPortPrivate != NULL;
152}
153
154static void vui_parameters(struct vl_rbsp *rbsp)
155{
156   // TODO
157}
158
159static void scaling_list(struct vl_rbsp *rbsp, uint8_t *scalingList, unsigned sizeOfScalingList,
160                         const uint8_t *defaultList, const uint8_t *fallbackList)
161{
162   unsigned lastScale = 8, nextScale = 8;
163   const int *list;
164   unsigned i;
165
166   /* (pic|seq)_scaling_list_present_flag[i] */
167   if (!vl_rbsp_u(rbsp, 1)) {
168      if (fallbackList)
169         memcpy(scalingList, fallbackList, sizeOfScalingList);
170      return;
171   }
172
173   list = (sizeOfScalingList == 16) ? vl_zscan_normal_16 : vl_zscan_normal;
174   for (i = 0; i < sizeOfScalingList; ++i ) {
175
176      if (nextScale != 0) {
177         signed delta_scale = vl_rbsp_se(rbsp);
178         nextScale = (lastScale + delta_scale + 256) % 256;
179         if (i == 0 && nextScale == 0) {
180            memcpy(scalingList, defaultList, sizeOfScalingList);
181            return;
182         }
183      }
184      scalingList[list[i]] = nextScale == 0 ? lastScale : nextScale;
185      lastScale = scalingList[list[i]];
186   }
187}
188
189static struct pipe_h264_sps *seq_parameter_set_id(vid_dec_PrivateType *priv, struct vl_rbsp *rbsp)
190{
191   unsigned id = vl_rbsp_ue(rbsp);
192   if (id >= ARRAY_SIZE(priv->codec_data.h264.sps))
193      return NULL; /* invalid seq_parameter_set_id */
194
195   return &priv->codec_data.h264.sps[id];
196}
197
198static void seq_parameter_set(vid_dec_PrivateType *priv, struct vl_rbsp *rbsp)
199{
200   struct pipe_h264_sps *sps;
201   unsigned profile_idc, level_idc;
202   unsigned i;
203
204   /* Sequence parameter set */
205   profile_idc = vl_rbsp_u(rbsp, 8);
206
207   /* constraint_set0_flag */
208   vl_rbsp_u(rbsp, 1);
209
210   /* constraint_set1_flag */
211   vl_rbsp_u(rbsp, 1);
212
213   /* constraint_set2_flag */
214   vl_rbsp_u(rbsp, 1);
215
216   /* constraint_set3_flag */
217   vl_rbsp_u(rbsp, 1);
218
219   /* constraint_set4_flag */
220   vl_rbsp_u(rbsp, 1);
221
222   /* constraint_set5_flag */
223   vl_rbsp_u(rbsp, 1);
224
225   /* reserved_zero_2bits */
226   vl_rbsp_u(rbsp, 2);
227
228   /* level_idc */
229   level_idc = vl_rbsp_u(rbsp, 8);
230
231   sps = seq_parameter_set_id(priv, rbsp);
232   if (!sps)
233      return;
234
235   memset(sps, 0, sizeof(*sps));
236   memset(sps->ScalingList4x4, 16, sizeof(sps->ScalingList4x4));
237   memset(sps->ScalingList8x8, 16, sizeof(sps->ScalingList8x8));
238
239   sps->level_idc = level_idc;
240
241   if (profile_idc == 100 || profile_idc == 110 || profile_idc == 122 || profile_idc == 244 ||
242       profile_idc == 44 || profile_idc == 83 || profile_idc == 86 || profile_idc == 118 ||
243       profile_idc == 128 || profile_idc == 138) {
244
245      sps->chroma_format_idc = vl_rbsp_ue(rbsp);
246
247      if (sps->chroma_format_idc == 3)
248         sps->separate_colour_plane_flag = vl_rbsp_u(rbsp, 1);
249
250      sps->bit_depth_luma_minus8 = vl_rbsp_ue(rbsp);
251
252      sps->bit_depth_chroma_minus8 = vl_rbsp_ue(rbsp);
253
254      /* qpprime_y_zero_transform_bypass_flag */
255      vl_rbsp_u(rbsp, 1);
256
257      sps->seq_scaling_matrix_present_flag = vl_rbsp_u(rbsp, 1);
258      if (sps->seq_scaling_matrix_present_flag) {
259
260         scaling_list(rbsp, sps->ScalingList4x4[0], 16, Default_4x4_Intra, Default_4x4_Intra);
261         scaling_list(rbsp, sps->ScalingList4x4[1], 16, Default_4x4_Intra, sps->ScalingList4x4[0]);
262         scaling_list(rbsp, sps->ScalingList4x4[2], 16, Default_4x4_Intra, sps->ScalingList4x4[1]);
263         scaling_list(rbsp, sps->ScalingList4x4[3], 16, Default_4x4_Inter, Default_4x4_Inter);
264         scaling_list(rbsp, sps->ScalingList4x4[4], 16, Default_4x4_Inter, sps->ScalingList4x4[3]);
265         scaling_list(rbsp, sps->ScalingList4x4[5], 16, Default_4x4_Inter, sps->ScalingList4x4[4]);
266
267         scaling_list(rbsp, sps->ScalingList8x8[0], 64, Default_8x8_Intra, Default_8x8_Intra);
268         scaling_list(rbsp, sps->ScalingList8x8[1], 64, Default_8x8_Inter, Default_8x8_Inter);
269         if (sps->chroma_format_idc == 3) {
270            scaling_list(rbsp, sps->ScalingList8x8[2], 64, Default_8x8_Intra, sps->ScalingList8x8[0]);
271            scaling_list(rbsp, sps->ScalingList8x8[3], 64, Default_8x8_Inter, sps->ScalingList8x8[1]);
272            scaling_list(rbsp, sps->ScalingList8x8[4], 64, Default_8x8_Intra, sps->ScalingList8x8[2]);
273            scaling_list(rbsp, sps->ScalingList8x8[5], 64, Default_8x8_Inter, sps->ScalingList8x8[3]);
274         }
275      }
276   } else if (profile_idc == 183)
277      sps->chroma_format_idc = 0;
278   else
279      sps->chroma_format_idc = 1;
280
281   sps->log2_max_frame_num_minus4 = vl_rbsp_ue(rbsp);
282
283   sps->pic_order_cnt_type = vl_rbsp_ue(rbsp);
284
285   if (sps->pic_order_cnt_type == 0)
286      sps->log2_max_pic_order_cnt_lsb_minus4 = vl_rbsp_ue(rbsp);
287   else if (sps->pic_order_cnt_type == 1) {
288      sps->delta_pic_order_always_zero_flag = vl_rbsp_u(rbsp, 1);
289
290      sps->offset_for_non_ref_pic = vl_rbsp_se(rbsp);
291
292      sps->offset_for_top_to_bottom_field = vl_rbsp_se(rbsp);
293
294      sps->num_ref_frames_in_pic_order_cnt_cycle = vl_rbsp_ue(rbsp);
295
296      for (i = 0; i < sps->num_ref_frames_in_pic_order_cnt_cycle; ++i)
297         sps->offset_for_ref_frame[i] = vl_rbsp_se(rbsp);
298   }
299
300   sps->max_num_ref_frames = vl_rbsp_ue(rbsp);
301
302   /* gaps_in_frame_num_value_allowed_flag */
303   vl_rbsp_u(rbsp, 1);
304
305   /* pic_width_in_mbs_minus1 */
306   ASSERTED int pic_width_in_samplesl = (vl_rbsp_ue(rbsp) + 1) * 16;
307   assert(pic_width_in_samplesl);
308
309   /* pic_height_in_map_units_minus1 */
310   ASSERTED int pic_height_in_map_units = vl_rbsp_ue(rbsp) + 1;
311   assert(pic_height_in_map_units);
312
313   sps->frame_mbs_only_flag = vl_rbsp_u(rbsp, 1);
314   if (!sps->frame_mbs_only_flag)
315      sps->mb_adaptive_frame_field_flag = vl_rbsp_u(rbsp, 1);
316
317   sps->direct_8x8_inference_flag = vl_rbsp_u(rbsp, 1);
318
319#if ENABLE_ST_OMX_TIZONIA
320   priv->stream_info.width = pic_width_in_samplesl;
321
322   int frame_height_in_mbs = (2 - sps->frame_mbs_only_flag) * pic_height_in_map_units;
323   int pic_height_in_mbs = frame_height_in_mbs / ( 1 + priv->picture.h264.field_pic_flag );
324   int pic_height_in_samplesl = pic_height_in_mbs * 16;
325   priv->stream_info.height = pic_height_in_samplesl;
326
327
328   /* frame_cropping_flag */
329   if (vl_rbsp_u(rbsp, 1)) {
330      unsigned frame_crop_left_offset = vl_rbsp_ue(rbsp);
331      unsigned frame_crop_right_offset = vl_rbsp_ue(rbsp);
332      unsigned frame_crop_top_offset = vl_rbsp_ue(rbsp);
333      unsigned frame_crop_bottom_offset = vl_rbsp_ue(rbsp);
334
335      priv->stream_info.width -= (frame_crop_left_offset + frame_crop_right_offset) * 2;
336      priv->stream_info.height -= (frame_crop_top_offset + frame_crop_bottom_offset) * 2;
337   }
338#else
339   /* frame_cropping_flag */
340   if (vl_rbsp_u(rbsp, 1)) {
341      /* frame_crop_left_offset */
342      vl_rbsp_ue(rbsp);
343
344      /* frame_crop_right_offset */
345      vl_rbsp_ue(rbsp);
346
347      /* frame_crop_top_offset */
348      vl_rbsp_ue(rbsp);
349
350      /* frame_crop_bottom_offset */
351      vl_rbsp_ue(rbsp);
352   }
353#endif
354
355   /* vui_parameters_present_flag */
356   if (vl_rbsp_u(rbsp, 1))
357      vui_parameters(rbsp);
358}
359
360static struct pipe_h264_pps *pic_parameter_set_id(vid_dec_PrivateType *priv, struct vl_rbsp *rbsp)
361{
362   unsigned id = vl_rbsp_ue(rbsp);
363   if (id >= ARRAY_SIZE(priv->codec_data.h264.pps))
364      return NULL; /* invalid pic_parameter_set_id */
365
366   return &priv->codec_data.h264.pps[id];
367}
368
369static void picture_parameter_set(vid_dec_PrivateType *priv, struct vl_rbsp *rbsp)
370{
371   struct pipe_h264_sps *sps;
372   struct pipe_h264_pps *pps;
373   unsigned i;
374
375   pps = pic_parameter_set_id(priv, rbsp);
376   if (!pps)
377      return;
378
379   memset(pps, 0, sizeof(*pps));
380
381   sps = pps->sps = seq_parameter_set_id(priv, rbsp);
382   if (!sps)
383      return;
384
385   memcpy(pps->ScalingList4x4, sps->ScalingList4x4, sizeof(pps->ScalingList4x4));
386   memcpy(pps->ScalingList8x8, sps->ScalingList8x8, sizeof(pps->ScalingList8x8));
387
388   pps->entropy_coding_mode_flag = vl_rbsp_u(rbsp, 1);
389
390   pps->bottom_field_pic_order_in_frame_present_flag = vl_rbsp_u(rbsp, 1);
391
392   pps->num_slice_groups_minus1 = vl_rbsp_ue(rbsp);
393   if (pps->num_slice_groups_minus1 > 0) {
394      pps->slice_group_map_type = vl_rbsp_ue(rbsp);
395
396      if (pps->slice_group_map_type == 0) {
397
398         for (i = 0; i <= pps->num_slice_groups_minus1; ++i)
399            /* run_length_minus1[i] */
400            vl_rbsp_ue(rbsp);
401
402      } else if (pps->slice_group_map_type == 2) {
403
404         for (i = 0; i <= pps->num_slice_groups_minus1; ++i) {
405            /* top_left[i] */
406            vl_rbsp_ue(rbsp);
407
408            /* bottom_right[i] */
409            vl_rbsp_ue(rbsp);
410         }
411
412      } else if (pps->slice_group_map_type >= 3 && pps->slice_group_map_type <= 5) {
413
414         /* slice_group_change_direction_flag */
415         vl_rbsp_u(rbsp, 1);
416
417         pps->slice_group_change_rate_minus1 = vl_rbsp_ue(rbsp);
418
419      } else if (pps->slice_group_map_type == 6) {
420
421         unsigned pic_size_in_map_units_minus1;
422
423         pic_size_in_map_units_minus1 = vl_rbsp_ue(rbsp);
424
425         for (i = 0; i <= pic_size_in_map_units_minus1; ++i)
426            /* slice_group_id[i] */
427            vl_rbsp_u(rbsp, log2(pps->num_slice_groups_minus1 + 1));
428      }
429   }
430
431   pps->num_ref_idx_l0_default_active_minus1 = vl_rbsp_ue(rbsp);
432
433   pps->num_ref_idx_l1_default_active_minus1 = vl_rbsp_ue(rbsp);
434
435   pps->weighted_pred_flag = vl_rbsp_u(rbsp, 1);
436
437   pps->weighted_bipred_idc = vl_rbsp_u(rbsp, 2);
438
439   pps->pic_init_qp_minus26 = vl_rbsp_se(rbsp);
440
441   /* pic_init_qs_minus26 */
442   vl_rbsp_se(rbsp);
443
444   pps->chroma_qp_index_offset = vl_rbsp_se(rbsp);
445
446   pps->deblocking_filter_control_present_flag = vl_rbsp_u(rbsp, 1);
447
448   pps->constrained_intra_pred_flag = vl_rbsp_u(rbsp, 1);
449
450   pps->redundant_pic_cnt_present_flag = vl_rbsp_u(rbsp, 1);
451
452   if (vl_rbsp_more_data(rbsp)) {
453      pps->transform_8x8_mode_flag = vl_rbsp_u(rbsp, 1);
454
455      /* pic_scaling_matrix_present_flag */
456      if (vl_rbsp_u(rbsp, 1)) {
457
458         scaling_list(rbsp, pps->ScalingList4x4[0], 16, Default_4x4_Intra,
459                      sps->seq_scaling_matrix_present_flag ? NULL : Default_4x4_Intra);
460         scaling_list(rbsp, pps->ScalingList4x4[1], 16, Default_4x4_Intra, pps->ScalingList4x4[0]);
461         scaling_list(rbsp, pps->ScalingList4x4[2], 16, Default_4x4_Intra, pps->ScalingList4x4[1]);
462         scaling_list(rbsp, pps->ScalingList4x4[3], 16, Default_4x4_Inter,
463                      sps->seq_scaling_matrix_present_flag ? NULL : Default_4x4_Inter);
464         scaling_list(rbsp, pps->ScalingList4x4[4], 16, Default_4x4_Inter, pps->ScalingList4x4[3]);
465         scaling_list(rbsp, pps->ScalingList4x4[5], 16, Default_4x4_Inter, pps->ScalingList4x4[4]);
466
467         if (pps->transform_8x8_mode_flag) {
468            scaling_list(rbsp, pps->ScalingList8x8[0], 64, Default_8x8_Intra,
469                         sps->seq_scaling_matrix_present_flag ? NULL : Default_8x8_Intra);
470            scaling_list(rbsp, pps->ScalingList8x8[1], 64, Default_8x8_Inter,
471                         sps->seq_scaling_matrix_present_flag ? NULL :  Default_8x8_Inter);
472            if (sps->chroma_format_idc == 3) {
473               scaling_list(rbsp, pps->ScalingList8x8[2], 64, Default_8x8_Intra, pps->ScalingList8x8[0]);
474               scaling_list(rbsp, pps->ScalingList8x8[3], 64, Default_8x8_Inter, pps->ScalingList8x8[1]);
475               scaling_list(rbsp, pps->ScalingList8x8[4], 64, Default_8x8_Intra, pps->ScalingList8x8[2]);
476               scaling_list(rbsp, pps->ScalingList8x8[5], 64, Default_8x8_Inter, pps->ScalingList8x8[3]);
477            }
478         }
479      }
480
481      pps->second_chroma_qp_index_offset = vl_rbsp_se(rbsp);
482   }
483}
484
485static void ref_pic_list_mvc_modification(vid_dec_PrivateType *priv, struct vl_rbsp *rbsp)
486{
487   // TODO
488   assert(0);
489}
490
491static void ref_pic_list_modification(vid_dec_PrivateType *priv, struct vl_rbsp *rbsp,
492                                      enum pipe_h264_slice_type slice_type)
493{
494   unsigned modification_of_pic_nums_idc;
495
496   if (slice_type != 2 && slice_type != 4) {
497      /* ref_pic_list_modification_flag_l0 */
498      if (vl_rbsp_u(rbsp, 1)) {
499         do {
500            modification_of_pic_nums_idc = vl_rbsp_ue(rbsp);
501            if (modification_of_pic_nums_idc == 0 ||
502                modification_of_pic_nums_idc == 1)
503               /* abs_diff_pic_num_minus1 */
504               vl_rbsp_ue(rbsp);
505            else if (modification_of_pic_nums_idc == 2)
506               /* long_term_pic_num */
507               vl_rbsp_ue(rbsp);
508         } while (modification_of_pic_nums_idc != 3);
509      }
510   }
511
512   if (slice_type == 1) {
513      /* ref_pic_list_modification_flag_l1 */
514      if (vl_rbsp_u(rbsp, 1)) {
515         do {
516            modification_of_pic_nums_idc = vl_rbsp_ue(rbsp);
517            if (modification_of_pic_nums_idc == 0 ||
518                modification_of_pic_nums_idc == 1)
519               /* abs_diff_pic_num_minus1 */
520               vl_rbsp_ue(rbsp);
521            else if (modification_of_pic_nums_idc == 2)
522               /* long_term_pic_num */
523               vl_rbsp_ue(rbsp);
524         } while (modification_of_pic_nums_idc != 3);
525      }
526   }
527}
528
529static void pred_weight_table(vid_dec_PrivateType *priv, struct vl_rbsp *rbsp,
530                              struct pipe_h264_sps *sps, enum pipe_h264_slice_type slice_type)
531{
532   unsigned ChromaArrayType = sps->separate_colour_plane_flag ? 0 : sps->chroma_format_idc;
533   unsigned i, j;
534
535   /* luma_log2_weight_denom */
536   vl_rbsp_ue(rbsp);
537
538   if (ChromaArrayType != 0)
539      /* chroma_log2_weight_denom */
540      vl_rbsp_ue(rbsp);
541
542   for (i = 0; i <= priv->picture.h264.num_ref_idx_l0_active_minus1; ++i) {
543      /* luma_weight_l0_flag */
544      if (vl_rbsp_u(rbsp, 1)) {
545         /* luma_weight_l0[i] */
546         vl_rbsp_se(rbsp);
547         /* luma_offset_l0[i] */
548         vl_rbsp_se(rbsp);
549      }
550      if (ChromaArrayType != 0) {
551         /* chroma_weight_l0_flag */
552         if (vl_rbsp_u(rbsp, 1)) {
553            for (j = 0; j < 2; ++j) {
554               /* chroma_weight_l0[i][j] */
555               vl_rbsp_se(rbsp);
556               /* chroma_offset_l0[i][j] */
557               vl_rbsp_se(rbsp);
558            }
559         }
560      }
561   }
562
563   if (slice_type == 1) {
564      for (i = 0; i <= priv->picture.h264.num_ref_idx_l1_active_minus1; ++i) {
565         /* luma_weight_l1_flag */
566         if (vl_rbsp_u(rbsp, 1)) {
567            /* luma_weight_l1[i] */
568            vl_rbsp_se(rbsp);
569            /* luma_offset_l1[i] */
570            vl_rbsp_se(rbsp);
571         }
572         if (ChromaArrayType != 0) {
573            /* chroma_weight_l1_flag */
574            if (vl_rbsp_u(rbsp, 1)) {
575               for (j = 0; j < 2; ++j) {
576                  /* chroma_weight_l1[i][j] */
577                  vl_rbsp_se(rbsp);
578                  /* chroma_offset_l1[i][j] */
579                  vl_rbsp_se(rbsp);
580               }
581            }
582         }
583      }
584   }
585}
586
587static void dec_ref_pic_marking(vid_dec_PrivateType *priv, struct vl_rbsp *rbsp,
588                                bool IdrPicFlag)
589{
590   unsigned memory_management_control_operation;
591
592   if (IdrPicFlag) {
593      /* no_output_of_prior_pics_flag */
594      vl_rbsp_u(rbsp, 1);
595      /* long_term_reference_flag */
596      vl_rbsp_u(rbsp, 1);
597   } else {
598      /* adaptive_ref_pic_marking_mode_flag */
599      if (vl_rbsp_u(rbsp, 1)) {
600         do {
601            memory_management_control_operation = vl_rbsp_ue(rbsp);
602
603            if (memory_management_control_operation == 1 ||
604                memory_management_control_operation == 3)
605               /* difference_of_pic_nums_minus1 */
606               vl_rbsp_ue(rbsp);
607
608            if (memory_management_control_operation == 2)
609               /* long_term_pic_num */
610               vl_rbsp_ue(rbsp);
611
612            if (memory_management_control_operation == 3 ||
613                memory_management_control_operation == 6)
614               /* long_term_frame_idx */
615               vl_rbsp_ue(rbsp);
616
617            if (memory_management_control_operation == 4)
618               /* max_long_term_frame_idx_plus1 */
619               vl_rbsp_ue(rbsp);
620         } while (memory_management_control_operation != 0);
621      }
622   }
623}
624
625static void slice_header(vid_dec_PrivateType *priv, struct vl_rbsp *rbsp,
626                         unsigned nal_ref_idc, unsigned nal_unit_type)
627{
628   enum pipe_h264_slice_type slice_type;
629   struct pipe_h264_pps *pps;
630   struct pipe_h264_sps *sps;
631   unsigned frame_num, prevFrameNum;
632   bool IdrPicFlag = nal_unit_type == 5;
633
634   if (IdrPicFlag != priv->codec_data.h264.IdrPicFlag)
635      vid_dec_h264_EndFrame(priv);
636
637   priv->codec_data.h264.IdrPicFlag = IdrPicFlag;
638
639   /* first_mb_in_slice */
640   vl_rbsp_ue(rbsp);
641
642   slice_type = vl_rbsp_ue(rbsp) % 5;
643
644   /* get picture parameter set */
645   pps = pic_parameter_set_id(priv, rbsp);
646   if (!pps)
647      return;
648
649   /* get sequence parameter set */
650   sps = pps->sps;
651   if (!sps)
652      return;
653
654   if (pps != priv->picture.h264.pps)
655      vid_dec_h264_EndFrame(priv);
656
657   priv->picture.h264.pps = pps;
658
659   if (sps->separate_colour_plane_flag == 1 )
660      /* colour_plane_id */
661      vl_rbsp_u(rbsp, 2);
662
663   /* frame number handling */
664   frame_num = vl_rbsp_u(rbsp, sps->log2_max_frame_num_minus4 + 4);
665
666   if (frame_num != priv->picture.h264.frame_num)
667      vid_dec_h264_EndFrame(priv);
668
669   prevFrameNum = priv->picture.h264.frame_num;
670   priv->picture.h264.frame_num = frame_num;
671
672   priv->picture.h264.field_pic_flag = 0;
673   priv->picture.h264.bottom_field_flag = 0;
674
675   if (!sps->frame_mbs_only_flag) {
676      unsigned field_pic_flag = vl_rbsp_u(rbsp, 1);
677
678      if (!field_pic_flag && field_pic_flag != priv->picture.h264.field_pic_flag)
679         vid_dec_h264_EndFrame(priv);
680
681      priv->picture.h264.field_pic_flag = field_pic_flag;
682
683      if (priv->picture.h264.field_pic_flag) {
684         unsigned bottom_field_flag = vl_rbsp_u(rbsp, 1);
685
686         if (bottom_field_flag != priv->picture.h264.bottom_field_flag)
687            vid_dec_h264_EndFrame(priv);
688
689         priv->picture.h264.bottom_field_flag = bottom_field_flag;
690      }
691   }
692
693   if (IdrPicFlag) {
694      /* set idr_pic_id */
695      unsigned idr_pic_id = vl_rbsp_ue(rbsp);
696
697      if (idr_pic_id != priv->codec_data.h264.idr_pic_id)
698         vid_dec_h264_EndFrame(priv);
699
700      priv->codec_data.h264.idr_pic_id = idr_pic_id;
701   }
702
703   if (sps->pic_order_cnt_type == 0) {
704      /* pic_order_cnt_lsb */
705      unsigned log2_max_pic_order_cnt_lsb = sps->log2_max_pic_order_cnt_lsb_minus4 + 4;
706      unsigned max_pic_order_cnt_lsb = 1 << log2_max_pic_order_cnt_lsb;
707      int pic_order_cnt_lsb = vl_rbsp_u(rbsp, log2_max_pic_order_cnt_lsb);
708      int pic_order_cnt_msb;
709
710      if (pic_order_cnt_lsb != priv->codec_data.h264.pic_order_cnt_lsb)
711         vid_dec_h264_EndFrame(priv);
712
713      if (IdrPicFlag) {
714         priv->codec_data.h264.pic_order_cnt_msb = 0;
715         priv->codec_data.h264.pic_order_cnt_lsb = 0;
716      }
717
718      if ((pic_order_cnt_lsb < priv->codec_data.h264.pic_order_cnt_lsb) &&
719          (priv->codec_data.h264.pic_order_cnt_lsb - pic_order_cnt_lsb) >= (max_pic_order_cnt_lsb / 2))
720         pic_order_cnt_msb = priv->codec_data.h264.pic_order_cnt_msb + max_pic_order_cnt_lsb;
721
722      else if ((pic_order_cnt_lsb > priv->codec_data.h264.pic_order_cnt_lsb) &&
723          (pic_order_cnt_lsb - priv->codec_data.h264.pic_order_cnt_lsb) > (max_pic_order_cnt_lsb / 2))
724         pic_order_cnt_msb = priv->codec_data.h264.pic_order_cnt_msb - max_pic_order_cnt_lsb;
725
726      else
727         pic_order_cnt_msb = priv->codec_data.h264.pic_order_cnt_msb;
728
729      priv->codec_data.h264.pic_order_cnt_msb = pic_order_cnt_msb;
730      priv->codec_data.h264.pic_order_cnt_lsb = pic_order_cnt_lsb;
731
732      if (pps->bottom_field_pic_order_in_frame_present_flag && !priv->picture.h264.field_pic_flag) {
733         /* delta_pic_oreder_cnt_bottom */
734         unsigned delta_pic_order_cnt_bottom = vl_rbsp_se(rbsp);
735
736         if (delta_pic_order_cnt_bottom != priv->codec_data.h264.delta_pic_order_cnt_bottom)
737            vid_dec_h264_EndFrame(priv);
738
739         priv->codec_data.h264.delta_pic_order_cnt_bottom = delta_pic_order_cnt_bottom;
740      }
741
742      if (!priv->picture.h264.field_pic_flag) {
743         priv->picture.h264.field_order_cnt[0] = pic_order_cnt_msb + pic_order_cnt_lsb;
744         priv->picture.h264.field_order_cnt[1] = priv->picture.h264.field_order_cnt [0] +
745                                          priv->codec_data.h264.delta_pic_order_cnt_bottom;
746      } else if (!priv->picture.h264.bottom_field_flag)
747         priv->picture.h264.field_order_cnt[0] = pic_order_cnt_msb + pic_order_cnt_lsb;
748      else
749         priv->picture.h264.field_order_cnt[1] = pic_order_cnt_msb + pic_order_cnt_lsb;
750
751   } else if (sps->pic_order_cnt_type == 1) {
752      /* delta_pic_order_cnt[0] */
753      unsigned MaxFrameNum = 1 << (sps->log2_max_frame_num_minus4 + 4);
754      unsigned FrameNumOffset, absFrameNum, expectedPicOrderCnt;
755
756      if (!sps->delta_pic_order_always_zero_flag) {
757         unsigned delta_pic_order_cnt[2];
758
759         delta_pic_order_cnt[0] = vl_rbsp_se(rbsp);
760
761         if (delta_pic_order_cnt[0] != priv->codec_data.h264.delta_pic_order_cnt[0])
762            vid_dec_h264_EndFrame(priv);
763
764         priv->codec_data.h264.delta_pic_order_cnt[0] = delta_pic_order_cnt[0];
765
766         if (pps->bottom_field_pic_order_in_frame_present_flag && !priv->picture.h264.field_pic_flag) {
767            /* delta_pic_order_cnt[1] */
768            delta_pic_order_cnt[1] = vl_rbsp_se(rbsp);
769
770            if (delta_pic_order_cnt[1] != priv->codec_data.h264.delta_pic_order_cnt[1])
771               vid_dec_h264_EndFrame(priv);
772
773            priv->codec_data.h264.delta_pic_order_cnt[1] = delta_pic_order_cnt[1];
774         }
775      }
776
777      if (IdrPicFlag)
778         FrameNumOffset = 0;
779      else if (prevFrameNum > frame_num)
780         FrameNumOffset = priv->codec_data.h264.prevFrameNumOffset + MaxFrameNum;
781      else
782         FrameNumOffset = priv->codec_data.h264.prevFrameNumOffset;
783
784      priv->codec_data.h264.prevFrameNumOffset = FrameNumOffset;
785
786      if (sps->num_ref_frames_in_pic_order_cnt_cycle != 0)
787         absFrameNum = FrameNumOffset + frame_num;
788      else
789         absFrameNum = 0;
790
791      if (nal_ref_idc == 0 && absFrameNum > 0)
792         absFrameNum = absFrameNum - 1;
793
794      if (absFrameNum > 0) {
795         unsigned picOrderCntCycleCnt = (absFrameNum - 1) / sps->num_ref_frames_in_pic_order_cnt_cycle;
796         unsigned frameNumInPicOrderCntCycle = (absFrameNum - 1) % sps->num_ref_frames_in_pic_order_cnt_cycle;
797         signed ExpectedDeltaPerPicOrderCntCycle = 0;
798         unsigned i;
799
800         for (i = 0; i < sps->num_ref_frames_in_pic_order_cnt_cycle; ++i)
801            ExpectedDeltaPerPicOrderCntCycle += sps->offset_for_ref_frame[i];
802
803         expectedPicOrderCnt = picOrderCntCycleCnt * ExpectedDeltaPerPicOrderCntCycle;
804         for (i = 0; i <= frameNumInPicOrderCntCycle; ++i)
805            expectedPicOrderCnt += sps->offset_for_ref_frame[i];
806
807      } else
808         expectedPicOrderCnt = 0;
809
810      if (nal_ref_idc == 0)
811         expectedPicOrderCnt += sps->offset_for_non_ref_pic;
812
813      if (!priv->picture.h264.field_pic_flag) {
814         priv->picture.h264.field_order_cnt[0] = expectedPicOrderCnt + priv->codec_data.h264.delta_pic_order_cnt[0];
815         priv->picture.h264.field_order_cnt[1] = priv->picture.h264.field_order_cnt[0] +
816            sps->offset_for_top_to_bottom_field + priv->codec_data.h264.delta_pic_order_cnt[1];
817
818      } else if (!priv->picture.h264.bottom_field_flag)
819         priv->picture.h264.field_order_cnt[0] = expectedPicOrderCnt + priv->codec_data.h264.delta_pic_order_cnt[0];
820      else
821         priv->picture.h264.field_order_cnt[1] = expectedPicOrderCnt + sps->offset_for_top_to_bottom_field +
822            priv->codec_data.h264.delta_pic_order_cnt[0];
823
824   } else if (sps->pic_order_cnt_type == 2) {
825      unsigned MaxFrameNum = 1 << (sps->log2_max_frame_num_minus4 + 4);
826      unsigned FrameNumOffset, tempPicOrderCnt;
827
828      if (IdrPicFlag)
829         FrameNumOffset = 0;
830      else if (prevFrameNum > frame_num)
831         FrameNumOffset = priv->codec_data.h264.prevFrameNumOffset + MaxFrameNum;
832      else
833         FrameNumOffset = priv->codec_data.h264.prevFrameNumOffset;
834
835      priv->codec_data.h264.prevFrameNumOffset = FrameNumOffset;
836
837      if (IdrPicFlag)
838         tempPicOrderCnt = 0;
839      else if (nal_ref_idc == 0)
840         tempPicOrderCnt = 2 * (FrameNumOffset + frame_num) - 1;
841      else
842         tempPicOrderCnt = 2 * (FrameNumOffset + frame_num);
843
844      if (!priv->picture.h264.field_pic_flag) {
845         priv->picture.h264.field_order_cnt[0] = tempPicOrderCnt;
846         priv->picture.h264.field_order_cnt[1] = tempPicOrderCnt;
847
848      } else if (!priv->picture.h264.bottom_field_flag)
849         priv->picture.h264.field_order_cnt[0] = tempPicOrderCnt;
850      else
851         priv->picture.h264.field_order_cnt[1] = tempPicOrderCnt;
852   }
853
854   if (pps->redundant_pic_cnt_present_flag)
855      /* redundant_pic_cnt */
856      vl_rbsp_ue(rbsp);
857
858   if (slice_type == PIPE_H264_SLICE_TYPE_B)
859      /* direct_spatial_mv_pred_flag */
860      vl_rbsp_u(rbsp, 1);
861
862   priv->picture.h264.num_ref_idx_l0_active_minus1 = pps->num_ref_idx_l0_default_active_minus1;
863   priv->picture.h264.num_ref_idx_l1_active_minus1 = pps->num_ref_idx_l1_default_active_minus1;
864
865   if (slice_type == PIPE_H264_SLICE_TYPE_P ||
866       slice_type == PIPE_H264_SLICE_TYPE_SP ||
867       slice_type == PIPE_H264_SLICE_TYPE_B) {
868
869      /* num_ref_idx_active_override_flag */
870      if (vl_rbsp_u(rbsp, 1)) {
871         priv->picture.h264.num_ref_idx_l0_active_minus1 = vl_rbsp_ue(rbsp);
872
873         if (slice_type == PIPE_H264_SLICE_TYPE_B)
874            priv->picture.h264.num_ref_idx_l1_active_minus1 = vl_rbsp_ue(rbsp);
875      }
876   }
877
878   if (nal_unit_type == 20 || nal_unit_type == 21)
879      ref_pic_list_mvc_modification(priv, rbsp);
880   else
881      ref_pic_list_modification(priv, rbsp, slice_type);
882
883   if ((pps->weighted_pred_flag && (slice_type == PIPE_H264_SLICE_TYPE_P || slice_type == PIPE_H264_SLICE_TYPE_SP)) ||
884       (pps->weighted_bipred_idc == 1 && slice_type == PIPE_H264_SLICE_TYPE_B))
885      pred_weight_table(priv, rbsp, sps, slice_type);
886
887   if (nal_ref_idc != 0)
888      dec_ref_pic_marking(priv, rbsp, IdrPicFlag);
889
890   if (pps->entropy_coding_mode_flag && slice_type != PIPE_H264_SLICE_TYPE_I && slice_type != PIPE_H264_SLICE_TYPE_SI)
891      /* cabac_init_idc */
892      vl_rbsp_ue(rbsp);
893
894   /* slice_qp_delta */
895   vl_rbsp_se(rbsp);
896
897   if (slice_type == PIPE_H264_SLICE_TYPE_SP || slice_type == PIPE_H264_SLICE_TYPE_SI) {
898      if (slice_type == PIPE_H264_SLICE_TYPE_SP)
899         /* sp_for_switch_flag */
900         vl_rbsp_u(rbsp, 1);
901
902      /*slice_qs_delta */
903      vl_rbsp_se(rbsp);
904   }
905
906   if (pps->deblocking_filter_control_present_flag) {
907      unsigned disable_deblocking_filter_idc = vl_rbsp_ue(rbsp);
908
909      if (disable_deblocking_filter_idc != 1) {
910         /* slice_alpha_c0_offset_div2 */
911         vl_rbsp_se(rbsp);
912
913         /* slice_beta_offset_div2 */
914         vl_rbsp_se(rbsp);
915      }
916   }
917
918   if (pps->num_slice_groups_minus1 > 0 && pps->slice_group_map_type >= 3 && pps->slice_group_map_type <= 5)
919      /* slice_group_change_cycle */
920      vl_rbsp_u(rbsp, 2);
921}
922
923#if ENABLE_ST_OMX_TIZONIA
924static OMX_ERRORTYPE update_port_parameters(vid_dec_PrivateType* priv) {
925   OMX_VIDEO_PORTDEFINITIONTYPE * p_def = NULL;   /* Output port info */
926   h264d_stream_info_t * i_def = NULL; /* Info read from stream */
927   OMX_ERRORTYPE err = OMX_ErrorNone;
928
929   assert(priv);
930
931   p_def = &(priv->out_port_def_.format.video);
932   i_def = &(priv->stream_info);
933
934   /* Handle dynamic resolution change */
935   if ((p_def->nFrameWidth == i_def->width) && p_def->nFrameHeight == i_def->height)
936      return err;
937
938   p_def->nFrameWidth = i_def->width;
939   p_def->nFrameHeight = i_def->height;
940   p_def->nStride = i_def->width;
941   p_def->nSliceHeight = i_def->height;
942
943   err = tiz_krn_SetParameter_internal(tiz_get_krn(handleOf(priv)), handleOf(priv),
944                                       OMX_IndexParamPortDefinition, &(priv->out_port_def_));
945   if (err == OMX_ErrorNone) {
946      tiz_port_t * p_obj = tiz_krn_get_port(tiz_get_krn(handleOf(priv)), OMX_VID_DEC_AVC_INPUT_PORT_INDEX);
947
948      /* Set desired buffer size that will be used when allocating input buffers */
949      p_obj->portdef_.nBufferSize = p_def->nFrameWidth * p_def->nFrameHeight * 512 / (16*16);
950
951      /* Get a locally copy of port def. Useful for the early return above */
952      tiz_check_omx(tiz_api_GetParameter(tiz_get_krn(handleOf(priv)), handleOf(priv),
953                                         OMX_IndexParamPortDefinition, &(priv->out_port_def_)));
954
955      tiz_srv_issue_event((OMX_PTR) priv, OMX_EventPortSettingsChanged,
956                          OMX_VID_DEC_AVC_OUTPUT_PORT_INDEX,
957                          OMX_IndexParamPortDefinition,
958                          NULL);
959   }
960
961   return err;
962}
963#endif
964
965void vid_dec_h264_Decode(vid_dec_PrivateType *priv, struct vl_vlc *vlc, unsigned min_bits_left)
966{
967   unsigned nal_ref_idc, nal_unit_type;
968
969   if (!vl_vlc_search_byte(vlc, vl_vlc_bits_left(vlc) - min_bits_left, 0x00))
970      return;
971
972   if (vl_vlc_peekbits(vlc, 24) != 0x000001) {
973      vl_vlc_eatbits(vlc, 8);
974      return;
975   }
976
977   if (priv->slice) {
978      unsigned bytes = priv->bytes_left - (vl_vlc_bits_left(vlc) / 8);
979      ++priv->picture.h264.slice_count;
980      priv->codec->decode_bitstream(priv->codec, priv->target, &priv->picture.base,
981                                    1, &priv->slice, &bytes);
982      priv->slice = NULL;
983   }
984
985   vl_vlc_eatbits(vlc, 24);
986
987   /* forbidden_zero_bit */
988   vl_vlc_eatbits(vlc, 1);
989
990   nal_ref_idc = vl_vlc_get_uimsbf(vlc, 2);
991
992   if (nal_ref_idc != priv->codec_data.h264.nal_ref_idc &&
993       (nal_ref_idc * priv->codec_data.h264.nal_ref_idc) == 0)
994      vid_dec_h264_EndFrame(priv);
995
996   priv->codec_data.h264.nal_ref_idc = nal_ref_idc;
997
998   nal_unit_type = vl_vlc_get_uimsbf(vlc, 5);
999
1000   if (nal_unit_type != 1 && nal_unit_type != 5)
1001      vid_dec_h264_EndFrame(priv);
1002
1003   if (nal_unit_type == 7) {
1004      struct vl_rbsp rbsp;
1005      vl_rbsp_init(&rbsp, vlc, ~0);
1006      seq_parameter_set(priv, &rbsp);
1007#if ENABLE_ST_OMX_TIZONIA
1008      update_port_parameters(priv);
1009#endif
1010
1011   } else if (nal_unit_type == 8) {
1012      struct vl_rbsp rbsp;
1013      vl_rbsp_init(&rbsp, vlc, ~0);
1014      picture_parameter_set(priv, &rbsp);
1015
1016   } else if (nal_unit_type == 1 || nal_unit_type == 5) {
1017      /* Coded slice of a non-IDR or IDR picture */
1018      unsigned bits = vl_vlc_valid_bits(vlc);
1019      unsigned bytes = bits / 8 + 4;
1020      struct vl_rbsp rbsp;
1021      uint8_t buf[8];
1022      const void *ptr = buf;
1023      unsigned i;
1024
1025      buf[0] = 0x0;
1026      buf[1] = 0x0;
1027      buf[2] = 0x1;
1028      buf[3] = (nal_ref_idc << 5) | nal_unit_type;
1029      for (i = 4; i < bytes; ++i)
1030         buf[i] = vl_vlc_peekbits(vlc, bits) >> ((bytes - i - 1) * 8);
1031
1032      priv->bytes_left = (vl_vlc_bits_left(vlc) - bits) / 8;
1033      priv->slice = vlc->data;
1034
1035      vl_rbsp_init(&rbsp, vlc, 128);
1036      slice_header(priv, &rbsp, nal_ref_idc, nal_unit_type);
1037
1038      vid_dec_h264_BeginFrame(priv);
1039
1040      ++priv->picture.h264.slice_count;
1041      priv->codec->decode_bitstream(priv->codec, priv->target, &priv->picture.base,
1042                                    1, &ptr, &bytes);
1043   }
1044
1045   /* resync to byte boundary */
1046   vl_vlc_eatbits(vlc, vl_vlc_valid_bits(vlc) % 8);
1047}
1048
1049void vid_dec_FreeInputPortPrivate(OMX_BUFFERHEADERTYPE *buf)
1050{
1051   struct pipe_video_buffer *vbuf = buf->pInputPortPrivate;
1052   if (!vbuf)
1053      return;
1054
1055   vbuf->destroy(vbuf);
1056   buf->pInputPortPrivate = NULL;
1057}
1058
1059void vid_dec_FrameDecoded_common(vid_dec_PrivateType* priv, OMX_BUFFERHEADERTYPE* input,
1060                          OMX_BUFFERHEADERTYPE* output)
1061{
1062#if ENABLE_ST_OMX_BELLAGIO
1063   bool eos = !!(input->nFlags & OMX_BUFFERFLAG_EOS);
1064#else
1065   bool eos = priv->eos_;
1066#endif
1067   OMX_TICKS timestamp;
1068
1069   if (!input->pInputPortPrivate) {
1070#if ENABLE_ST_OMX_BELLAGIO
1071      input->pInputPortPrivate = priv->Flush(priv, &timestamp);
1072#else
1073      input->pInputPortPrivate = vid_dec_h264_Flush(priv, &timestamp);
1074#endif
1075      if (timestamp != OMX_VID_DEC_AVC_TIMESTAMP_INVALID)
1076         input->nTimeStamp = timestamp;
1077   }
1078
1079   if (input->pInputPortPrivate) {
1080      if (output->pInputPortPrivate && !priv->disable_tunnel) {
1081         struct pipe_video_buffer *tmp, *vbuf, *new_vbuf;
1082
1083         tmp = output->pOutputPortPrivate;
1084         vbuf = input->pInputPortPrivate;
1085         if (vbuf->interlaced) {
1086            /* re-allocate the progressive buffer */
1087            struct pipe_video_buffer templat = {};
1088            struct u_rect src_rect, dst_rect;
1089
1090#if ENABLE_ST_OMX_BELLAGIO
1091            omx_base_video_PortType *port;
1092            port = (omx_base_video_PortType *)
1093                    priv->ports[OMX_BASE_FILTER_INPUTPORT_INDEX];
1094#else
1095            tiz_port_t *port;
1096            port = tiz_krn_get_port(tiz_get_krn(handleOf (priv)), OMX_VID_DEC_AVC_INPUT_PORT_INDEX);
1097#endif
1098            memset(&templat, 0, sizeof(templat));
1099#if ENABLE_ST_OMX_BELLAGIO
1100            templat.width = port->sPortParam.format.video.nFrameWidth;
1101            templat.height = port->sPortParam.format.video.nFrameHeight;
1102#else
1103            templat.width = port->portdef_.format.video.nFrameWidth;
1104            templat.height = port->portdef_.format.video.nFrameHeight;
1105#endif
1106            templat.buffer_format = PIPE_FORMAT_NV12;
1107            templat.interlaced = false;
1108            new_vbuf = priv->pipe->create_video_buffer(priv->pipe, &templat);
1109
1110            /* convert the interlaced to the progressive */
1111            src_rect.x0 = dst_rect.x0 = 0;
1112            src_rect.x1 = dst_rect.x1 = templat.width;
1113            src_rect.y0 = dst_rect.y0 = 0;
1114            src_rect.y1 = dst_rect.y1 = templat.height;
1115
1116            vl_compositor_yuv_deint_full(&priv->cstate, &priv->compositor,
1117                                         input->pInputPortPrivate, new_vbuf,
1118                                         &src_rect, &dst_rect, VL_COMPOSITOR_WEAVE);
1119
1120            /* set the progrssive buffer for next round */
1121            vbuf->destroy(vbuf);
1122            input->pInputPortPrivate = new_vbuf;
1123         }
1124         output->pOutputPortPrivate = input->pInputPortPrivate;
1125         input->pInputPortPrivate = tmp;
1126      } else {
1127         vid_dec_FillOutput(priv, input->pInputPortPrivate, output);
1128      }
1129      output->nFilledLen = output->nAllocLen;
1130      output->nTimeStamp = input->nTimeStamp;
1131   }
1132
1133   if (eos && input->pInputPortPrivate)
1134      vid_dec_FreeInputPortPrivate(input);
1135   else
1136      input->nFilledLen = 0;
1137}
1138