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 "pipe/p_screen.h" 33#include "pipe/p_video_codec.h" 34#include "util/u_memory.h" 35 36#include "vl/vl_codec.h" 37 38#include "entrypoint.h" 39#include "h264e.h" 40#include "h264eprc.h" 41#include "vid_omx_common.h" 42#include "vid_enc_common.h" 43 44static OMX_ERRORTYPE init_port_structs(vid_enc_PrivateType * priv) { 45 const void * p_krn = NULL; 46 47 assert(priv); 48 49 /* Initialisation */ 50 TIZ_INIT_OMX_PORT_STRUCT(priv->in_port_def_, 51 OMX_VID_ENC_AVC_INPUT_PORT_INDEX); 52 TIZ_INIT_OMX_PORT_STRUCT(priv->out_port_def_, 53 OMX_VID_ENC_AVC_OUTPUT_PORT_INDEX); 54 TIZ_INIT_OMX_PORT_STRUCT(priv->bitrate, 55 OMX_VID_ENC_AVC_OUTPUT_PORT_INDEX); 56 TIZ_INIT_OMX_PORT_STRUCT(priv->quant, 57 OMX_VID_ENC_AVC_OUTPUT_PORT_INDEX); 58 TIZ_INIT_OMX_PORT_STRUCT(priv->profile_level, 59 OMX_VID_ENC_AVC_OUTPUT_PORT_INDEX); 60 61 /* Get values */ 62 p_krn = tiz_get_krn(handleOf(priv)); 63 64 tiz_check_omx( 65 tiz_api_GetParameter(p_krn, handleOf(priv), 66 OMX_IndexParamPortDefinition, &(priv->in_port_def_))); 67 tiz_check_omx( 68 tiz_api_GetParameter(p_krn, handleOf(priv), 69 OMX_IndexParamPortDefinition, &(priv->out_port_def_))); 70 tiz_check_omx( 71 tiz_api_GetParameter(p_krn, handleOf(priv), 72 OMX_IndexParamVideoBitrate, &(priv->bitrate))); 73 tiz_check_omx( 74 tiz_api_GetParameter(p_krn, handleOf(priv), 75 OMX_IndexParamVideoQuantization, &(priv->quant))); 76 tiz_check_omx( 77 tiz_api_GetParameter(p_krn, handleOf(priv), 78 OMX_IndexParamVideoProfileLevelCurrent, &(priv->profile_level))); 79 80 return OMX_ErrorNone; 81} 82 83static OMX_BUFFERHEADERTYPE * get_input_buffer(vid_enc_PrivateType * priv) { 84 assert(priv); 85 86 if (priv->in_port_disabled_) { 87 return NULL; 88 } 89 90 assert(!priv->p_inhdr_); /* encode_frame expects new buffers every time */ 91 92 tiz_krn_claim_buffer(tiz_get_krn(handleOf(priv)), 93 OMX_VID_ENC_AVC_INPUT_PORT_INDEX, 0, 94 &priv->p_inhdr_); 95 return priv->p_inhdr_; 96} 97 98static OMX_BUFFERHEADERTYPE * get_output_buffer(vid_enc_PrivateType * priv) { 99 assert(priv); 100 101 if (priv->out_port_disabled_) { 102 return NULL; 103 } 104 105 if (!priv->p_outhdr_) { 106 tiz_krn_claim_buffer(tiz_get_krn(handleOf(priv)), 107 OMX_VID_ENC_AVC_OUTPUT_PORT_INDEX, 0, 108 &priv->p_outhdr_); 109 } 110 return priv->p_outhdr_; 111} 112 113static OMX_ERRORTYPE h264e_buffer_emptied(vid_enc_PrivateType * priv, OMX_BUFFERHEADERTYPE * p_hdr) 114{ 115 OMX_ERRORTYPE r = OMX_ErrorNone; 116 117 assert(priv); 118 assert(priv->p_inhdr_ == p_hdr); 119 120 if (!priv->out_port_disabled_) { 121 p_hdr->nOffset = 0; 122 123 if ((p_hdr->nFlags & OMX_BUFFERFLAG_EOS) != 0) { 124 priv->eos_ = true; 125 } 126 127 r = tiz_krn_release_buffer(tiz_get_krn(handleOf(priv)), 0, p_hdr); 128 priv->p_inhdr_ = NULL; 129 } 130 131 return r; 132} 133 134static OMX_ERRORTYPE h264e_buffer_filled(vid_enc_PrivateType * priv, OMX_BUFFERHEADERTYPE * p_hdr) 135{ 136 OMX_ERRORTYPE r = OMX_ErrorNone; 137 138 assert(priv); 139 assert(priv->p_outhdr_ == p_hdr); 140 assert(p_hdr); 141 142 if (!priv->in_port_disabled_) { 143 p_hdr->nOffset = 0; 144 145 if (priv->eos_) { 146 /* EOS has been received and all the input data has been consumed 147 * already, so its time to propagate the EOS flag */ 148 priv->p_outhdr_->nFlags |= OMX_BUFFERFLAG_EOS; 149 } 150 151 r = tiz_krn_release_buffer(tiz_get_krn(handleOf(priv)), 152 OMX_VID_ENC_AVC_OUTPUT_PORT_INDEX, 153 p_hdr); 154 priv->p_outhdr_ = NULL; 155 } 156 157 return r; 158} 159 160 161static void release_input_header(vid_enc_PrivateType * priv) { 162 assert(!priv->in_port_disabled_); 163 if (priv->p_inhdr_) { 164 (void) tiz_krn_release_buffer(tiz_get_krn(handleOf(priv)), 165 OMX_VID_ENC_AVC_INPUT_PORT_INDEX, 166 priv->p_inhdr_); 167 } 168 priv->p_inhdr_ = NULL; 169} 170 171static void release_output_header(vid_enc_PrivateType * priv) { 172 if (priv->p_outhdr_) { 173 assert(!priv->out_port_disabled_); 174 (void) tiz_krn_release_buffer(tiz_get_krn(handleOf(priv)), 175 OMX_VID_ENC_AVC_OUTPUT_PORT_INDEX, 176 priv->p_outhdr_); 177 priv->p_outhdr_ = NULL; 178 } 179} 180 181static OMX_ERRORTYPE h264e_release_all_headers(vid_enc_PrivateType * priv) 182{ 183 assert(priv); 184 185 release_input_header(priv); 186 release_output_header(priv); 187 188 return OMX_ErrorNone; 189} 190 191static void reset_stream_parameters(vid_enc_PrivateType * priv) 192{ 193 assert(priv); 194 init_port_structs(priv); 195 priv->p_inhdr_ = 0; 196 priv->p_outhdr_ = 0; 197 priv->eos_ = false; 198} 199 200/* Replacement for bellagio's omx_base_filter_BufferMgmtFunction */ 201static OMX_ERRORTYPE h264e_manage_buffers(vid_enc_PrivateType* priv) { 202 OMX_BUFFERHEADERTYPE * in_buf = priv->p_inhdr_; 203 OMX_BUFFERHEADERTYPE * out_buf = priv->p_outhdr_; 204 OMX_ERRORTYPE r = OMX_ErrorNone; 205 206 if (in_buf->nFilledLen > 0) { 207 vid_enc_BufferEncoded_common(priv, in_buf, out_buf); 208 } else { 209 in_buf->nFilledLen = 0; 210 } 211 212 out_buf->nTimeStamp = in_buf->nTimeStamp; 213 214 /* Release input buffer if possible */ 215 if (in_buf->nFilledLen == 0) { 216 r = h264e_buffer_emptied(priv, in_buf); 217 } 218 219 /* Realase output buffer if filled or eos */ 220 if ((out_buf->nFilledLen != 0) || priv->eos_) { 221 r = h264e_buffer_filled(priv, out_buf); 222 } 223 224 return r; 225} 226 227static struct encode_task *enc_NeedTask(vid_enc_PrivateType * priv) 228{ 229 OMX_VIDEO_PORTDEFINITIONTYPE *def = &priv->in_port_def_.format.video; 230 231 return enc_NeedTask_common(priv, def); 232} 233 234static void enc_ScaleInput(vid_enc_PrivateType * priv, struct pipe_video_buffer **vbuf, unsigned *size) 235{ 236 OMX_VIDEO_PORTDEFINITIONTYPE *def = &priv->in_port_def_.format.video; 237 enc_ScaleInput_common(priv, def, vbuf, size); 238} 239 240static void enc_HandleTask(vid_enc_PrivateType * priv, struct encode_task *task, 241 enum pipe_h2645_enc_picture_type picture_type) 242{ 243 unsigned size = priv->out_port_def_.nBufferSize; 244 struct pipe_video_buffer *vbuf = task->buf; 245 struct pipe_h264_enc_picture_desc picture = {}; 246 247 /* -------------- scale input image --------- */ 248 enc_ScaleInput(priv, &vbuf, &size); 249 priv->s_pipe->flush(priv->s_pipe, NULL, 0); 250 251 /* -------------- allocate output buffer --------- */ 252 task->bitstream = pipe_buffer_create(priv->s_pipe->screen, 253 PIPE_BIND_VERTEX_BUFFER, 254 PIPE_USAGE_STAGING, /* map for read */ 255 size); 256 257 picture.picture_type = picture_type; 258 picture.pic_order_cnt = task->pic_order_cnt; 259 if (priv->restricted_b_frames && picture_type == PIPE_H2645_ENC_PICTURE_TYPE_B) 260 picture.not_referenced = true; 261 enc_ControlPicture_common(priv, &picture); 262 263 /* -------------- encode frame --------- */ 264 priv->codec->begin_frame(priv->codec, vbuf, &picture.base); 265 priv->codec->encode_bitstream(priv->codec, vbuf, task->bitstream, &task->feedback); 266 priv->codec->end_frame(priv->codec, vbuf, &picture.base); 267} 268 269static void enc_ClearBframes(vid_enc_PrivateType * priv, struct input_buf_private *inp) 270{ 271 struct encode_task *task; 272 273 if (list_is_empty(&priv->b_frames)) 274 return; 275 276 task = list_entry(priv->b_frames.prev, struct encode_task, list); 277 list_del(&task->list); 278 279 /* promote last from to P frame */ 280 priv->ref_idx_l0 = priv->ref_idx_l1; 281 enc_HandleTask(priv, task, PIPE_H2645_ENC_PICTURE_TYPE_P); 282 list_addtail(&task->list, &inp->tasks); 283 priv->ref_idx_l1 = priv->frame_num++; 284 285 /* handle B frames */ 286 LIST_FOR_EACH_ENTRY(task, &priv->b_frames, list) { 287 enc_HandleTask(priv, task, PIPE_H2645_ENC_PICTURE_TYPE_B); 288 if (!priv->restricted_b_frames) 289 priv->ref_idx_l0 = priv->frame_num; 290 priv->frame_num++; 291 } 292 293 enc_MoveTasks(&priv->b_frames, &inp->tasks); 294} 295 296static OMX_ERRORTYPE enc_LoadImage(vid_enc_PrivateType * priv, OMX_BUFFERHEADERTYPE *buf, 297 struct pipe_video_buffer *vbuf) 298{ 299 OMX_VIDEO_PORTDEFINITIONTYPE *def = &priv->in_port_def_.format.video; 300 return enc_LoadImage_common(priv, def, buf, vbuf); 301} 302 303static OMX_ERRORTYPE encode_frame(vid_enc_PrivateType * priv, OMX_BUFFERHEADERTYPE * in_buf) 304{ 305 struct input_buf_private *inp = in_buf->pInputPortPrivate; 306 enum pipe_h2645_enc_picture_type picture_type; 307 struct encode_task *task; 308 unsigned stacked_num = 0; 309 OMX_ERRORTYPE err; 310 311 enc_MoveTasks(&inp->tasks, &priv->free_tasks); 312 task = enc_NeedTask(priv); 313 if (!task) 314 return OMX_ErrorInsufficientResources; 315 316 /* EOS */ 317 if (in_buf->nFilledLen == 0) { 318 if (in_buf->nFlags & OMX_BUFFERFLAG_EOS) { 319 in_buf->nFilledLen = in_buf->nAllocLen; 320 enc_ClearBframes(priv, inp); 321 enc_MoveTasks(&priv->stacked_tasks, &inp->tasks); 322 priv->codec->flush(priv->codec); 323 } 324 return h264e_manage_buffers(priv); 325 } 326 327 if (in_buf->pOutputPortPrivate) { 328 struct pipe_video_buffer *vbuf = in_buf->pOutputPortPrivate; 329 in_buf->pOutputPortPrivate = task->buf; 330 task->buf = vbuf; 331 } else { 332 /* ------- load input image into video buffer ---- */ 333 err = enc_LoadImage(priv, in_buf, task->buf); 334 if (err != OMX_ErrorNone) { 335 FREE(task); 336 return err; 337 } 338 } 339 340 /* -------------- determine picture type --------- */ 341 if (!(priv->pic_order_cnt % OMX_VID_ENC_IDR_PERIOD_DEFAULT) || 342 priv->force_pic_type.IntraRefreshVOP) { 343 enc_ClearBframes(priv, inp); 344 picture_type = PIPE_H2645_ENC_PICTURE_TYPE_IDR; 345 priv->force_pic_type.IntraRefreshVOP = OMX_FALSE; 346 priv->frame_num = 0; 347 } else if (priv->codec->profile == PIPE_VIDEO_PROFILE_MPEG4_AVC_BASELINE || 348 !(priv->pic_order_cnt % OMX_VID_ENC_P_PERIOD_DEFAULT) || 349 (in_buf->nFlags & OMX_BUFFERFLAG_EOS)) { 350 picture_type = PIPE_H2645_ENC_PICTURE_TYPE_P; 351 } else { 352 picture_type = PIPE_H2645_ENC_PICTURE_TYPE_B; 353 } 354 355 task->pic_order_cnt = priv->pic_order_cnt++; 356 357 if (picture_type == PIPE_H2645_ENC_PICTURE_TYPE_B) { 358 /* put frame at the tail of the queue */ 359 list_addtail(&task->list, &priv->b_frames); 360 } else { 361 /* handle I or P frame */ 362 priv->ref_idx_l0 = priv->ref_idx_l1; 363 enc_HandleTask(priv, task, picture_type); 364 list_addtail(&task->list, &priv->stacked_tasks); 365 LIST_FOR_EACH_ENTRY(task, &priv->stacked_tasks, list) { 366 ++stacked_num; 367 } 368 if (stacked_num == priv->stacked_frames_num) { 369 struct encode_task *t; 370 t = list_entry(priv->stacked_tasks.next, struct encode_task, list); 371 list_del(&t->list); 372 list_addtail(&t->list, &inp->tasks); 373 } 374 priv->ref_idx_l1 = priv->frame_num++; 375 376 /* handle B frames */ 377 LIST_FOR_EACH_ENTRY(task, &priv->b_frames, list) { 378 enc_HandleTask(priv, task, PIPE_H2645_ENC_PICTURE_TYPE_B); 379 if (!priv->restricted_b_frames) 380 priv->ref_idx_l0 = priv->frame_num; 381 priv->frame_num++; 382 } 383 384 enc_MoveTasks(&priv->b_frames, &inp->tasks); 385 } 386 387 if (list_is_empty(&inp->tasks)) { 388 return h264e_buffer_emptied(priv, in_buf); 389 } else { 390 return h264e_manage_buffers(priv); 391 } 392} 393 394static OMX_ERRORTYPE h264e_prc_create_encoder(void *ap_obj) 395{ 396 vid_enc_PrivateType *priv = ap_obj; 397 struct pipe_screen *screen; 398 399 priv->screen = omx_get_screen(); 400 if (!priv->screen) 401 return OMX_ErrorInsufficientResources; 402 403 screen = priv->screen->pscreen; 404 if (!vl_codec_supported(screen, PIPE_VIDEO_PROFILE_MPEG4_AVC_HIGH, true)) 405 return OMX_ErrorBadParameter; 406 407 priv->s_pipe = pipe_create_multimedia_context(screen); 408 if (!priv->s_pipe) 409 return OMX_ErrorInsufficientResources; 410 411 enc_InitCompute_common(priv); 412 413 if (!vl_compositor_init(&priv->compositor, priv->s_pipe)) { 414 priv->s_pipe->destroy(priv->s_pipe); 415 priv->s_pipe = NULL; 416 return OMX_ErrorInsufficientResources; 417 } 418 419 if (!vl_compositor_init_state(&priv->cstate, priv->s_pipe)) { 420 vl_compositor_cleanup(&priv->compositor); 421 priv->s_pipe->destroy(priv->s_pipe); 422 priv->s_pipe = NULL; 423 return OMX_ErrorInsufficientResources; 424 } 425 426 priv->t_pipe = pipe_create_multimedia_context(screen); 427 if (!priv->t_pipe) 428 return OMX_ErrorInsufficientResources; 429 430 list_inithead(&priv->free_tasks); 431 list_inithead(&priv->used_tasks); 432 list_inithead(&priv->b_frames); 433 list_inithead(&priv->stacked_tasks); 434 435 return OMX_ErrorNone; 436} 437 438static void h264e_prc_destroy_encoder(void *ap_obj) 439{ 440 vid_enc_PrivateType *priv = ap_obj; 441 int i; 442 443 assert (priv); 444 445 enc_ReleaseTasks(&priv->free_tasks); 446 enc_ReleaseTasks(&priv->used_tasks); 447 enc_ReleaseTasks(&priv->b_frames); 448 enc_ReleaseTasks(&priv->stacked_tasks); 449 450 for (i = 0; i < OMX_VID_ENC_NUM_SCALING_BUFFERS; ++i) 451 if (priv->scale_buffer[i]) 452 priv->scale_buffer[i]->destroy(priv->scale_buffer[i]); 453 454 if (priv->s_pipe) { 455 vl_compositor_cleanup_state(&priv->cstate); 456 vl_compositor_cleanup(&priv->compositor); 457 enc_ReleaseCompute_common(priv); 458 priv->s_pipe->destroy(priv->s_pipe); 459 } 460 461 if (priv->t_pipe) 462 priv->t_pipe->destroy(priv->t_pipe); 463 464 if (priv->screen) 465 omx_put_screen(); 466} 467 468/* 469 * h264eprc 470 */ 471 472static void * h264e_prc_ctor(void *ap_obj, va_list * app) 473{ 474 vid_enc_PrivateType *priv = super_ctor(typeOf(ap_obj, "h264eprc"), ap_obj, app); 475 assert (priv); 476 477 if (h264e_prc_create_encoder(ap_obj) != OMX_ErrorNone) 478 return priv; 479 480 priv->p_inhdr_ = 0; 481 priv->p_outhdr_ = 0; 482 priv->profile_level.eProfile = OMX_VIDEO_AVCProfileBaseline; 483 priv->profile_level.eLevel = OMX_VIDEO_AVCLevel51; 484 priv->force_pic_type.IntraRefreshVOP = OMX_FALSE; 485 priv->frame_num = 0; 486 priv->pic_order_cnt = 0; 487 priv->restricted_b_frames = debug_get_bool_option("OMX_USE_RESTRICTED_B_FRAMES", FALSE); 488 priv->scale.xWidth = OMX_VID_ENC_SCALING_WIDTH_DEFAULT; 489 priv->scale.xHeight = OMX_VID_ENC_SCALING_WIDTH_DEFAULT; 490 priv->in_port_disabled_ = false; 491 priv->out_port_disabled_ = false; 492 reset_stream_parameters(priv); 493 494 return priv; 495} 496 497static void * h264e_prc_dtor(void *ap_obj) 498{ 499 h264e_prc_destroy_encoder(ap_obj); 500 return super_dtor(typeOf(ap_obj, "h264eprc"), ap_obj); 501} 502 503static OMX_ERRORTYPE h264e_prc_allocate_resources(void *ap_obj, OMX_U32 a_pid) 504{ 505 vid_enc_PrivateType *priv = ap_obj; 506 507 assert(priv); 508 if (!priv->screen) 509 return OMX_ErrorInsufficientResources; 510 511 return OMX_ErrorNone; 512} 513 514static OMX_ERRORTYPE h264e_prc_deallocate_resources(void *ap_obj) 515{ 516 return OMX_ErrorNone; 517} 518 519static OMX_ERRORTYPE h264e_prc_prepare_to_transfer(void *ap_obj, OMX_U32 a_pid) 520{ 521 vid_enc_PrivateType *priv = ap_obj; 522 523 assert(priv); 524 525 init_port_structs(priv); 526 527 priv->eos_ = false; 528 529 struct pipe_video_codec templat = {}; 530 531 templat.profile = enc_TranslateOMXProfileToPipe(priv->profile_level.eProfile); 532 templat.level = enc_TranslateOMXLevelToPipe(priv->profile_level.eLevel); 533 templat.entrypoint = PIPE_VIDEO_ENTRYPOINT_ENCODE; 534 templat.chroma_format = PIPE_VIDEO_CHROMA_FORMAT_420; 535 templat.width = priv->scale_buffer[priv->current_scale_buffer] ? 536 priv->scale.xWidth : priv->in_port_def_.format.video.nFrameWidth; 537 templat.height = priv->scale_buffer[priv->current_scale_buffer] ? 538 priv->scale.xHeight : priv->in_port_def_.format.video.nFrameHeight; 539 540 if (templat.profile == PIPE_VIDEO_PROFILE_MPEG4_AVC_BASELINE) { 541 struct pipe_screen *screen = priv->screen->pscreen; 542 templat.max_references = 1; 543 priv->stacked_frames_num = 544 screen->get_video_param(screen, 545 PIPE_VIDEO_PROFILE_MPEG4_AVC_HIGH, 546 PIPE_VIDEO_ENTRYPOINT_ENCODE, 547 PIPE_VIDEO_CAP_STACKED_FRAMES); 548 } else { 549 templat.max_references = OMX_VID_ENC_P_PERIOD_DEFAULT; 550 priv->stacked_frames_num = 1; 551 } 552 priv->codec = priv->s_pipe->create_video_codec(priv->s_pipe, &templat); 553 554 return OMX_ErrorNone; 555} 556 557static OMX_ERRORTYPE h264e_prc_transfer_and_process(void *ap_obj, OMX_U32 a_pid) 558{ 559 return OMX_ErrorNone; 560} 561 562static OMX_ERRORTYPE h264e_prc_stop_and_return(void *ap_obj) 563{ 564 vid_enc_PrivateType *priv = (vid_enc_PrivateType *) ap_obj; 565 return h264e_release_all_headers(priv); 566} 567 568static OMX_ERRORTYPE h264e_prc_buffers_ready(const void *ap_obj) 569{ 570 vid_enc_PrivateType *priv = (vid_enc_PrivateType *) ap_obj; 571 OMX_BUFFERHEADERTYPE *in_buf = NULL; 572 OMX_BUFFERHEADERTYPE *out_buf = NULL; 573 OMX_ERRORTYPE r = OMX_ErrorNone; 574 575 assert(priv); 576 577 /* Don't get input buffer if output buffer not found */ 578 while (!priv->eos_ && (out_buf = get_output_buffer(priv)) && (in_buf = get_input_buffer(priv))) { 579 if (!priv->out_port_disabled_) { 580 r = encode_frame(priv, in_buf); 581 } 582 } 583 584 return r; 585} 586 587static OMX_ERRORTYPE h264e_prc_port_flush(const void *ap_obj, OMX_U32 a_pid) 588{ 589 vid_enc_PrivateType *priv = (vid_enc_PrivateType *) ap_obj; 590 if (OMX_ALL == a_pid || OMX_VID_ENC_AVC_INPUT_PORT_INDEX == a_pid) { 591 release_input_header(priv); 592 reset_stream_parameters(priv); 593 } 594 if (OMX_ALL == a_pid || OMX_VID_ENC_AVC_OUTPUT_PORT_INDEX == a_pid) { 595 release_output_header(priv); 596 } 597 return OMX_ErrorNone; 598} 599 600static OMX_ERRORTYPE h264e_prc_port_disable(const void *ap_obj, OMX_U32 a_pid) 601{ 602 vid_enc_PrivateType *priv = (vid_enc_PrivateType *) ap_obj; 603 assert(priv); 604 if (OMX_ALL == a_pid || OMX_VID_ENC_AVC_INPUT_PORT_INDEX == a_pid) { 605 /* Release all buffers */ 606 h264e_release_all_headers(priv); 607 reset_stream_parameters(priv); 608 priv->in_port_disabled_ = true; 609 } 610 if (OMX_ALL == a_pid || OMX_VID_ENC_AVC_OUTPUT_PORT_INDEX == a_pid) { 611 release_output_header(priv); 612 priv->out_port_disabled_ = true; 613 } 614 return OMX_ErrorNone; 615} 616 617static OMX_ERRORTYPE h264e_prc_port_enable(const void *ap_obj, OMX_U32 a_pid) 618{ 619 vid_enc_PrivateType * priv = (vid_enc_PrivateType *) ap_obj; 620 assert(priv); 621 if (OMX_ALL == a_pid || OMX_VID_ENC_AVC_INPUT_PORT_INDEX == a_pid) { 622 if (priv->in_port_disabled_) { 623 reset_stream_parameters(priv); 624 priv->in_port_disabled_ = false; 625 } 626 } 627 if (OMX_ALL == a_pid || OMX_VID_ENC_AVC_OUTPUT_PORT_INDEX == a_pid) { 628 priv->out_port_disabled_ = false; 629 } 630 return OMX_ErrorNone; 631} 632 633/* 634 * h264e_prc_class 635 */ 636 637static void * h264e_prc_class_ctor(void *ap_obj, va_list * app) 638{ 639 /* NOTE: Class methods might be added in the future. None for now. */ 640 return super_ctor(typeOf(ap_obj, "h264eprc_class"), ap_obj, app); 641} 642 643/* 644 * initialization 645 */ 646 647void * h264e_prc_class_init(void * ap_tos, void * ap_hdl) 648{ 649 void * tizprc = tiz_get_type(ap_hdl, "tizprc"); 650 void * h264eprc_class = factory_new 651 /* TIZ_CLASS_COMMENT: class type, class name, parent, size */ 652 (classOf(tizprc), "h264eprc_class", classOf(tizprc), 653 sizeof(h264e_prc_class_t), 654 /* TIZ_CLASS_COMMENT: */ 655 ap_tos, ap_hdl, 656 /* TIZ_CLASS_COMMENT: class constructor */ 657 ctor, h264e_prc_class_ctor, 658 /* TIZ_CLASS_COMMENT: stop value*/ 659 0); 660 return h264eprc_class; 661} 662 663void * h264e_prc_init(void * ap_tos, void * ap_hdl) 664{ 665 void * tizprc = tiz_get_type(ap_hdl, "tizprc"); 666 void * h264eprc_class = tiz_get_type(ap_hdl, "h264eprc_class"); 667 TIZ_LOG_CLASS (h264eprc_class); 668 void * h264eprc = factory_new 669 /* TIZ_CLASS_COMMENT: class type, class name, parent, size */ 670 (h264eprc_class, "h264eprc", tizprc, sizeof(vid_enc_PrivateType), 671 /* TIZ_CLASS_COMMENT: */ 672 ap_tos, ap_hdl, 673 /* TIZ_CLASS_COMMENT: class constructor */ 674 ctor, h264e_prc_ctor, 675 /* TIZ_CLASS_COMMENT: class destructor */ 676 dtor, h264e_prc_dtor, 677 /* TIZ_CLASS_COMMENT: */ 678 tiz_srv_allocate_resources, h264e_prc_allocate_resources, 679 /* TIZ_CLASS_COMMENT: */ 680 tiz_srv_deallocate_resources, h264e_prc_deallocate_resources, 681 /* TIZ_CLASS_COMMENT: */ 682 tiz_srv_prepare_to_transfer, h264e_prc_prepare_to_transfer, 683 /* TIZ_CLASS_COMMENT: */ 684 tiz_srv_transfer_and_process, h264e_prc_transfer_and_process, 685 /* TIZ_CLASS_COMMENT: */ 686 tiz_srv_stop_and_return, h264e_prc_stop_and_return, 687 /* TIZ_CLASS_COMMENT: */ 688 tiz_prc_buffers_ready, h264e_prc_buffers_ready, 689 /* TIZ_CLASS_COMMENT: */ 690 tiz_prc_port_flush, h264e_prc_port_flush, 691 /* TIZ_CLASS_COMMENT: */ 692 tiz_prc_port_disable, h264e_prc_port_disable, 693 /* TIZ_CLASS_COMMENT: */ 694 tiz_prc_port_enable, h264e_prc_port_enable, 695 /* TIZ_CLASS_COMMENT: stop value*/ 696 0); 697 698 return h264eprc; 699} 700