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