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