1 /*
2 INTEL CONFIDENTIAL
3 Copyright 2009 Intel Corporation All Rights Reserved.
4 The source code contained or described herein and all documents related to the source code ("Material") are owned by Intel Corporation or its suppliers or licensors. Title to the Material remains with Intel Corporation or its suppliers and licensors. The Material contains trade secrets and proprietary and confidential information of Intel or its suppliers and licensors. The Material is protected by worldwide copyright and trade secret laws and treaty provisions. No part of the Material may be used, copied, reproduced, modified, published, uploaded, posted, transmitted, distributed, or disclosed in any way without Intel’s prior express written permission.
5
6 No license under any patent, copyright, trade secret or other intellectual property right is granted to or conferred upon you by disclosure or delivery of the Materials, either expressly, by implication, inducement, estoppel or otherwise. Any license under such intellectual property rights must be express and approved by Intel in writing.
7 */
8 #include <glib.h>
9 #include "mixvideolog.h"
10 #include "mixvideoformatenc.h"
11
12 //#define MDEBUG
13
14 /* Default vmethods implementation */
15 static MIX_RESULT mix_videofmtenc_getcaps_default(MixVideoFormatEnc *mix,
16 GString *msg);
17 static MIX_RESULT mix_videofmtenc_initialize_default(MixVideoFormatEnc *mix,
18 MixVideoConfigParamsEnc * config_params_enc,
19 MixFrameManager * frame_mgr,
20 MixBufferPool * input_buf_pool,
21 MixSurfacePool ** surface_pool,
22 VADisplay vadisplay);
23
24 static MIX_RESULT
25 mix_videofmtenc_encode_default(MixVideoFormatEnc *mix, MixBuffer * bufin[],
26 gint bufincnt, MixIOVec * iovout[], gint iovoutcnt,
27 MixVideoEncodeParams * encode_params);
28 static MIX_RESULT mix_videofmtenc_flush_default(MixVideoFormatEnc *mix);
29 static MIX_RESULT mix_videofmtenc_eos_default(MixVideoFormatEnc *mix);
30 static MIX_RESULT mix_videofmtenc_deinitialize_default(MixVideoFormatEnc *mix);
31 static MIX_RESULT mix_videofmtenc_get_max_coded_buffer_size_default(
32 MixVideoFormatEnc *mix, guint *max_size);
33
34
35 static GObjectClass *parent_class = NULL;
36
37 static void mix_videoformatenc_finalize(GObject * obj);
38 G_DEFINE_TYPE (MixVideoFormatEnc, mix_videoformatenc, G_TYPE_OBJECT);
39
mix_videoformatenc_init(MixVideoFormatEnc * self)40 static void mix_videoformatenc_init(MixVideoFormatEnc * self) {
41 /* TODO: public member initialization */
42
43 /* TODO: private member initialization */
44
45 self->objectlock = g_mutex_new();
46
47 self->initialized = FALSE;
48 self->framemgr = NULL;
49 self->surfacepool = NULL;
50 self->inputbufpool = NULL;
51 self->inputbufqueue = NULL;
52 self->va_display = NULL;
53 self->va_context = 0;
54 self->va_config = 0;
55 self->mime_type = NULL;
56 self->frame_rate_num= 0;
57 self->frame_rate_denom = 1;
58 self->picture_width = 0;
59 self->picture_height = 0;
60 self->initial_qp = 0;
61 self->min_qp = 0;
62 self->intra_period = 0;
63 self->bitrate = 0;
64 self->share_buf_mode = FALSE;
65 self->ci_frame_id = NULL;
66 self->ci_frame_num = 0;
67 self->drawable = 0x0;
68 self->need_display = TRUE;
69
70 self->va_rcmode = VA_RC_NONE;
71 self->va_format = VA_RT_FORMAT_YUV420;
72 self->va_entrypoint = VAEntrypointEncSlice;
73 self->va_profile = VAProfileH264Baseline;
74
75 //add more properties here
76 }
77
mix_videoformatenc_class_init(MixVideoFormatEncClass * klass)78 static void mix_videoformatenc_class_init(MixVideoFormatEncClass * klass) {
79 GObjectClass *gobject_class = (GObjectClass *) klass;
80
81 /* parent class for later use */
82 parent_class = g_type_class_peek_parent(klass);
83
84 gobject_class->finalize = mix_videoformatenc_finalize;
85
86 /* setup vmethods with base implementation */
87 klass->getcaps = mix_videofmtenc_getcaps_default;
88 klass->initialize = mix_videofmtenc_initialize_default;
89 klass->encode = mix_videofmtenc_encode_default;
90 klass->flush = mix_videofmtenc_flush_default;
91 klass->eos = mix_videofmtenc_eos_default;
92 klass->deinitialize = mix_videofmtenc_deinitialize_default;
93 klass->getmaxencodedbufsize = mix_videofmtenc_get_max_coded_buffer_size_default;
94 }
95
96 MixVideoFormatEnc *
mix_videoformatenc_new(void)97 mix_videoformatenc_new(void) {
98 MixVideoFormatEnc *ret = g_object_new(MIX_TYPE_VIDEOFORMATENC, NULL);
99
100 return ret;
101 }
102
mix_videoformatenc_finalize(GObject * obj)103 void mix_videoformatenc_finalize(GObject * obj) {
104 /* clean up here. */
105
106 if (obj == NULL) {
107 LOG_E( "obj == NULL\n");
108 return;
109 }
110
111 MixVideoFormatEnc *mix = MIX_VIDEOFORMATENC(obj);
112
113 LOG_V( "\n");
114
115 if(mix->objectlock) {
116 g_mutex_free(mix->objectlock);
117 mix->objectlock = NULL;
118 }
119
120 //MiVideo object calls the _deinitialize() for frame manager
121 if (mix->framemgr)
122 {
123 mix_framemanager_unref(mix->framemgr);
124 mix->framemgr = NULL;
125 }
126
127 if (mix->mime_type)
128 {
129 if (mix->mime_type->str)
130 g_string_free(mix->mime_type, TRUE);
131 else
132 g_string_free(mix->mime_type, FALSE);
133 }
134
135 if (mix->ci_frame_id)
136 g_free (mix->ci_frame_id);
137
138
139 if (mix->surfacepool)
140 {
141 mix_surfacepool_deinitialize(mix->surfacepool);
142 mix_surfacepool_unref(mix->surfacepool);
143 mix->surfacepool = NULL;
144 }
145
146
147 /* TODO: cleanup here */
148
149 /* Chain up parent */
150 if (parent_class->finalize) {
151 parent_class->finalize(obj);
152 }
153 }
154
155 MixVideoFormatEnc *
mix_videoformatenc_ref(MixVideoFormatEnc * mix)156 mix_videoformatenc_ref(MixVideoFormatEnc * mix) {
157 return (MixVideoFormatEnc *) g_object_ref(G_OBJECT(mix));
158 }
159
160 /* Default vmethods implementation */
mix_videofmtenc_getcaps_default(MixVideoFormatEnc * mix,GString * msg)161 static MIX_RESULT mix_videofmtenc_getcaps_default(MixVideoFormatEnc *mix,
162 GString *msg) {
163 LOG_V( "Begin\n");
164 return MIX_RESULT_SUCCESS;
165 }
166
mix_videofmtenc_initialize_default(MixVideoFormatEnc * mix,MixVideoConfigParamsEnc * config_params_enc,MixFrameManager * frame_mgr,MixBufferPool * input_buf_pool,MixSurfacePool ** surface_pool,VADisplay va_display)167 static MIX_RESULT mix_videofmtenc_initialize_default(MixVideoFormatEnc *mix,
168 MixVideoConfigParamsEnc * config_params_enc,
169 MixFrameManager * frame_mgr,
170 MixBufferPool * input_buf_pool,
171 MixSurfacePool ** surface_pool,
172 VADisplay va_display) {
173
174 LOG_V( "Begin\n");
175
176 if (mix == NULL ||config_params_enc == NULL) {
177 LOG_E(
178 "!mix || config_params_enc == NULL\n");
179 return MIX_RESULT_NULL_PTR;
180 }
181
182
183 MIX_RESULT ret = MIX_RESULT_SUCCESS;
184
185 //TODO check return values of getter fns for config_params
186
187 g_mutex_lock(mix->objectlock);
188
189 mix->framemgr = frame_mgr;
190 mix_framemanager_ref(mix->framemgr);
191
192 mix->va_display = va_display;
193
194 LOG_V(
195 "Start to get properities from parent params\n");
196
197 /* get properties from param (parent) Object*/
198 ret = mix_videoconfigparamsenc_get_bit_rate (config_params_enc,
199 &(mix->bitrate));
200 if (ret != MIX_RESULT_SUCCESS) {
201 //TODO cleanup
202 LOG_E(
203 "Failed to mix_videoconfigparamsenc_get_bps\n");
204 g_mutex_unlock(mix->objectlock);
205 return MIX_RESULT_FAIL;
206 }
207
208 ret = mix_videoconfigparamsenc_get_frame_rate (config_params_enc,
209 &(mix->frame_rate_num), &(mix->frame_rate_denom));
210
211 if (ret != MIX_RESULT_SUCCESS) {
212 //TODO cleanup
213 LOG_E(
214 "Failed to mix_videoconfigparamsenc_get_frame_rate\n");
215 g_mutex_unlock(mix->objectlock);
216 return MIX_RESULT_FAIL;
217 }
218
219 ret = mix_videoconfigparamsenc_get_init_qp (config_params_enc,
220 &(mix->initial_qp));
221
222 if (ret != MIX_RESULT_SUCCESS) {
223 //TODO cleanup
224
225 LOG_E(
226 "Failed to mix_videoconfigparamsenc_get_init_qp\n");
227 g_mutex_unlock(mix->objectlock);
228 return MIX_RESULT_FAIL;
229 }
230
231
232 ret = mix_videoconfigparamsenc_get_min_qp (config_params_enc,
233 &(mix->min_qp));
234
235 if (ret != MIX_RESULT_SUCCESS) {
236 //TODO cleanup
237
238 LOG_E(
239 "Failed to mix_videoconfigparamsenc_get_min_qp\n");
240 g_mutex_unlock(mix->objectlock);
241 return MIX_RESULT_FAIL;
242 }
243
244 ret = mix_videoconfigparamsenc_get_intra_period (config_params_enc,
245 &(mix->intra_period));
246
247 if (ret != MIX_RESULT_SUCCESS) {
248 //TODO cleanup
249
250 LOG_E(
251 "Failed to mix_videoconfigparamsenc_get_intra_period\n");
252 g_mutex_unlock(mix->objectlock);
253 return MIX_RESULT_FAIL;
254 }
255
256 ret = mix_videoconfigparamsenc_get_picture_res (config_params_enc,
257 &(mix->picture_width), &(mix->picture_height));
258
259 if (ret != MIX_RESULT_SUCCESS) {
260 //TODO cleanup
261
262 LOG_E(
263 "Failed to mix_videoconfigparamsenc_get_picture_res\n");
264 g_mutex_unlock(mix->objectlock);
265 return MIX_RESULT_FAIL;
266 }
267
268 ret = mix_videoconfigparamsenc_get_share_buf_mode (config_params_enc,
269 &(mix->share_buf_mode));
270
271 if (ret != MIX_RESULT_SUCCESS) {
272 //TODO cleanup
273
274 LOG_E(
275 "Failed to mix_videoconfigparamsenc_get_share_buf_mode\n");
276 g_mutex_unlock(mix->objectlock);
277 return MIX_RESULT_FAIL;
278 }
279
280
281 ret = mix_videoconfigparamsenc_get_ci_frame_info (config_params_enc,
282 &(mix->ci_frame_id), &(mix->ci_frame_num));
283
284 if (ret != MIX_RESULT_SUCCESS) {
285 //TODO cleanup
286
287 LOG_E(
288 "Failed to mix_videoconfigparamsenc_get_ci_frame_info\n");
289 g_mutex_unlock(mix->objectlock);
290 return MIX_RESULT_FAIL;
291 }
292
293
294 ret = mix_videoconfigparamsenc_get_drawable (config_params_enc,
295 &(mix->drawable));
296
297 if (ret != MIX_RESULT_SUCCESS) {
298 //TODO cleanup
299
300 LOG_E(
301 "Failed to mix_videoconfigparamsenc_get_drawable\n");
302 g_mutex_unlock(mix->objectlock);
303 return MIX_RESULT_FAIL;
304 }
305
306 ret = mix_videoconfigparamsenc_get_need_display (config_params_enc,
307 &(mix->need_display));
308
309 if (ret != MIX_RESULT_SUCCESS) {
310 //TODO cleanup
311
312 LOG_E(
313 "Failed to mix_videoconfigparamsenc_get_drawable\n");
314 g_mutex_unlock(mix->objectlock);
315 return MIX_RESULT_FAIL;
316 }
317
318 ret = mix_videoconfigparamsenc_get_rate_control (config_params_enc,
319 &(mix->va_rcmode));
320
321 if (ret != MIX_RESULT_SUCCESS) {
322 //TODO cleanup
323
324 LOG_E(
325 "Failed to mix_videoconfigparamsenc_get_rc_mode\n");
326 g_mutex_unlock(mix->objectlock);
327 return MIX_RESULT_FAIL;
328 }
329
330 ret = mix_videoconfigparamsenc_get_raw_format (config_params_enc,
331 &(mix->va_format));
332
333 if (ret != MIX_RESULT_SUCCESS) {
334 //TODO cleanup
335
336 LOG_E(
337 "Failed to mix_videoconfigparamsenc_get_format\n");
338 g_mutex_unlock(mix->objectlock);
339 return MIX_RESULT_FAIL;
340 }
341
342 ret = mix_videoconfigparamsenc_get_profile (config_params_enc,
343 (MixProfile *) &(mix->va_profile));
344
345 if (ret != MIX_RESULT_SUCCESS) {
346 //TODO cleanup
347
348 LOG_E(
349 "Failed to mix_videoconfigparamsenc_get_profile\n");
350 g_mutex_unlock(mix->objectlock);
351 return MIX_RESULT_FAIL;
352 }
353
354
355 LOG_V(
356 "======Video Encode Parent Object properities======:\n");
357
358 LOG_I( "mix->bitrate = %d\n",
359 mix->bitrate);
360 LOG_I( "mix->frame_rate = %d\n",
361 mix->frame_rate_denom / mix->frame_rate_denom);
362 LOG_I( "mix->initial_qp = %d\n",
363 mix->initial_qp);
364 LOG_I( "mix->min_qp = %d\n",
365 mix->min_qp);
366 LOG_I( "mix->intra_period = %d\n",
367 mix->intra_period);
368 LOG_I( "mix->picture_width = %d\n",
369 mix->picture_width);
370 LOG_I( "mix->picture_height = %d\n",
371 mix->picture_height);
372 LOG_I( "mix->share_buf_mode = %d\n",
373 mix->share_buf_mode);
374 LOG_I( "mix->ci_frame_id = 0x%08x\n",
375 mix->ci_frame_id);
376 LOG_I( "mix->ci_frame_num = %d\n",
377 mix->ci_frame_num);
378 LOG_I( "mix->drawable = 0x%08x\n",
379 mix->drawable);
380 LOG_I( "mix->need_display = %d\n",
381 mix->need_display);
382 LOG_I( "mix->va_format = %d\n",
383 mix->va_format);
384 LOG_I( "mix->va_profile = %d\n",
385 mix->va_profile);
386 LOG_I( "mix->va_rcmode = %d\n\n",
387 mix->va_rcmode);
388
389 g_mutex_unlock(mix->objectlock);
390
391 LOG_V( "end\n");
392
393 return MIX_RESULT_SUCCESS;
394 }
395
mix_videofmtenc_encode_default(MixVideoFormatEnc * mix,MixBuffer * bufin[],gint bufincnt,MixIOVec * iovout[],gint iovoutcnt,MixVideoEncodeParams * encode_params)396 static MIX_RESULT mix_videofmtenc_encode_default (MixVideoFormatEnc *mix, MixBuffer * bufin[],
397 gint bufincnt, MixIOVec * iovout[], gint iovoutcnt,
398 MixVideoEncodeParams * encode_params) {
399 return MIX_RESULT_SUCCESS;
400 }
401
mix_videofmtenc_flush_default(MixVideoFormatEnc * mix)402 static MIX_RESULT mix_videofmtenc_flush_default(MixVideoFormatEnc *mix) {
403 return MIX_RESULT_SUCCESS;
404 }
405
mix_videofmtenc_eos_default(MixVideoFormatEnc * mix)406 static MIX_RESULT mix_videofmtenc_eos_default(MixVideoFormatEnc *mix) {
407 return MIX_RESULT_SUCCESS;
408 }
409
mix_videofmtenc_deinitialize_default(MixVideoFormatEnc * mix)410 static MIX_RESULT mix_videofmtenc_deinitialize_default(MixVideoFormatEnc *mix) {
411
412 //TODO decide whether to put any of the teardown from _finalize() here
413
414 return MIX_RESULT_SUCCESS;
415 }
416
mix_videofmtenc_get_max_coded_buffer_size_default(MixVideoFormatEnc * mix,guint * max_size)417 static MIX_RESULT mix_videofmtenc_get_max_coded_buffer_size_default(
418 MixVideoFormatEnc *mix, guint *max_size) {
419
420
421 return MIX_RESULT_SUCCESS;
422 }
423
424 /* mixvideoformatenc class methods implementation */
425
mix_videofmtenc_getcaps(MixVideoFormatEnc * mix,GString * msg)426 MIX_RESULT mix_videofmtenc_getcaps(MixVideoFormatEnc *mix, GString *msg) {
427 MixVideoFormatEncClass *klass = MIX_VIDEOFORMATENC_GET_CLASS(mix);
428
429 LOG_V( "Begin\n");
430
431 if (klass->getcaps) {
432 return klass->getcaps(mix, msg);
433 }
434 return MIX_RESULT_NOTIMPL;
435 }
436
mix_videofmtenc_initialize(MixVideoFormatEnc * mix,MixVideoConfigParamsEnc * config_params_enc,MixFrameManager * frame_mgr,MixBufferPool * input_buf_pool,MixSurfacePool ** surface_pool,VADisplay va_display)437 MIX_RESULT mix_videofmtenc_initialize(MixVideoFormatEnc *mix,
438 MixVideoConfigParamsEnc * config_params_enc,
439 MixFrameManager * frame_mgr,
440 MixBufferPool * input_buf_pool,
441 MixSurfacePool ** surface_pool,
442 VADisplay va_display) {
443 MixVideoFormatEncClass *klass = MIX_VIDEOFORMATENC_GET_CLASS(mix);
444
445 /*frame_mgr and input_buf_pool is reserved for future use*/
446 if (klass->initialize) {
447 return klass->initialize(mix, config_params_enc, frame_mgr,
448 input_buf_pool, surface_pool, va_display);
449 }
450
451 return MIX_RESULT_FAIL;
452
453 }
454
mix_videofmtenc_encode(MixVideoFormatEnc * mix,MixBuffer * bufin[],gint bufincnt,MixIOVec * iovout[],gint iovoutcnt,MixVideoEncodeParams * encode_params)455 MIX_RESULT mix_videofmtenc_encode(MixVideoFormatEnc *mix, MixBuffer * bufin[],
456 gint bufincnt, MixIOVec * iovout[], gint iovoutcnt,
457 MixVideoEncodeParams * encode_params) {
458
459 MixVideoFormatEncClass *klass = MIX_VIDEOFORMATENC_GET_CLASS(mix);
460 if (klass->encode) {
461 return klass->encode(mix, bufin, bufincnt, iovout, iovoutcnt, encode_params);
462 }
463
464 return MIX_RESULT_FAIL;
465 }
466
mix_videofmtenc_flush(MixVideoFormatEnc * mix)467 MIX_RESULT mix_videofmtenc_flush(MixVideoFormatEnc *mix) {
468 MixVideoFormatEncClass *klass = MIX_VIDEOFORMATENC_GET_CLASS(mix);
469 if (klass->flush) {
470 return klass->flush(mix);
471 }
472
473 return MIX_RESULT_FAIL;
474 }
475
mix_videofmtenc_eos(MixVideoFormatEnc * mix)476 MIX_RESULT mix_videofmtenc_eos(MixVideoFormatEnc *mix) {
477 MixVideoFormatEncClass *klass = MIX_VIDEOFORMATENC_GET_CLASS(mix);
478 if (klass->eos) {
479 return klass->eos(mix);
480 }
481
482 return MIX_RESULT_FAIL;
483 }
484
mix_videofmtenc_deinitialize(MixVideoFormatEnc * mix)485 MIX_RESULT mix_videofmtenc_deinitialize(MixVideoFormatEnc *mix) {
486 MixVideoFormatEncClass *klass = MIX_VIDEOFORMATENC_GET_CLASS(mix);
487 if (klass->deinitialize) {
488 return klass->deinitialize(mix);
489 }
490
491 return MIX_RESULT_FAIL;
492 }
493
mix_videofmtenc_get_max_coded_buffer_size(MixVideoFormatEnc * mix,guint * max_size)494 MIX_RESULT mix_videofmtenc_get_max_coded_buffer_size(MixVideoFormatEnc *mix, guint * max_size) {
495
496 MixVideoFormatEncClass *klass = MIX_VIDEOFORMATENC_GET_CLASS(mix);
497 if (klass->encode) {
498 return klass->getmaxencodedbufsize(mix, max_size);
499 }
500
501 return MIX_RESULT_FAIL;
502 }
503