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 Intels 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 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 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 * 97 mix_videoformatenc_new(void) { 98 MixVideoFormatEnc *ret = g_object_new(MIX_TYPE_VIDEOFORMATENC, NULL); 99 100 return ret; 101 } 102 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 * 156 mix_videoformatenc_ref(MixVideoFormatEnc * mix) { 157 return (MixVideoFormatEnc *) g_object_ref(G_OBJECT(mix)); 158 } 159 160 /* Default vmethods implementation */ 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 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 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 402 static MIX_RESULT mix_videofmtenc_flush_default(MixVideoFormatEnc *mix) { 403 return MIX_RESULT_SUCCESS; 404 } 405 406 static MIX_RESULT mix_videofmtenc_eos_default(MixVideoFormatEnc *mix) { 407 return MIX_RESULT_SUCCESS; 408 } 409 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 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 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 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 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 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 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 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 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