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 #include <tizplatform.h>
29 #include <tizkernel.h>
30 #include <tizutils.h>
31 
32 #include "entrypoint.h"
33 #include "h264d.h"
34 #include "h264dprc.h"
35 #include "vid_omx_common.h"
36 #include "vid_dec_common.h"
37 #include "vid_dec_h264_common.h"
38 
39 #include "vl/vl_video_buffer.h"
40 #include "vl/vl_compositor.h"
41 #include "util/u_hash_table.h"
42 #include "util/u_surface.h"
43 
44 #include "dri_screen.h"
45 #include "egl_dri2.h"
46 
47 unsigned dec_frame_delta;
48 
hash_table_clear_item_callback(void * key,void * value,void * data)49 static enum pipe_error hash_table_clear_item_callback(void *key, void *value, void *data)
50 {
51    struct pipe_video_buffer *video_buffer = (struct pipe_video_buffer *)value;
52    video_buffer->destroy(video_buffer);
53    return PIPE_OK;
54 }
55 
release_input_headers(vid_dec_PrivateType * priv)56 static void release_input_headers(vid_dec_PrivateType* priv) {
57    int i;
58    for (i = 0; i < priv->num_in_buffers; i++) {
59       assert(!priv->in_port_disabled_);
60       if (priv->in_buffers[i]->pInputPortPrivate) {
61          vid_dec_FreeInputPortPrivate(priv->in_buffers[i]);
62       }
63       (void) tiz_krn_release_buffer (tiz_get_krn (handleOf (priv)),
64                                      OMX_VID_DEC_AVC_INPUT_PORT_INDEX,
65                                      priv->in_buffers[i]);
66       priv->in_buffers[i] = NULL;
67    }
68    priv->p_inhdr_ = NULL;
69    priv->num_in_buffers = 0;
70 }
71 
release_output_header(vid_dec_PrivateType * priv)72 static void release_output_header(vid_dec_PrivateType* priv) {
73    if (priv->p_outhdr_) {
74       assert(!priv->out_port_disabled_);
75       (void) tiz_krn_release_buffer (tiz_get_krn (handleOf (priv)),
76                                      OMX_VID_DEC_AVC_OUTPUT_PORT_INDEX,
77                                      priv->p_outhdr_);
78       priv->p_outhdr_ = NULL;
79    }
80 }
81 
h264d_release_all_headers(vid_dec_PrivateType * priv)82 static OMX_ERRORTYPE h264d_release_all_headers(vid_dec_PrivateType* priv)
83 {
84    assert(priv);
85    release_input_headers(priv);
86    release_output_header(priv);
87 
88    return OMX_ErrorNone;
89 }
90 
h264d_buffer_emptied(vid_dec_PrivateType * priv,OMX_BUFFERHEADERTYPE * p_hdr)91 static void h264d_buffer_emptied(vid_dec_PrivateType* priv, OMX_BUFFERHEADERTYPE * p_hdr)
92 {
93    assert(priv);
94    assert(priv->in_buffers[0] == p_hdr);
95 
96    if (!priv->out_port_disabled_) {
97       assert (p_hdr->nFilledLen == 0);
98       p_hdr->nOffset = 0;
99 
100       if ((p_hdr->nFlags & OMX_BUFFERFLAG_EOS) != 0) {
101          priv->eos_ = true;
102       }
103 
104       (void) tiz_krn_release_buffer (tiz_get_krn (handleOf (priv)), 0, p_hdr);
105       priv->p_inhdr_ = NULL;
106       priv->in_buffers[0] = NULL;
107    }
108 }
109 
h264d_buffer_filled(vid_dec_PrivateType * priv,OMX_BUFFERHEADERTYPE * p_hdr)110 static void h264d_buffer_filled(vid_dec_PrivateType* priv, OMX_BUFFERHEADERTYPE * p_hdr)
111 {
112    assert(priv);
113    assert(p_hdr);
114    assert(priv->p_outhdr_ == p_hdr);
115 
116    if (!priv->in_port_disabled_) {
117       p_hdr->nOffset = 0;
118 
119       if (priv->eos_) {
120          /* EOS has been received and all the input data has been consumed
121           * already, so its time to propagate the EOS flag */
122          priv->p_outhdr_->nFlags |= OMX_BUFFERFLAG_EOS;
123          priv->eos_ = false;
124       }
125 
126       (void) tiz_krn_release_buffer(tiz_get_krn (handleOf (priv)),
127                                     OMX_VID_DEC_AVC_OUTPUT_PORT_INDEX,
128                                     p_hdr);
129       priv->p_outhdr_ = NULL;
130    }
131 }
132 
h264d_shift_buffers_left(vid_dec_PrivateType * priv)133 static bool h264d_shift_buffers_left(vid_dec_PrivateType* priv) {
134    if (--priv->num_in_buffers) {
135       priv->in_buffers[0] = priv->in_buffers[1];
136       priv->sizes[0] = priv->sizes[1] - dec_frame_delta;
137       priv->inputs[0] = priv->inputs[1] + dec_frame_delta;
138       priv->timestamps[0] = priv->timestamps[1];
139 
140       return true;
141    }
142    return false;
143 }
144 
get_input_buffer(vid_dec_PrivateType * priv)145 static OMX_BUFFERHEADERTYPE * get_input_buffer(vid_dec_PrivateType* priv) {
146    assert(priv);
147 
148    if (priv->in_port_disabled_) {
149       return NULL;
150    }
151 
152    if (priv->num_in_buffers > 1) {
153       /* The input buffer wasn't cleared last time. */
154       h264d_buffer_emptied(priv, priv->in_buffers[0]);
155       if (priv->in_buffers[0]) {
156          /* Failed to release buffer */
157          return NULL;
158       }
159       h264d_shift_buffers_left(priv);
160    }
161 
162    /* Decode_frame expects new buffers each time */
163    assert(priv->p_inhdr_ || priv->first_buf_in_frame);
164    tiz_krn_claim_buffer(tiz_get_krn (handleOf (priv)),
165                         OMX_VID_DEC_AVC_INPUT_PORT_INDEX, 0,
166                         &priv->p_inhdr_);
167    return priv->p_inhdr_;
168 }
169 
st_omx_pipe_texture_from_eglimage(EGLDisplay egldisplay,EGLImage eglimage)170 static struct pipe_resource * st_omx_pipe_texture_from_eglimage(EGLDisplay egldisplay,
171                                                                 EGLImage eglimage)
172 {
173    _EGLDisplay *disp = egldisplay;
174    struct dri2_egl_display *dri2_egl_dpy = disp->DriverData;
175    __DRIscreen *_dri_screen = dri2_egl_dpy->dri_screen;
176    struct dri_screen *st_dri_screen = dri_screen(_dri_screen);
177    __DRIimage *_dri_image = st_dri_screen->lookup_egl_image(st_dri_screen, eglimage);
178 
179    return _dri_image->texture;
180 }
181 
get_eglimage(vid_dec_PrivateType * priv)182 static void get_eglimage(vid_dec_PrivateType* priv) {
183    OMX_PTR p_eglimage = NULL;
184    OMX_NATIVE_WINDOWTYPE * p_egldisplay = NULL;
185    const tiz_port_t * p_port = NULL;
186    struct pipe_video_buffer templat = {};
187    struct pipe_video_buffer *video_buffer = NULL;
188    struct pipe_resource * p_res = NULL;
189    struct pipe_resource *resources[VL_NUM_COMPONENTS];
190 
191    if (OMX_ErrorNone ==
192       tiz_krn_claim_eglimage(tiz_get_krn (handleOf (priv)),
193                              OMX_VID_DEC_AVC_OUTPUT_PORT_INDEX,
194                              priv->p_outhdr_, &p_eglimage)) {
195       priv->use_eglimage = true;
196       p_port = tiz_krn_get_port(tiz_get_krn (handleOf (priv)),
197                                 OMX_VID_DEC_AVC_OUTPUT_PORT_INDEX);
198       p_egldisplay = p_port->portdef_.format.video.pNativeWindow;
199 
200       if (!util_hash_table_get(priv->video_buffer_map, priv->p_outhdr_)) {
201         p_res = st_omx_pipe_texture_from_eglimage(p_egldisplay, p_eglimage);
202 
203         assert(p_res);
204 
205         memset(&templat, 0, sizeof(templat));
206         templat.buffer_format = p_res->format;
207         templat.width = p_res->width0;
208         templat.height = p_res->height0;
209         templat.interlaced = 0;
210 
211         memset(resources, 0, sizeof(resources));
212         pipe_resource_reference(&resources[0], p_res);
213 
214         video_buffer = vl_video_buffer_create_ex2(priv->pipe, &templat, resources);
215 
216         assert(video_buffer);
217         assert(video_buffer->buffer_format == p_res->format);
218 
219         _mesa_hash_table_insert(priv->video_buffer_map, priv->p_outhdr_, video_buffer);
220       }
221    } else {
222       (void) tiz_krn_release_buffer(tiz_get_krn (handleOf (priv)),
223                                     OMX_VID_DEC_AVC_OUTPUT_PORT_INDEX,
224                                     priv->p_outhdr_);
225       priv->p_outhdr_ = NULL;
226    }
227 }
228 
get_output_buffer(vid_dec_PrivateType * priv)229 static OMX_BUFFERHEADERTYPE * get_output_buffer(vid_dec_PrivateType* priv) {
230    assert (priv);
231 
232    if (priv->out_port_disabled_) {
233       return NULL;
234    }
235 
236    if (!priv->p_outhdr_) {
237       if (OMX_ErrorNone
238           == tiz_krn_claim_buffer(tiz_get_krn (handleOf (priv)),
239                                   OMX_VID_DEC_AVC_OUTPUT_PORT_INDEX, 0,
240                                   &priv->p_outhdr_)) {
241          if (priv->p_outhdr_) {
242             /* Check pBuffer nullity to know if an eglimage has been registered. */
243             if (!priv->p_outhdr_->pBuffer) {
244                get_eglimage(priv);
245             }
246          }
247       }
248    }
249    return priv->p_outhdr_;
250 }
251 
reset_stream_parameters(vid_dec_PrivateType * apriv)252 static void reset_stream_parameters(vid_dec_PrivateType* apriv)
253 {
254    assert(apriv);
255    TIZ_INIT_OMX_PORT_STRUCT(apriv->out_port_def_,
256                             OMX_VID_DEC_AVC_OUTPUT_PORT_INDEX);
257 
258    tiz_api_GetParameter (tiz_get_krn (handleOf (apriv)), handleOf (apriv),
259                           OMX_IndexParamPortDefinition, &(apriv->out_port_def_));
260 
261    apriv->p_inhdr_ = 0;
262    apriv->num_in_buffers = 0;
263    apriv->first_buf_in_frame = true;
264    apriv->eos_ = false;
265    apriv->frame_finished = false;
266    apriv->frame_started = false;
267    apriv->picture.h264.field_order_cnt[0] = apriv->picture.h264.field_order_cnt[1] = INT_MAX;
268    apriv->slice = NULL;
269 }
270 
271 /* Replacement for bellagio's omx_base_filter_BufferMgmtFunction */
h264d_manage_buffers(vid_dec_PrivateType * priv)272 static void h264d_manage_buffers(vid_dec_PrivateType* priv) {
273    bool next_is_eos = priv->num_in_buffers == 2 ? !!(priv->in_buffers[1]->nFlags & OMX_BUFFERFLAG_EOS) : false;
274    vid_dec_FrameDecoded_common(priv, priv->in_buffers[0], priv->p_outhdr_);
275 
276    priv->p_outhdr_->nTimeStamp = priv->in_buffers[0]->nTimeStamp;
277 
278    /* Realase output buffer if filled or eos
279       Keep if two input buffers are being decoded */
280    if ((!next_is_eos) && ((priv->p_outhdr_->nFilledLen > 0) || priv->use_eglimage  || priv->eos_)) {
281       h264d_buffer_filled(priv, priv->p_outhdr_);
282    }
283 
284    /* Release input buffer if possible */
285    if (priv->in_buffers[0]->nFilledLen == 0) {
286       h264d_buffer_emptied(priv, priv->in_buffers[0]);
287    }
288 }
289 
decode_frame(vid_dec_PrivateType * priv,OMX_BUFFERHEADERTYPE * in_buf)290 static OMX_ERRORTYPE decode_frame(vid_dec_PrivateType*priv,
291                                   OMX_BUFFERHEADERTYPE *in_buf)
292 {
293    unsigned i = priv->num_in_buffers++;
294    priv->in_buffers[i] = in_buf;
295    priv->sizes[i] = in_buf->nFilledLen;
296    priv->inputs[i] = in_buf->pBuffer;
297    priv->timestamps[i] = in_buf->nTimeStamp;
298 
299    while (priv->num_in_buffers > (!!(in_buf->nFlags & OMX_BUFFERFLAG_EOS) ? 0 : 1)) {
300       priv->eos_ = !!(priv->in_buffers[0]->nFlags & OMX_BUFFERFLAG_EOS);
301       unsigned min_bits_left = priv->eos_ ? 32 : MAX2(in_buf->nFilledLen * 8, 32);
302       struct vl_vlc vlc;
303 
304       vl_vlc_init(&vlc, priv->num_in_buffers, priv->inputs, priv->sizes);
305 
306       if (priv->slice)
307          priv->bytes_left = vl_vlc_bits_left(&vlc) / 8;
308 
309       while (vl_vlc_bits_left (&vlc) > min_bits_left) {
310          vid_dec_h264_Decode(priv, &vlc, min_bits_left);
311          vl_vlc_fillbits(&vlc);
312       }
313 
314       if (priv->slice) {
315          unsigned bytes = priv->bytes_left - vl_vlc_bits_left(&vlc) / 8;
316 
317          priv->codec->decode_bitstream(priv->codec, priv->target, &priv->picture.base,
318                                  1, &priv->slice, &bytes);
319 
320          if (priv->num_in_buffers)
321             priv->slice = priv->inputs[1];
322          else
323             priv->slice = NULL;
324       }
325 
326       if (priv->eos_ && priv->frame_started)
327          vid_dec_h264_EndFrame(priv);
328 
329       if (priv->frame_finished) {
330          priv->frame_finished = false;
331          h264d_manage_buffers(priv);
332       } else if (priv->eos_) {
333          vid_dec_FreeInputPortPrivate(priv->in_buffers[0]);
334          h264d_manage_buffers(priv);
335       } else {
336          priv->in_buffers[0]->nFilledLen = 0;
337          h264d_buffer_emptied(priv, priv->in_buffers[0]);
338       }
339 
340       if (priv->out_port_disabled_) {
341          /* In case out port is disabled, h264d_buffer_emptied will fail to release input port.
342           * We need to wait before shifting the buffers in that case and check in
343           * get_input_buffer when out port is enabled to release and shift the buffers.
344           * Infinite looping occurs if buffer is not released */
345          if (priv->num_in_buffers == 2) {
346             /* Set the delta value for use in get_input_buffer before exiting */
347             dec_frame_delta = MIN2((min_bits_left - vl_vlc_bits_left(&vlc)) / 8, priv->sizes[1]);
348          }
349          break;
350       }
351 
352       h264d_shift_buffers_left(priv);
353    }
354 
355    return OMX_ErrorNone;
356 }
357 
358 /*
359  * h264dprc
360  */
361 
h264d_prc_ctor(void * ap_obj,va_list * app)362 static void * h264d_prc_ctor(void *ap_obj, va_list * app)
363 {
364    vid_dec_PrivateType*priv = super_ctor(typeOf (ap_obj, "h264dprc"), ap_obj, app);
365    assert(priv);
366    priv->p_inhdr_ = 0;
367    priv->p_outhdr_ = 0;
368    priv->first_buf_in_frame = true;
369    priv->eos_ = false;
370    priv->in_port_disabled_   = false;
371    priv->out_port_disabled_   = false;
372    priv->picture.base.profile = PIPE_VIDEO_PROFILE_MPEG4_AVC_HIGH;
373    priv->profile = PIPE_VIDEO_PROFILE_MPEG4_AVC_HIGH;
374    reset_stream_parameters(priv);
375 
376    return priv;
377 }
378 
h264d_prc_dtor(void * ap_obj)379 static void * h264d_prc_dtor(void *ap_obj)
380 {
381    return super_dtor(typeOf(ap_obj, "h264dprc"), ap_obj);
382 }
383 
h264d_prc_allocate_resources(void * ap_obj,OMX_U32 a_pid)384 static OMX_ERRORTYPE h264d_prc_allocate_resources(void *ap_obj, OMX_U32 a_pid)
385 {
386    vid_dec_PrivateType*priv = ap_obj;
387    struct pipe_screen *screen;
388    vl_csc_matrix csc;
389 
390    assert (priv);
391 
392    priv->screen = omx_get_screen();
393    if (!priv->screen)
394       return OMX_ErrorInsufficientResources;
395 
396    screen = priv->screen->pscreen;
397    priv->pipe = pipe_create_multimedia_context(screen);
398    if (!priv->pipe)
399       return OMX_ErrorInsufficientResources;
400 
401    if (!vl_compositor_init(&priv->compositor, priv->pipe)) {
402       priv->pipe->destroy(priv->pipe);
403       priv->pipe = NULL;
404       return OMX_ErrorInsufficientResources;
405    }
406 
407    if (!vl_compositor_init_state(&priv->cstate, priv->pipe)) {
408       vl_compositor_cleanup(&priv->compositor);
409       priv->pipe->destroy(priv->pipe);
410       priv->pipe = NULL;
411       return OMX_ErrorInsufficientResources;
412    }
413 
414    vl_csc_get_matrix(VL_CSC_COLOR_STANDARD_BT_601, NULL, true, &csc);
415    if (!vl_compositor_set_csc_matrix(&priv->cstate, (const vl_csc_matrix *)&csc, 1.0f, 0.0f)) {
416       vl_compositor_cleanup(&priv->compositor);
417       priv->pipe->destroy(priv->pipe);
418       priv->pipe = NULL;
419       return OMX_ErrorInsufficientResources;
420    }
421 
422    list_inithead(&priv->codec_data.h264.dpb_list);
423 
424    priv->video_buffer_map = util_hash_table_create_ptr_keys();
425 
426    return OMX_ErrorNone;
427 }
428 
h264d_prc_deallocate_resources(void * ap_obj)429 static OMX_ERRORTYPE h264d_prc_deallocate_resources(void *ap_obj)
430 {
431    vid_dec_PrivateType*priv = ap_obj;
432    assert(priv);
433 
434    /* Clear hash table */
435    util_hash_table_foreach(priv->video_buffer_map,
436                             &hash_table_clear_item_callback,
437                             NULL);
438    _mesa_hash_table_destroy(priv->video_buffer_map, NULL);
439 
440    if (priv->pipe) {
441       vl_compositor_cleanup_state(&priv->cstate);
442       vl_compositor_cleanup(&priv->compositor);
443       priv->pipe->destroy(priv->pipe);
444    }
445 
446    if (priv->screen)
447       omx_put_screen();
448 
449    return OMX_ErrorNone;
450 }
451 
h264d_prc_prepare_to_transfer(void * ap_obj,OMX_U32 a_pid)452 static OMX_ERRORTYPE h264d_prc_prepare_to_transfer(void *ap_obj, OMX_U32 a_pid)
453 {
454    vid_dec_PrivateType*priv = ap_obj;
455    assert(priv);
456 
457    TIZ_INIT_OMX_PORT_STRUCT(priv->out_port_def_,
458                             OMX_VID_DEC_AVC_OUTPUT_PORT_INDEX);
459    tiz_check_omx(
460       tiz_api_GetParameter(tiz_get_krn(handleOf(priv)), handleOf(priv),
461                            OMX_IndexParamPortDefinition, &(priv->out_port_def_)));
462 
463    priv->first_buf_in_frame = true;
464    priv->eos_ = false;
465    return OMX_ErrorNone;
466 }
467 
h264d_prc_transfer_and_process(void * ap_obj,OMX_U32 a_pid)468 static OMX_ERRORTYPE h264d_prc_transfer_and_process(void *ap_obj, OMX_U32 a_pid)
469 {
470    return OMX_ErrorNone;
471 }
472 
h264d_prc_stop_and_return(void * ap_obj)473 static OMX_ERRORTYPE h264d_prc_stop_and_return(void *ap_obj)
474 {
475    vid_dec_PrivateType*priv = (vid_dec_PrivateType*) ap_obj;
476    return h264d_release_all_headers (priv);
477 }
478 
h264d_prc_buffers_ready(const void * ap_obj)479 static OMX_ERRORTYPE h264d_prc_buffers_ready(const void *ap_obj)
480 {
481    vid_dec_PrivateType*priv = (vid_dec_PrivateType*) ap_obj;
482    OMX_BUFFERHEADERTYPE *in_buf = NULL;
483    OMX_BUFFERHEADERTYPE *out_buf = NULL;
484 
485    assert(priv);
486 
487    /* Set parameters if start of stream */
488    if (!priv->eos_ && priv->first_buf_in_frame && (in_buf = get_input_buffer(priv))) {
489       decode_frame(priv, in_buf);
490    }
491 
492    /* Don't get input buffer if output buffer not found */
493    while (!priv->eos_ && (out_buf = get_output_buffer(priv)) && (in_buf = get_input_buffer(priv))) {
494       if (!priv->out_port_disabled_) {
495          decode_frame(priv, in_buf);
496       }
497    }
498 
499    return OMX_ErrorNone;
500 }
501 
h264d_prc_port_flush(const void * ap_obj,OMX_U32 a_pid)502 static OMX_ERRORTYPE h264d_prc_port_flush(const void *ap_obj, OMX_U32 a_pid)
503 {
504    vid_dec_PrivateType*priv = (vid_dec_PrivateType*) ap_obj;
505    if (OMX_ALL == a_pid || OMX_VID_DEC_AVC_INPUT_PORT_INDEX == a_pid) {
506       release_input_headers(priv);
507       reset_stream_parameters(priv);
508    }
509    if (OMX_ALL == a_pid || OMX_VID_DEC_AVC_OUTPUT_PORT_INDEX == a_pid) {
510       release_output_header(priv);
511    }
512    return OMX_ErrorNone;
513 }
514 
h264d_prc_port_disable(const void * ap_obj,OMX_U32 a_pid)515 static OMX_ERRORTYPE h264d_prc_port_disable(const void *ap_obj, OMX_U32 a_pid)
516 {
517    vid_dec_PrivateType*priv = (vid_dec_PrivateType*) ap_obj;
518    assert(priv);
519    if (OMX_ALL == a_pid || OMX_VID_DEC_AVC_INPUT_PORT_INDEX == a_pid) {
520       /* Release all buffers */
521       h264d_release_all_headers(priv);
522       reset_stream_parameters(priv);
523       priv->in_port_disabled_ = true;
524    }
525    if (OMX_ALL == a_pid || OMX_VID_DEC_AVC_OUTPUT_PORT_INDEX == a_pid) {
526       release_output_header(priv);
527       priv->out_port_disabled_ = true;
528    }
529    return OMX_ErrorNone;
530 }
531 
h264d_prc_port_enable(const void * ap_obj,OMX_U32 a_pid)532 static OMX_ERRORTYPE h264d_prc_port_enable(const void *ap_obj, OMX_U32 a_pid)
533 {
534    vid_dec_PrivateType* priv = (vid_dec_PrivateType*) ap_obj;
535    assert(priv);
536    if (OMX_ALL == a_pid || OMX_VID_DEC_AVC_INPUT_PORT_INDEX == a_pid) {
537       if (priv->in_port_disabled_) {
538          reset_stream_parameters(priv);
539          priv->in_port_disabled_ = false;
540       }
541    }
542    if (OMX_ALL == a_pid || OMX_VID_DEC_AVC_OUTPUT_PORT_INDEX == a_pid) {
543       priv->out_port_disabled_ = false;
544    }
545    return OMX_ErrorNone;
546 }
547 
548 /*
549  * h264d_prc_class
550  */
551 
h264d_prc_class_ctor(void * ap_obj,va_list * app)552 static void * h264d_prc_class_ctor(void *ap_obj, va_list * app)
553 {
554    /* NOTE: Class methods might be added in the future. None for now. */
555    return super_ctor(typeOf(ap_obj, "h264dprc_class"), ap_obj, app);
556 }
557 
558 /*
559  * initialization
560  */
561 
h264d_prc_class_init(void * ap_tos,void * ap_hdl)562 void * h264d_prc_class_init(void * ap_tos, void * ap_hdl)
563 {
564    void * tizprc = tiz_get_type(ap_hdl, "tizprc");
565    void * h264dprc_class = factory_new
566       /* TIZ_CLASS_COMMENT: class type, class name, parent, size */
567       (classOf(tizprc), "h264dprc_class", classOf(tizprc),
568        sizeof(h264d_prc_class_t),
569        /* TIZ_CLASS_COMMENT: */
570        ap_tos, ap_hdl,
571        /* TIZ_CLASS_COMMENT: class constructor */
572        ctor, h264d_prc_class_ctor,
573        /* TIZ_CLASS_COMMENT: stop value*/
574        0);
575    return h264dprc_class;
576 }
577 
h264d_prc_init(void * ap_tos,void * ap_hdl)578 void * h264d_prc_init(void * ap_tos, void * ap_hdl)
579 {
580    void * tizprc = tiz_get_type(ap_hdl, "tizprc");
581    void * h264dprc_class = tiz_get_type(ap_hdl, "h264dprc_class");
582    TIZ_LOG_CLASS (h264dprc_class);
583    void * h264dprc = factory_new
584      /* TIZ_CLASS_COMMENT: class type, class name, parent, size */
585      (h264dprc_class, "h264dprc", tizprc, sizeof(vid_dec_PrivateType),
586       /* TIZ_CLASS_COMMENT: */
587       ap_tos, ap_hdl,
588       /* TIZ_CLASS_COMMENT: class constructor */
589       ctor, h264d_prc_ctor,
590       /* TIZ_CLASS_COMMENT: class destructor */
591       dtor, h264d_prc_dtor,
592       /* TIZ_CLASS_COMMENT: */
593       tiz_srv_allocate_resources, h264d_prc_allocate_resources,
594       /* TIZ_CLASS_COMMENT: */
595       tiz_srv_deallocate_resources, h264d_prc_deallocate_resources,
596       /* TIZ_CLASS_COMMENT: */
597       tiz_srv_prepare_to_transfer, h264d_prc_prepare_to_transfer,
598       /* TIZ_CLASS_COMMENT: */
599       tiz_srv_transfer_and_process, h264d_prc_transfer_and_process,
600       /* TIZ_CLASS_COMMENT: */
601       tiz_srv_stop_and_return, h264d_prc_stop_and_return,
602       /* TIZ_CLASS_COMMENT: */
603       tiz_prc_buffers_ready, h264d_prc_buffers_ready,
604       /* TIZ_CLASS_COMMENT: */
605       tiz_prc_port_flush, h264d_prc_port_flush,
606       /* TIZ_CLASS_COMMENT: */
607       tiz_prc_port_disable, h264d_prc_port_disable,
608       /* TIZ_CLASS_COMMENT: */
609       tiz_prc_port_enable, h264d_prc_port_enable,
610       /* TIZ_CLASS_COMMENT: stop value*/
611       0);
612 
613    return h264dprc;
614 }
615