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