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
47unsigned dec_frame_delta;
48
49static 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
56static 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
72static 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
82static 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
91static 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
110static 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
133static 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
145static 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
170static 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
182static 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
229static 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
252static 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 */
272static 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
290static 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
362static 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
379static void * h264d_prc_dtor(void *ap_obj)
380{
381   return super_dtor(typeOf(ap_obj, "h264dprc"), ap_obj);
382}
383
384static 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
429static 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
452static 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
468static OMX_ERRORTYPE h264d_prc_transfer_and_process(void *ap_obj, OMX_U32 a_pid)
469{
470   return OMX_ErrorNone;
471}
472
473static 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
479static 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
502static 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
515static 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
532static 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
552static 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
562void * 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
578void * 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