Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mesa
Path: blob/21.2-virgl/src/gallium/frontends/omx/tizonia/h264eprc.c
4561 views
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
42
static 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
81
static 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
96
static 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
111
static 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
132
static 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
159
static 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
169
static 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
179
static 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
189
static 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 */
199
static 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
225
static 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
232
static 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
238
static 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
267
static 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
294
static 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
301
static 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
392
static 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
437
static 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
471
static 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
496
static 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
502
static 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
513
static OMX_ERRORTYPE h264e_prc_deallocate_resources(void *ap_obj)
514
{
515
return OMX_ErrorNone;
516
}
517
518
static 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
556
static OMX_ERRORTYPE h264e_prc_transfer_and_process(void *ap_obj, OMX_U32 a_pid)
557
{
558
return OMX_ErrorNone;
559
}
560
561
static 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
567
static 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
586
static 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
599
static 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
616
static 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
636
static 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
646
void * 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
662
void * 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
700