mp4enc_api.cpp revision b62a73b860757143d3b140b2985fdae71e18d675
1/* ------------------------------------------------------------------ 2 * Copyright (C) 1998-2009 PacketVideo 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 13 * express or implied. 14 * See the License for the specific language governing permissions 15 * and limitations under the License. 16 * ------------------------------------------------------------------- 17 */ 18 19#include "mp4enc_lib.h" 20#include "bitstream_io.h" 21#include "rate_control.h" 22#include "m4venc_oscl.h" 23 24 25/* Inverse normal zigzag */ 26const static Int zigzag_i[NCOEFF_BLOCK] = 27{ 28 0, 1, 8, 16, 9, 2, 3, 10, 29 17, 24, 32, 25, 18, 11, 4, 5, 30 12, 19, 26, 33, 40, 48, 41, 34, 31 27, 20, 13, 6, 7, 14, 21, 28, 32 35, 42, 49, 56, 57, 50, 43, 36, 33 29, 22, 15, 23, 30, 37, 44, 51, 34 58, 59, 52, 45, 38, 31, 39, 46, 35 53, 60, 61, 54, 47, 55, 62, 63 36}; 37 38/* INTRA */ 39const static Int mpeg_iqmat_def[NCOEFF_BLOCK] = 40 { 8, 17, 18, 19, 21, 23, 25, 27, 41 17, 18, 19, 21, 23, 25, 27, 28, 42 20, 21, 22, 23, 24, 26, 28, 30, 43 21, 22, 23, 24, 26, 28, 30, 32, 44 22, 23, 24, 26, 28, 30, 32, 35, 45 23, 24, 26, 28, 30, 32, 35, 38, 46 25, 26, 28, 30, 32, 35, 38, 41, 47 27, 28, 30, 32, 35, 38, 41, 45 48 }; 49 50/* INTER */ 51const static Int mpeg_nqmat_def[64] = 52 { 16, 17, 18, 19, 20, 21, 22, 23, 53 17, 18, 19, 20, 21, 22, 23, 24, 54 18, 19, 20, 21, 22, 23, 24, 25, 55 19, 20, 21, 22, 23, 24, 26, 27, 56 20, 21, 22, 23, 25, 26, 27, 28, 57 21, 22, 23, 24, 26, 27, 28, 30, 58 22, 23, 24, 26, 27, 28, 30, 31, 59 23, 24, 25, 27, 28, 30, 31, 33 60 }; 61 62/* Profiles and levels */ 63/* Simple profile(level 0-3) and Core profile (level 1-2) */ 64/* {SPL0, SPL1, SPL2, SPL3, CPL1, CPL2, CPL2, CPL2} , SPL0: Simple Profile@Level0, CPL1: Core Profile@Level1, the last two are redundant for easy table manipulation */ 65const static Int profile_level_code[8] = 66{ 67 0x08, 0x01, 0x02, 0x03, 0x21, 0x22, 0x22, 0x22 68}; 69 70const static Int profile_level_max_bitrate[8] = 71{ 72 64000, 64000, 128000, 384000, 384000, 2000000, 2000000, 2000000 73}; 74 75const static Int profile_level_max_packet_size[8] = 76{ 77 2048, 2048, 4096, 8192, 4096, 8192, 8192, 8192 78}; 79 80const static Int profile_level_max_mbsPerSec[8] = 81{ 82 1485, 1485, 5940, 11880, 5940, 23760, 23760, 23760 83}; 84 85const static Int profile_level_max_VBV_size[8] = 86{ 87 163840, 163840, 655360, 655360, 262144, 1310720, 1310720, 1310720 88}; 89 90 91/* Simple scalable profile (level 0-2) and Core scalable profile (level 1-3) */ 92/* {SSPL0, SSPL1, SSPL2, SSPL2, CSPL1, CSPL2, CSPL3, CSPL3} , SSPL0: Simple Scalable Profile@Level0, CSPL1: Core Scalable Profile@Level1, the fourth is redundant for easy table manipulation */ 93 94const static Int scalable_profile_level_code[8] = 95{ 96 0x10, 0x11, 0x12, 0x12, 0xA1, 0xA2, 0xA3, 0xA3 97}; 98 99const static Int scalable_profile_level_max_bitrate[8] = 100{ 101 128000, 128000, 256000, 256000, 768000, 1500000, 4000000, 4000000 102}; 103 104/* in bits */ 105const static Int scalable_profile_level_max_packet_size[8] = 106{ 107 2048, 2048, 4096, 4096, 4096, 4096, 16384, 16384 108}; 109 110const static Int scalable_profile_level_max_mbsPerSec[8] = 111{ 112 1485, 7425, 23760, 23760, 14850, 29700, 120960, 120960 113}; 114 115const static Int scalable_profile_level_max_VBV_size[8] = 116{ 117 163840, 655360, 655360, 655360, 1048576, 1310720, 1310720, 1310720 118}; 119 120 121/* H263 profile 0 @ level 10-70 */ 122const static Int h263Level[8] = {0, 10, 20, 30, 40, 50, 60, 70}; 123const static float rBR_bound[8] = {0, 1, 2, 6, 32, 64, 128, 256}; 124const static float max_h263_framerate[2] = {(float)30000 / (float)2002, 125 (float)30000 / (float)1001 126 }; 127const static Int max_h263_width[2] = {176, 352}; 128const static Int max_h263_height[2] = {144, 288}; 129 130/* 6/2/2001, newly added functions to make PVEncodeVop more readable. */ 131Int DetermineCodingLayer(VideoEncData *video, Int *nLayer, ULong modTime); 132void DetermineVopType(VideoEncData *video, Int currLayer); 133Int UpdateSkipNextFrame(VideoEncData *video, ULong *modTime, Int *size, PV_STATUS status); 134Bool SetProfile_BufferSize(VideoEncData *video, float delay, Int bInitialized); 135 136#ifdef PRINT_RC_INFO 137extern FILE *facct; 138extern int tiTotalNumBitsGenerated; 139extern int iStuffBits; 140#endif 141 142#ifdef PRINT_EC 143extern FILE *fec; 144#endif 145 146 147/* ======================================================================== */ 148/* Function : PVGetDefaultEncOption() */ 149/* Date : 12/12/2005 */ 150/* Purpose : */ 151/* In/out : */ 152/* Return : PV_TRUE if successed, PV_FALSE if failed. */ 153/* Modified : */ 154/* */ 155/* ======================================================================== */ 156 157OSCL_EXPORT_REF Bool PVGetDefaultEncOption(VideoEncOptions *encOption, Int encUseCase) 158{ 159 VideoEncOptions defaultUseCase = {H263_MODE, profile_level_max_packet_size[SIMPLE_PROFILE_LEVEL0] >> 3, 160 SIMPLE_PROFILE_LEVEL0, PV_OFF, 0, 1, 1000, 33, {144, 144}, {176, 176}, {15, 30}, {64000, 128000}, 161 {10, 10}, {12, 12}, {0, 0}, CBR_1, 0.0, PV_OFF, -1, 0, PV_OFF, 16, PV_OFF, 0, PV_ON 162 }; 163 164 OSCL_UNUSED_ARG(encUseCase); // unused for now. Later we can add more defaults setting and use this 165 // argument to select the right one. 166 /* in the future we can create more meaningful use-cases */ 167 if (encOption == NULL) 168 { 169 return PV_FALSE; 170 } 171 172 M4VENC_MEMCPY(encOption, &defaultUseCase, sizeof(VideoEncOptions)); 173 174 return PV_TRUE; 175} 176 177/* ======================================================================== */ 178/* Function : PVInitVideoEncoder() */ 179/* Date : 08/22/2000 */ 180/* Purpose : Initialization of MP4 Encoder and VO bitstream */ 181/* In/out : */ 182/* Return : PV_TRUE if successed, PV_FALSE if failed. */ 183/* Modified : 5/21/01, allocate only yChan and assign uChan & vChan */ 184/* 12/12/05, add encoding option as input argument */ 185/* ======================================================================== */ 186OSCL_EXPORT_REF Bool PVInitVideoEncoder(VideoEncControls *encoderControl, VideoEncOptions *encOption) 187{ 188 189 Bool status = PV_TRUE; 190 Int nLayers, idx, i, j; 191 Int max = 0, max_width = 0, max_height = 0, pitch, offset; 192 Int size = 0, nTotalMB = 0; 193 VideoEncData *video; 194 Vol *pVol; 195 VideoEncParams *pEncParams; 196 Int temp_w, temp_h, mbsPerSec; 197 198 /******************************************/ 199 /* this part use to be PVSetEncode() */ 200 Int profile_table_index, *profile_level_table; 201 Int profile_level = encOption->profile_level; 202 Int PacketSize = encOption->packetSize << 3; 203 Int timeInc, timeIncRes; 204 float profile_max_framerate; 205 VideoEncParams *encParams; 206 207 if (encoderControl->videoEncoderData) /* this has been called */ 208 { 209 if (encoderControl->videoEncoderInit) /* check if PVInitVideoEncoder() has been called */ 210 { 211 PVCleanUpVideoEncoder(encoderControl); 212 encoderControl->videoEncoderInit = 0; 213 } 214 215 M4VENC_FREE(encoderControl->videoEncoderData); 216 encoderControl->videoEncoderData = NULL; 217 } 218 encoderControl->videoEncoderInit = 0; /* reset this value */ 219 220 video = (VideoEncData *)M4VENC_MALLOC(sizeof(VideoEncData)); /* allocate memory for encData */ 221 222 if (video == NULL) 223 return PV_FALSE; 224 225 M4VENC_MEMSET(video, 0, sizeof(VideoEncData)); 226 227 encoderControl->videoEncoderData = (void *) video; /* set up pointer in VideoEncData structure */ 228 229 video->encParams = (VideoEncParams *)M4VENC_MALLOC(sizeof(VideoEncParams)); 230 if (video->encParams == NULL) 231 goto CLEAN_UP; 232 233 M4VENC_MEMSET(video->encParams, 0, sizeof(VideoEncParams)); 234 235 encParams = video->encParams; 236 encParams->nLayers = encOption->numLayers; 237 238 /* Check whether the input packetsize is valid (Note: put code here (before any memory allocation) in order to avoid memory leak */ 239 if ((Int)profile_level < (Int)(SIMPLE_SCALABLE_PROFILE_LEVEL0)) /* non-scalable profile */ 240 { 241 profile_level_table = (Int *)profile_level_max_packet_size; 242 profile_table_index = (Int)profile_level; 243 if (encParams->nLayers != 1) 244 { 245 goto CLEAN_UP; 246 } 247 248 encParams->LayerMaxMbsPerSec[0] = profile_level_max_mbsPerSec[profile_table_index]; 249 250 } 251 else /* scalable profile */ 252 { 253 profile_level_table = (Int *)scalable_profile_level_max_packet_size; 254 profile_table_index = (Int)profile_level - (Int)(SIMPLE_SCALABLE_PROFILE_LEVEL0); 255 if (encParams->nLayers < 2) 256 { 257 goto CLEAN_UP; 258 } 259 for (i = 0; i < encParams->nLayers; i++) 260 { 261 encParams->LayerMaxMbsPerSec[i] = scalable_profile_level_max_mbsPerSec[profile_table_index]; 262 } 263 264 } 265 266 /* cannot have zero size packet with these modes */ 267 if (PacketSize == 0) 268 { 269 if (encOption->encMode == DATA_PARTITIONING_MODE) 270 { 271 goto CLEAN_UP; 272 } 273 if (encOption->encMode == COMBINE_MODE_WITH_ERR_RES) 274 { 275 encOption->encMode = COMBINE_MODE_NO_ERR_RES; 276 } 277 } 278 279 if (encOption->gobHeaderInterval == 0) 280 { 281 if (encOption->encMode == H263_MODE_WITH_ERR_RES) 282 { 283 encOption->encMode = H263_MODE; 284 } 285 286 if (encOption->encMode == SHORT_HEADER_WITH_ERR_RES) 287 { 288 encOption->encMode = SHORT_HEADER; 289 } 290 } 291 292 if (PacketSize > profile_level_table[profile_table_index]) 293 goto CLEAN_UP; 294 295 /* Initial Defaults for all Modes */ 296 297 encParams->SequenceStartCode = 1; 298 encParams->GOV_Enabled = 0; 299 encParams->RoundingType = 0; 300 encParams->IntraDCVlcThr = PV_MAX(PV_MIN(encOption->intraDCVlcTh, 7), 0); 301 encParams->ACDCPrediction = ((encOption->useACPred == PV_ON) ? TRUE : FALSE); 302 encParams->RC_Type = encOption->rcType; 303 encParams->Refresh = encOption->numIntraMB; 304 encParams->ResyncMarkerDisable = 0; /* Enable Resync Marker */ 305 306 for (i = 0; i < encOption->numLayers; i++) 307 { 308#ifdef NO_MPEG_QUANT 309 encParams->QuantType[i] = 0; 310#else 311 encParams->QuantType[i] = encOption->quantType[i]; /* H263 */ 312#endif 313 if (encOption->pQuant[i] >= 1 && encOption->pQuant[i] <= 31) 314 { 315 encParams->InitQuantPvop[i] = encOption->pQuant[i]; 316 } 317 else 318 { 319 goto CLEAN_UP; 320 } 321 if (encOption->iQuant[i] >= 1 && encOption->iQuant[i] <= 31) 322 { 323 encParams->InitQuantIvop[i] = encOption->iQuant[i]; 324 } 325 else 326 { 327 goto CLEAN_UP; 328 } 329 } 330 331 encParams->HalfPel_Enabled = 1; 332 encParams->SearchRange = encOption->searchRange; /* 4/16/2001 */ 333 encParams->FullSearch_Enabled = 0; 334#ifdef NO_INTER4V 335 encParams->MV8x8_Enabled = 0; 336#else 337 encParams->MV8x8_Enabled = 0;// comment out for now!! encOption->mv8x8Enable; 338#endif 339 encParams->H263_Enabled = 0; 340 encParams->GOB_Header_Interval = 0; // need to be reset to 0 341 encParams->IntraPeriod = encOption->intraPeriod; /* Intra update period update default*/ 342 encParams->SceneChange_Det = encOption->sceneDetect; 343 encParams->FineFrameSkip_Enabled = 0; 344 encParams->NoFrameSkip_Enabled = encOption->noFrameSkipped; 345 encParams->NoPreSkip_Enabled = encOption->noFrameSkipped; 346 encParams->GetVolHeader[0] = 0; 347 encParams->GetVolHeader[1] = 0; 348 encParams->ResyncPacketsize = encOption->packetSize << 3; 349 encParams->LayerMaxBitRate[0] = 0; 350 encParams->LayerMaxBitRate[1] = 0; 351 encParams->LayerMaxFrameRate[0] = (float)0.0; 352 encParams->LayerMaxFrameRate[1] = (float)0.0; 353 encParams->VBV_delay = encOption->vbvDelay; /* 2sec VBV buffer size */ 354 355 switch (encOption->encMode) 356 { 357 358 case SHORT_HEADER: 359 case SHORT_HEADER_WITH_ERR_RES: 360 361 /* From Table 6-26 */ 362 encParams->nLayers = 1; 363 encParams->QuantType[0] = 0; /*H263 */ 364 encParams->ResyncMarkerDisable = 1; /* Disable Resync Marker */ 365 encParams->DataPartitioning = 0; /* Combined Mode */ 366 encParams->ReversibleVLC = 0; /* Disable RVLC */ 367 encParams->RoundingType = 0; 368 encParams->IntraDCVlcThr = 7; /* use_intra_dc_vlc = 0 */ 369 encParams->MV8x8_Enabled = 0; 370 371 encParams->GOB_Header_Interval = encOption->gobHeaderInterval; 372 encParams->H263_Enabled = 2; 373 encParams->GOV_Enabled = 0; 374 encParams->TimeIncrementRes = 30000; /* timeIncrementRes for H263 */ 375 break; 376 377 case H263_MODE: 378 case H263_MODE_WITH_ERR_RES: 379 380 /* From Table 6-26 */ 381 encParams->nLayers = 1; 382 encParams->QuantType[0] = 0; /*H263 */ 383 encParams->ResyncMarkerDisable = 1; /* Disable Resync Marker */ 384 encParams->DataPartitioning = 0; /* Combined Mode */ 385 encParams->ReversibleVLC = 0; /* Disable RVLC */ 386 encParams->RoundingType = 0; 387 encParams->IntraDCVlcThr = 7; /* use_intra_dc_vlc = 0 */ 388 encParams->MV8x8_Enabled = 0; 389 390 encParams->H263_Enabled = 1; 391 encParams->GOV_Enabled = 0; 392 encParams->TimeIncrementRes = 30000; /* timeIncrementRes for H263 */ 393 394 break; 395#ifndef H263_ONLY 396 case DATA_PARTITIONING_MODE: 397 398 encParams->DataPartitioning = 1; /* Base Layer Data Partitioning */ 399 encParams->ResyncMarkerDisable = 0; /* Resync Marker */ 400#ifdef NO_RVLC 401 encParams->ReversibleVLC = 0; 402#else 403 encParams->ReversibleVLC = (encOption->rvlcEnable == PV_ON); /* RVLC when Data Partitioning */ 404#endif 405 encParams->ResyncPacketsize = PacketSize; 406 break; 407 408 case COMBINE_MODE_WITH_ERR_RES: 409 410 encParams->DataPartitioning = 0; /* Combined Mode */ 411 encParams->ResyncMarkerDisable = 0; /* Resync Marker */ 412 encParams->ReversibleVLC = 0; /* No RVLC */ 413 encParams->ResyncPacketsize = PacketSize; 414 break; 415 416 case COMBINE_MODE_NO_ERR_RES: 417 418 encParams->DataPartitioning = 0; /* Combined Mode */ 419 encParams->ResyncMarkerDisable = 1; /* Disable Resync Marker */ 420 encParams->ReversibleVLC = 0; /* No RVLC */ 421 break; 422#endif 423 default: 424 goto CLEAN_UP; 425 } 426 /* Set the constraints (maximum values) according to the input profile and level */ 427 /* Note that profile_table_index is already figured out above */ 428 429 /* base layer */ 430 encParams->profile_table_index = profile_table_index; /* Used to limit the profile and level in SetProfile_BufferSize() */ 431 432 /* check timeIncRes */ 433 timeIncRes = encOption->timeIncRes; 434 timeInc = encOption->tickPerSrc; 435 436 if ((timeIncRes >= 1) && (timeIncRes <= 65536) && (timeInc < timeIncRes) && (timeInc != 0)) 437 { 438 if (!encParams->H263_Enabled) 439 { 440 encParams->TimeIncrementRes = timeIncRes; 441 } 442 else 443 { 444 encParams->TimeIncrementRes = 30000; 445// video->FrameRate = 30000/(float)1001; /* fix it to 29.97 fps */ 446 } 447 video->FrameRate = timeIncRes / ((float)timeInc); 448 } 449 else 450 { 451 goto CLEAN_UP; 452 } 453 454 /* check frame dimension */ 455 if (encParams->H263_Enabled) 456 { 457 switch (encOption->encWidth[0]) 458 { 459 case 128: 460 if (encOption->encHeight[0] != 96) /* source_format = 1 */ 461 goto CLEAN_UP; 462 break; 463 case 176: 464 if (encOption->encHeight[0] != 144) /* source_format = 2 */ 465 goto CLEAN_UP; 466 break; 467 case 352: 468 if (encOption->encHeight[0] != 288) /* source_format = 2 */ 469 goto CLEAN_UP; 470 break; 471 472 case 704: 473 if (encOption->encHeight[0] != 576) /* source_format = 2 */ 474 goto CLEAN_UP; 475 break; 476 case 1408: 477 if (encOption->encHeight[0] != 1152) /* source_format = 2 */ 478 goto CLEAN_UP; 479 break; 480 481 default: 482 goto CLEAN_UP; 483 } 484 } 485 for (i = 0; i < encParams->nLayers; i++) 486 { 487 encParams->LayerHeight[i] = encOption->encHeight[i]; 488 encParams->LayerWidth[i] = encOption->encWidth[i]; 489 } 490 491 /* check frame rate */ 492 for (i = 0; i < encParams->nLayers; i++) 493 { 494 encParams->LayerFrameRate[i] = encOption->encFrameRate[i]; 495 } 496 497 if (encParams->nLayers > 1) 498 { 499 if (encOption->encFrameRate[0] == encOption->encFrameRate[1] || 500 encOption->encFrameRate[0] == 0. || encOption->encFrameRate[1] == 0.) /* 7/31/03 */ 501 goto CLEAN_UP; 502 } 503 /* set max frame rate */ 504 for (i = 0; i < encParams->nLayers; i++) 505 { 506 507 /* Make sure the maximum framerate is consistent with the given profile and level */ 508 nTotalMB = ((encParams->LayerWidth[i] + 15) / 16) * ((encParams->LayerHeight[i] + 15) / 16); 509 510 if (nTotalMB > 0) 511 profile_max_framerate = (float)encParams->LayerMaxMbsPerSec[i] / (float)nTotalMB; 512 513 else 514 profile_max_framerate = (float)30.0; 515 516 encParams->LayerMaxFrameRate[i] = PV_MIN(profile_max_framerate, encParams->LayerFrameRate[i]); 517 } 518 519 /* check bit rate */ 520 /* set max bit rate */ 521 for (i = 0; i < encParams->nLayers; i++) 522 { 523 encParams->LayerBitRate[i] = encOption->bitRate[i]; 524 encParams->LayerMaxBitRate[i] = encOption->bitRate[i]; 525 } 526 if (encParams->nLayers > 1) 527 { 528 if (encOption->bitRate[0] == encOption->bitRate[1] || 529 encOption->bitRate[0] == 0 || encOption->bitRate[1] == 0) /* 7/31/03 */ 530 goto CLEAN_UP; 531 } 532 /* check rate control and vbv delay*/ 533 encParams->RC_Type = encOption->rcType; 534 535 if (encOption->vbvDelay == 0.0) /* set to default */ 536 { 537 switch (encOption->rcType) 538 { 539 case CBR_1: 540 case CBR_2: 541 encParams->VBV_delay = (float)2.0; /* default 2sec VBV buffer size */ 542 break; 543 544 case CBR_LOWDELAY: 545 encParams->VBV_delay = (float)0.5; /* default 0.5sec VBV buffer size */ 546 break; 547 548 case VBR_1: 549 case VBR_2: 550 encParams->VBV_delay = (float)10.0; /* default 10sec VBV buffer size */ 551 break; 552 default: 553 break; 554 } 555 } 556 else /* force this value */ 557 { 558 encParams->VBV_delay = encOption->vbvDelay; 559 } 560 561 /* check search range */ 562 if (encParams->H263_Enabled && encOption->searchRange > 16) 563 { 564 encParams->SearchRange = 16; /* 4/16/2001 */ 565 } 566 567 /*****************************************/ 568 /* checking for conflict between options */ 569 /*****************************************/ 570 571 if (video->encParams->RC_Type == CBR_1 || video->encParams->RC_Type == CBR_2 || video->encParams->RC_Type == CBR_LOWDELAY) /* if CBR */ 572 { 573#ifdef _PRINT_STAT 574 if (video->encParams->NoFrameSkip_Enabled == PV_ON || 575 video->encParams->NoPreSkip_Enabled == PV_ON) /* don't allow frame skip*/ 576 printf("WARNING!!!! CBR with NoFrameSkip\n"); 577#endif 578 } 579 else if (video->encParams->RC_Type == CONSTANT_Q) /* constant_Q */ 580 { 581 video->encParams->NoFrameSkip_Enabled = PV_ON; /* no frame skip */ 582 video->encParams->NoPreSkip_Enabled = PV_ON; /* no frame skip */ 583#ifdef _PRINT_STAT 584 printf("Turn on NoFrameSkip\n"); 585#endif 586 } 587 588 if (video->encParams->NoFrameSkip_Enabled == PV_ON) /* if no frame skip */ 589 { 590 video->encParams->FineFrameSkip_Enabled = PV_OFF; 591#ifdef _PRINT_STAT 592 printf("NoFrameSkip !!! may violate VBV_BUFFER constraint.\n"); 593 printf("Turn off FineFrameSkip\n"); 594#endif 595 } 596 597 /******************************************/ 598 /******************************************/ 599 600 nLayers = video->encParams->nLayers; /* Number of Layers to be encoded */ 601 602 /* Find the maximum width*height for memory allocation of the VOPs */ 603 for (idx = 0; idx < nLayers; idx++) 604 { 605 temp_w = video->encParams->LayerWidth[idx]; 606 temp_h = video->encParams->LayerHeight[idx]; 607 608 if ((temp_w*temp_h) > max) 609 { 610 max = temp_w * temp_h; 611 max_width = ((temp_w + 15) >> 4) << 4; 612 max_height = ((temp_h + 15) >> 4) << 4; 613 if (((uint64_t)max_width * max_height) > (uint64_t)INT32_MAX 614 || temp_w > INT32_MAX - 15 || temp_h > INT32_MAX - 15) { 615 goto CLEAN_UP; 616 } 617 nTotalMB = ((max_width * max_height) >> 8); 618 } 619 620 /* Check if the video size and framerate(MBsPerSec) are vald */ 621 mbsPerSec = (Int)(nTotalMB * video->encParams->LayerFrameRate[idx]); 622 if (mbsPerSec > video->encParams->LayerMaxMbsPerSec[idx]) status = PV_FALSE; 623 } 624 625 /****************************************************/ 626 /* Set Profile and Video Buffer Size for each layer */ 627 /****************************************************/ 628 if (video->encParams->RC_Type == CBR_LOWDELAY) video->encParams->VBV_delay = 0.5; /* For CBR_LOWDELAY, we set 0.5sec buffer */ 629 status = SetProfile_BufferSize(video, video->encParams->VBV_delay, 1); 630 if (status != PV_TRUE) 631 goto CLEAN_UP; 632 633 /****************************************/ 634 /* memory allocation and initialization */ 635 /****************************************/ 636 637 if (video == NULL) goto CLEAN_UP; 638 639 /* cyclic reference for passing through both structures */ 640 video->videoEncControls = encoderControl; 641 642 //video->currLayer = 0; /* Set current Layer to 0 */ 643 //video->currFrameNo = 0; /* Set current frame Number to 0 */ 644 video->nextModTime = 0; 645 video->nextEncIVop = 0; /* Sets up very first frame to be I-VOP! */ 646 video->numVopsInGOP = 0; /* counter for Vops in Gop, 2/8/01 */ 647 648 //video->frameRate = video->encParams->LayerFrameRate[0]; /* Set current layer frame rate */ 649 650 video->QPMB = (UChar *) M4VENC_MALLOC(nTotalMB * sizeof(UChar)); /* Memory for MB quantizers */ 651 if (video->QPMB == NULL) goto CLEAN_UP; 652 653 654 video->headerInfo.Mode = (UChar *) M4VENC_MALLOC(sizeof(UChar) * nTotalMB); /* Memory for MB Modes */ 655 if (video->headerInfo.Mode == NULL) goto CLEAN_UP; 656 video->headerInfo.CBP = (UChar *) M4VENC_MALLOC(sizeof(UChar) * nTotalMB); /* Memory for CBP (Y and C) of each MB */ 657 if (video->headerInfo.CBP == NULL) goto CLEAN_UP; 658 659 /* Allocating motion vector space and interpolation memory*/ 660 661 if ((size_t)nTotalMB > SIZE_MAX / sizeof(MOT *)) { 662 goto CLEAN_UP; 663 } 664 video->mot = (MOT **)M4VENC_MALLOC(sizeof(MOT *) * nTotalMB); 665 if (video->mot == NULL) goto CLEAN_UP; 666 667 for (idx = 0; idx < nTotalMB; idx++) 668 { 669 video->mot[idx] = (MOT *)M4VENC_MALLOC(sizeof(MOT) * 8); 670 if (video->mot[idx] == NULL) 671 { 672 goto CLEAN_UP; 673 } 674 } 675 676 video->intraArray = (UChar *)M4VENC_MALLOC(sizeof(UChar) * nTotalMB); 677 if (video->intraArray == NULL) goto CLEAN_UP; 678 679 video->sliceNo = (UChar *) M4VENC_MALLOC(nTotalMB); /* Memory for Slice Numbers */ 680 if (video->sliceNo == NULL) goto CLEAN_UP; 681 /* Allocating space for predDCAC[][8][16], Not that I intentionally */ 682 /* increase the dimension of predDCAC from [][6][15] to [][8][16] */ 683 /* so that compilers can generate faster code to indexing the */ 684 /* data inside (by using << instead of *). 04/14/2000. */ 685 /* 5/29/01, use decoder lib ACDC prediction memory scheme. */ 686 if ((size_t)nTotalMB > SIZE_MAX / sizeof(typeDCStore)) { 687 goto CLEAN_UP; 688 } 689 video->predDC = (typeDCStore *) M4VENC_MALLOC(nTotalMB * sizeof(typeDCStore)); 690 if (video->predDC == NULL) goto CLEAN_UP; 691 692 if (!video->encParams->H263_Enabled) 693 { 694 if ((size_t)((max_width >> 4) + 1) > SIZE_MAX / sizeof(typeDCACStore)) { 695 goto CLEAN_UP; 696 } 697 video->predDCAC_col = (typeDCACStore *) M4VENC_MALLOC(((max_width >> 4) + 1) * sizeof(typeDCACStore)); 698 if (video->predDCAC_col == NULL) goto CLEAN_UP; 699 700 /* element zero will be used for storing vertical (col) AC coefficients */ 701 /* the rest will be used for storing horizontal (row) AC coefficients */ 702 video->predDCAC_row = video->predDCAC_col + 1; /* ACDC */ 703 704 if ((size_t)nTotalMB > SIZE_MAX / sizeof(Int)) { 705 goto CLEAN_UP; 706 } 707 video->acPredFlag = (Int *) M4VENC_MALLOC(nTotalMB * sizeof(Int)); /* Memory for acPredFlag */ 708 if (video->acPredFlag == NULL) goto CLEAN_UP; 709 } 710 711 video->outputMB = (MacroBlock *) M4VENC_MALLOC(sizeof(MacroBlock)); /* Allocating macroblock space */ 712 if (video->outputMB == NULL) goto CLEAN_UP; 713 M4VENC_MEMSET(video->outputMB->block[0], 0, (sizeof(Short) << 6)*6); 714 715 M4VENC_MEMSET(video->dataBlock, 0, sizeof(Short) << 7); 716 /* Allocate (2*packetsize) working bitstreams */ 717 718 video->bitstream1 = BitStreamCreateEnc(2 * 4096); /*allocate working stream 1*/ 719 if (video->bitstream1 == NULL) goto CLEAN_UP; 720 video->bitstream2 = BitStreamCreateEnc(2 * 4096); /*allocate working stream 2*/ 721 if (video->bitstream2 == NULL) goto CLEAN_UP; 722 video->bitstream3 = BitStreamCreateEnc(2 * 4096); /*allocate working stream 3*/ 723 if (video->bitstream3 == NULL) goto CLEAN_UP; 724 725 /* allocate overrun buffer */ 726 // this buffer is used when user's buffer is too small to hold one frame. 727 // It is not needed for slice-based encoding. 728 if (nLayers == 1) 729 { 730 video->oBSize = encParams->BufferSize[0] >> 3; 731 } 732 else 733 { 734 video->oBSize = PV_MAX((encParams->BufferSize[0] >> 3), (encParams->BufferSize[1] >> 3)); 735 } 736 737 if (video->oBSize > DEFAULT_OVERRUN_BUFFER_SIZE || encParams->RC_Type == CONSTANT_Q) // set limit 738 { 739 video->oBSize = DEFAULT_OVERRUN_BUFFER_SIZE; 740 } 741 video->overrunBuffer = (UChar*) M4VENC_MALLOC(sizeof(UChar) * video->oBSize); 742 if (video->overrunBuffer == NULL) goto CLEAN_UP; 743 744 745 video->currVop = (Vop *) M4VENC_MALLOC(sizeof(Vop)); /* Memory for Current VOP */ 746 if (video->currVop == NULL) goto CLEAN_UP; 747 748 /* add padding, 09/19/05 */ 749 if (video->encParams->H263_Enabled) /* make it conditional 11/28/05 */ 750 { 751 pitch = max_width; 752 offset = 0; 753 } 754 else 755 { 756 pitch = max_width + 32; 757 offset = (pitch << 4) + 16; 758 max_height += 32; 759 } 760 if (((uint64_t)pitch * max_height) > (uint64_t)INT32_MAX) { 761 goto CLEAN_UP; 762 } 763 size = pitch * max_height; 764 765 if (size > INT32_MAX - (size >> 1) 766 || (size_t)(size + (size >> 1)) > SIZE_MAX / sizeof(PIXEL)) { 767 goto CLEAN_UP; 768 } 769 video->currVop->yChan = (PIXEL *)M4VENC_MALLOC(sizeof(PIXEL) * (size + (size >> 1))); /* Memory for currVop Y */ 770 if (video->currVop->yChan == NULL) goto CLEAN_UP; 771 video->currVop->uChan = video->currVop->yChan + size;/* Memory for currVop U */ 772 video->currVop->vChan = video->currVop->uChan + (size >> 2);/* Memory for currVop V */ 773 774 /* shift for the offset */ 775 if (offset) 776 { 777 video->currVop->yChan += offset; /* offset to the origin.*/ 778 video->currVop->uChan += (offset >> 2) + 4; 779 video->currVop->vChan += (offset >> 2) + 4; 780 } 781 782 video->forwardRefVop = video->currVop; /* Initialize forwardRefVop */ 783 video->backwardRefVop = video->currVop; /* Initialize backwardRefVop */ 784 785 video->prevBaseVop = (Vop *) M4VENC_MALLOC(sizeof(Vop)); /* Memory for Previous Base Vop */ 786 if (video->prevBaseVop == NULL) goto CLEAN_UP; 787 video->prevBaseVop->yChan = (PIXEL *) M4VENC_MALLOC(sizeof(PIXEL) * (size + (size >> 1))); /* Memory for prevBaseVop Y */ 788 if (video->prevBaseVop->yChan == NULL) goto CLEAN_UP; 789 video->prevBaseVop->uChan = video->prevBaseVop->yChan + size; /* Memory for prevBaseVop U */ 790 video->prevBaseVop->vChan = video->prevBaseVop->uChan + (size >> 2); /* Memory for prevBaseVop V */ 791 792 if (offset) 793 { 794 video->prevBaseVop->yChan += offset; /* offset to the origin.*/ 795 video->prevBaseVop->uChan += (offset >> 2) + 4; 796 video->prevBaseVop->vChan += (offset >> 2) + 4; 797 } 798 799 800 if (0) /* If B Frames */ 801 { 802 video->nextBaseVop = (Vop *) M4VENC_MALLOC(sizeof(Vop)); /* Memory for Next Base Vop */ 803 if (video->nextBaseVop == NULL) goto CLEAN_UP; 804 video->nextBaseVop->yChan = (PIXEL *) M4VENC_MALLOC(sizeof(PIXEL) * (size + (size >> 1))); /* Memory for nextBaseVop Y */ 805 if (video->nextBaseVop->yChan == NULL) goto CLEAN_UP; 806 video->nextBaseVop->uChan = video->nextBaseVop->yChan + size; /* Memory for nextBaseVop U */ 807 video->nextBaseVop->vChan = video->nextBaseVop->uChan + (size >> 2); /* Memory for nextBaseVop V */ 808 809 if (offset) 810 { 811 video->nextBaseVop->yChan += offset; /* offset to the origin.*/ 812 video->nextBaseVop->uChan += (offset >> 2) + 4; 813 video->nextBaseVop->vChan += (offset >> 2) + 4; 814 } 815 } 816 817 if (nLayers > 1) /* If enhancement layers */ 818 { 819 video->prevEnhanceVop = (Vop *) M4VENC_MALLOC(sizeof(Vop)); /* Memory for Previous Enhancement Vop */ 820 if (video->prevEnhanceVop == NULL) goto CLEAN_UP; 821 video->prevEnhanceVop->yChan = (PIXEL *) M4VENC_MALLOC(sizeof(PIXEL) * (size + (size >> 1))); /* Memory for Previous Ehancement Y */ 822 if (video->prevEnhanceVop->yChan == NULL) goto CLEAN_UP; 823 video->prevEnhanceVop->uChan = video->prevEnhanceVop->yChan + size; /* Memory for Previous Enhancement U */ 824 video->prevEnhanceVop->vChan = video->prevEnhanceVop->uChan + (size >> 2); /* Memory for Previous Enhancement V */ 825 826 if (offset) 827 { 828 video->prevEnhanceVop->yChan += offset; /* offset to the origin.*/ 829 video->prevEnhanceVop->uChan += (offset >> 2) + 4; 830 video->prevEnhanceVop->vChan += (offset >> 2) + 4; 831 } 832 } 833 834 video->numberOfLayers = nLayers; /* Number of Layers */ 835 video->sumMAD = 0; 836 837 838 /* 04/09/01, for Vops in the use multipass processing */ 839 for (idx = 0; idx < nLayers; idx++) 840 { 841 video->pMP[idx] = (MultiPass *)M4VENC_MALLOC(sizeof(MultiPass)); 842 if (video->pMP[idx] == NULL) goto CLEAN_UP; 843 M4VENC_MEMSET(video->pMP[idx], 0, sizeof(MultiPass)); 844 845 video->pMP[idx]->encoded_frames = -1; /* forget about the very first I frame */ 846 847 848 /* RDInfo **pRDSamples */ 849 video->pMP[idx]->pRDSamples = (RDInfo **)M4VENC_MALLOC(30 * sizeof(RDInfo *)); 850 if (video->pMP[idx]->pRDSamples == NULL) goto CLEAN_UP; 851 for (i = 0; i < 30; i++) 852 { 853 video->pMP[idx]->pRDSamples[i] = (RDInfo *)M4VENC_MALLOC(32 * sizeof(RDInfo)); 854 if (video->pMP[idx]->pRDSamples[i] == NULL) goto CLEAN_UP; 855 for (j = 0; j < 32; j++) M4VENC_MEMSET(&(video->pMP[idx]->pRDSamples[i][j]), 0, sizeof(RDInfo)); 856 } 857 video->pMP[idx]->frameRange = (Int)(video->encParams->LayerFrameRate[idx] * 1.0); /* 1.0s time frame*/ 858 video->pMP[idx]->frameRange = PV_MAX(video->pMP[idx]->frameRange, 5); 859 video->pMP[idx]->frameRange = PV_MIN(video->pMP[idx]->frameRange, 30); 860 861 video->pMP[idx]->framePos = -1; 862 863 } 864 /* /// End /////////////////////////////////////// */ 865 866 867 if ((size_t)nLayers > SIZE_MAX / sizeof(Vol *)) { 868 goto CLEAN_UP; 869 } 870 video->vol = (Vol **)M4VENC_MALLOC(nLayers * sizeof(Vol *)); /* Memory for VOL pointers */ 871 872 /* Memory allocation and Initialization of Vols and writing of headers */ 873 if (video->vol == NULL) goto CLEAN_UP; 874 875 for (idx = 0; idx < nLayers; idx++) 876 { 877 video->volInitialize[idx] = 1; 878 video->refTick[idx] = 0; 879 video->relLayerCodeTime[idx] = 1000; 880 video->vol[idx] = (Vol *)M4VENC_MALLOC(sizeof(Vol)); 881 if (video->vol[idx] == NULL) goto CLEAN_UP; 882 883 pVol = video->vol[idx]; 884 pEncParams = video->encParams; 885 886 M4VENC_MEMSET(video->vol[idx], 0, sizeof(Vol)); 887 /* Initialize some VOL parameters */ 888 pVol->volID = idx; /* Set VOL ID */ 889 pVol->shortVideoHeader = pEncParams->H263_Enabled; /*Short Header */ 890 pVol->GOVStart = pEncParams->GOV_Enabled; /* GOV Header */ 891 pVol->timeIncrementResolution = video->encParams->TimeIncrementRes; 892 pVol->nbitsTimeIncRes = 1; 893 while (pVol->timeIncrementResolution > (1 << pVol->nbitsTimeIncRes)) 894 { 895 pVol->nbitsTimeIncRes++; 896 } 897 898 /* timing stuff */ 899 pVol->timeIncrement = 0; 900 pVol->moduloTimeBase = 0; 901 pVol->fixedVopRate = 0; /* No fixed VOP rate */ 902 pVol->stream = (BitstreamEncVideo *)M4VENC_MALLOC(sizeof(BitstreamEncVideo)); /* allocate BitstreamEncVideo Instance */ 903 if (pVol->stream == NULL) goto CLEAN_UP; 904 905 pVol->width = pEncParams->LayerWidth[idx]; /* Layer Width */ 906 pVol->height = pEncParams->LayerHeight[idx]; /* Layer Height */ 907 // pVol->intra_acdcPredDisable = pEncParams->ACDCPrediction; /* ACDC Prediction */ 908 pVol->ResyncMarkerDisable = pEncParams->ResyncMarkerDisable; /* Resync Marker Mode */ 909 pVol->dataPartitioning = pEncParams->DataPartitioning; /* Data Partitioning */ 910 pVol->useReverseVLC = pEncParams->ReversibleVLC; /* RVLC */ 911 if (idx > 0) /* Scalability layers */ 912 { 913 pVol->ResyncMarkerDisable = 1; 914 pVol->dataPartitioning = 0; 915 pVol->useReverseVLC = 0; /* No RVLC */ 916 } 917 pVol->quantType = pEncParams->QuantType[idx]; /* Quantizer Type */ 918 919 /* no need to init Quant Matrices */ 920 921 pVol->scalability = 0; /* Vol Scalability */ 922 if (idx > 0) 923 pVol->scalability = 1; /* Multiple layers => Scalability */ 924 925 /* Initialize Vol to Temporal scalability. It can change during encoding */ 926 pVol->scalType = 1; 927 /* Initialize reference Vol ID to the base layer = 0 */ 928 pVol->refVolID = 0; 929 /* Initialize layer resolution to same as the reference */ 930 pVol->refSampDir = 0; 931 pVol->horSamp_m = 1; 932 pVol->horSamp_n = 1; 933 pVol->verSamp_m = 1; 934 pVol->verSamp_n = 1; 935 pVol->enhancementType = 0; /* We always enhance the entire region */ 936 937 pVol->nMBPerRow = (pVol->width + 15) / 16; 938 pVol->nMBPerCol = (pVol->height + 15) / 16; 939 pVol->nTotalMB = pVol->nMBPerRow * pVol->nMBPerCol; 940 941 if (pVol->nTotalMB >= 1) 942 pVol->nBitsForMBID = 1; 943 if (pVol->nTotalMB >= 3) 944 pVol->nBitsForMBID = 2; 945 if (pVol->nTotalMB >= 5) 946 pVol->nBitsForMBID = 3; 947 if (pVol->nTotalMB >= 9) 948 pVol->nBitsForMBID = 4; 949 if (pVol->nTotalMB >= 17) 950 pVol->nBitsForMBID = 5; 951 if (pVol->nTotalMB >= 33) 952 pVol->nBitsForMBID = 6; 953 if (pVol->nTotalMB >= 65) 954 pVol->nBitsForMBID = 7; 955 if (pVol->nTotalMB >= 129) 956 pVol->nBitsForMBID = 8; 957 if (pVol->nTotalMB >= 257) 958 pVol->nBitsForMBID = 9; 959 if (pVol->nTotalMB >= 513) 960 pVol->nBitsForMBID = 10; 961 if (pVol->nTotalMB >= 1025) 962 pVol->nBitsForMBID = 11; 963 if (pVol->nTotalMB >= 2049) 964 pVol->nBitsForMBID = 12; 965 if (pVol->nTotalMB >= 4097) 966 pVol->nBitsForMBID = 13; 967 if (pVol->nTotalMB >= 8193) 968 pVol->nBitsForMBID = 14; 969 if (pVol->nTotalMB >= 16385) 970 pVol->nBitsForMBID = 15; 971 if (pVol->nTotalMB >= 32769) 972 pVol->nBitsForMBID = 16; 973 if (pVol->nTotalMB >= 65537) 974 pVol->nBitsForMBID = 17; 975 if (pVol->nTotalMB >= 131073) 976 pVol->nBitsForMBID = 18; 977 978 if (pVol->shortVideoHeader) 979 { 980 switch (pVol->width) 981 { 982 case 128: 983 if (pVol->height == 96) /* source_format = 1 */ 984 { 985 pVol->nGOBinVop = 6; 986 pVol->nMBinGOB = 8; 987 } 988 else 989 status = PV_FALSE; 990 break; 991 992 case 176: 993 if (pVol->height == 144) /* source_format = 2 */ 994 { 995 pVol->nGOBinVop = 9; 996 pVol->nMBinGOB = 11; 997 } 998 else 999 status = PV_FALSE; 1000 break; 1001 case 352: 1002 if (pVol->height == 288) /* source_format = 2 */ 1003 { 1004 pVol->nGOBinVop = 18; 1005 pVol->nMBinGOB = 22; 1006 } 1007 else 1008 status = PV_FALSE; 1009 break; 1010 1011 case 704: 1012 if (pVol->height == 576) /* source_format = 2 */ 1013 { 1014 pVol->nGOBinVop = 18; 1015 pVol->nMBinGOB = 88; 1016 } 1017 else 1018 status = PV_FALSE; 1019 break; 1020 case 1408: 1021 if (pVol->height == 1152) /* source_format = 2 */ 1022 { 1023 pVol->nGOBinVop = 18; 1024 pVol->nMBinGOB = 352; 1025 } 1026 else 1027 status = PV_FALSE; 1028 break; 1029 1030 default: 1031 status = PV_FALSE; 1032 break; 1033 } 1034 } 1035 } 1036 1037 /***************************************************/ 1038 /* allocate and initialize rate control parameters */ 1039 /***************************************************/ 1040 1041 /* BEGIN INITIALIZATION OF ANNEX L RATE CONTROL */ 1042 if (video->encParams->RC_Type != CONSTANT_Q) 1043 { 1044 for (idx = 0; idx < nLayers; idx++) /* 12/25/00 */ 1045 { 1046 video->rc[idx] = 1047 (rateControl *)M4VENC_MALLOC(sizeof(rateControl)); 1048 1049 if (video->rc[idx] == NULL) goto CLEAN_UP; 1050 1051 M4VENC_MEMSET(video->rc[idx], 0, sizeof(rateControl)); 1052 } 1053 if (PV_SUCCESS != RC_Initialize(video)) 1054 { 1055 goto CLEAN_UP; 1056 } 1057 /* initialization for 2-pass rate control */ 1058 } 1059 /* END INITIALIZATION OF ANNEX L RATE CONTROL */ 1060 1061 /********** assign platform dependent functions ***********************/ 1062 /* 1/23/01 */ 1063 /* This must be done at run-time not a compile time */ 1064 video->functionPointer = (FuncPtr*) M4VENC_MALLOC(sizeof(FuncPtr)); 1065 if (video->functionPointer == NULL) goto CLEAN_UP; 1066 1067 video->functionPointer->ComputeMBSum = &ComputeMBSum_C; 1068 video->functionPointer->SAD_MB_HalfPel[0] = NULL; 1069 video->functionPointer->SAD_MB_HalfPel[1] = &SAD_MB_HalfPel_Cxh; 1070 video->functionPointer->SAD_MB_HalfPel[2] = &SAD_MB_HalfPel_Cyh; 1071 video->functionPointer->SAD_MB_HalfPel[3] = &SAD_MB_HalfPel_Cxhyh; 1072 1073#ifndef NO_INTER4V 1074 video->functionPointer->SAD_Blk_HalfPel = &SAD_Blk_HalfPel_C; 1075 video->functionPointer->SAD_Block = &SAD_Block_C; 1076#endif 1077 video->functionPointer->SAD_Macroblock = &SAD_Macroblock_C; 1078 video->functionPointer->ChooseMode = &ChooseMode_C; 1079 video->functionPointer->GetHalfPelMBRegion = &GetHalfPelMBRegion_C; 1080// video->functionPointer->SAD_MB_PADDING = &SAD_MB_PADDING; /* 4/21/01 */ 1081 1082 1083 encoderControl->videoEncoderInit = 1; /* init done! */ 1084 1085 return PV_TRUE; 1086 1087CLEAN_UP: 1088 PVCleanUpVideoEncoder(encoderControl); 1089 1090 return PV_FALSE; 1091} 1092 1093 1094/* ======================================================================== */ 1095/* Function : PVCleanUpVideoEncoder() */ 1096/* Date : 08/22/2000 */ 1097/* Purpose : Deallocates allocated memory from InitVideoEncoder() */ 1098/* In/out : */ 1099/* Return : PV_TRUE if successed, PV_FALSE if failed. */ 1100/* Modified : 5/21/01, free only yChan in Vop */ 1101/* */ 1102/* ======================================================================== */ 1103 1104OSCL_EXPORT_REF Bool PVCleanUpVideoEncoder(VideoEncControls *encoderControl) 1105{ 1106 Int idx, i; 1107 VideoEncData *video = (VideoEncData *)encoderControl->videoEncoderData; 1108 int nTotalMB; 1109 int max_width, offset; 1110 1111#ifdef PRINT_RC_INFO 1112 if (facct != NULL) 1113 { 1114 fprintf(facct, "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n"); 1115 fprintf(facct, "TOTAL NUM BITS GENERATED %d\n", tiTotalNumBitsGenerated); 1116 fprintf(facct, "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n"); 1117 fprintf(facct, "TOTAL NUMBER OF FRAMES CODED %d\n", 1118 video->encParams->rc[0]->totalFrameNumber); 1119 fprintf(facct, "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n"); 1120 fprintf(facct, "Average BitRate %d\n", 1121 (tiTotalNumBitsGenerated / (90 / 30))); 1122 fprintf(facct, "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n"); 1123 fprintf(facct, "TOTAL NUMBER OF STUFF BITS %d\n", (iStuffBits + 10740)); 1124 fprintf(facct, "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n"); 1125 fprintf(facct, "TOTAL NUMBER OF BITS TO NETWORK %d\n", (35800*90 / 30));; 1126 fprintf(facct, "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n"); 1127 fprintf(facct, "SUM OF STUFF BITS AND GENERATED BITS %d\n", 1128 (tiTotalNumBitsGenerated + iStuffBits + 10740)); 1129 fprintf(facct, "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n"); 1130 fprintf(facct, "UNACCOUNTED DIFFERENCE %d\n", 1131 ((35800*90 / 30) - (tiTotalNumBitsGenerated + iStuffBits + 10740))); 1132 fprintf(facct, "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n"); 1133 fclose(facct); 1134 } 1135#endif 1136 1137#ifdef PRINT_EC 1138 fclose(fec); 1139#endif 1140 1141 if (video != NULL) 1142 { 1143 1144 if (video->QPMB) M4VENC_FREE(video->QPMB); 1145 if (video->headerInfo.Mode)M4VENC_FREE(video->headerInfo.Mode); 1146 if (video->headerInfo.CBP)M4VENC_FREE(video->headerInfo.CBP); 1147 1148 1149 if (video->mot) 1150 { 1151 nTotalMB = video->vol[0]->nTotalMB; 1152 for (idx = 1; idx < video->currLayer; idx++) 1153 if (video->vol[idx]->nTotalMB > nTotalMB) 1154 nTotalMB = video->vol[idx]->nTotalMB; 1155 for (idx = 0; idx < nTotalMB; idx++) 1156 { 1157 if (video->mot[idx]) 1158 M4VENC_FREE(video->mot[idx]); 1159 } 1160 M4VENC_FREE(video->mot); 1161 } 1162 1163 if (video->intraArray) M4VENC_FREE(video->intraArray); 1164 1165 if (video->sliceNo)M4VENC_FREE(video->sliceNo); 1166 if (video->acPredFlag)M4VENC_FREE(video->acPredFlag); 1167// if(video->predDCAC)M4VENC_FREE(video->predDCAC); 1168 if (video->predDC) M4VENC_FREE(video->predDC); 1169 video->predDCAC_row = NULL; 1170 if (video->predDCAC_col) M4VENC_FREE(video->predDCAC_col); 1171 if (video->outputMB)M4VENC_FREE(video->outputMB); 1172 1173 if (video->bitstream1)BitstreamCloseEnc(video->bitstream1); 1174 if (video->bitstream2)BitstreamCloseEnc(video->bitstream2); 1175 if (video->bitstream3)BitstreamCloseEnc(video->bitstream3); 1176 1177 if (video->overrunBuffer) M4VENC_FREE(video->overrunBuffer); 1178 1179 max_width = video->encParams->LayerWidth[0]; 1180 max_width = (((max_width + 15) >> 4) << 4); /* 09/19/05 */ 1181 if (video->encParams->H263_Enabled) 1182 { 1183 offset = 0; 1184 } 1185 else 1186 { 1187 offset = ((max_width + 32) << 4) + 16; 1188 } 1189 1190 if (video->currVop) 1191 { 1192 if (video->currVop->yChan) 1193 { 1194 video->currVop->yChan -= offset; 1195 M4VENC_FREE(video->currVop->yChan); 1196 } 1197 M4VENC_FREE(video->currVop); 1198 } 1199 1200 if (video->nextBaseVop) 1201 { 1202 if (video->nextBaseVop->yChan) 1203 { 1204 video->nextBaseVop->yChan -= offset; 1205 M4VENC_FREE(video->nextBaseVop->yChan); 1206 } 1207 M4VENC_FREE(video->nextBaseVop); 1208 } 1209 1210 if (video->prevBaseVop) 1211 { 1212 if (video->prevBaseVop->yChan) 1213 { 1214 video->prevBaseVop->yChan -= offset; 1215 M4VENC_FREE(video->prevBaseVop->yChan); 1216 } 1217 M4VENC_FREE(video->prevBaseVop); 1218 } 1219 if (video->prevEnhanceVop) 1220 { 1221 if (video->prevEnhanceVop->yChan) 1222 { 1223 video->prevEnhanceVop->yChan -= offset; 1224 M4VENC_FREE(video->prevEnhanceVop->yChan); 1225 } 1226 M4VENC_FREE(video->prevEnhanceVop); 1227 } 1228 1229 /* 04/09/01, for Vops in the use multipass processing */ 1230 for (idx = 0; idx < video->encParams->nLayers; idx++) 1231 { 1232 if (video->pMP[idx]) 1233 { 1234 if (video->pMP[idx]->pRDSamples) 1235 { 1236 for (i = 0; i < 30; i++) 1237 { 1238 if (video->pMP[idx]->pRDSamples[i]) 1239 M4VENC_FREE(video->pMP[idx]->pRDSamples[i]); 1240 } 1241 M4VENC_FREE(video->pMP[idx]->pRDSamples); 1242 } 1243 1244 M4VENC_MEMSET(video->pMP[idx], 0, sizeof(MultiPass)); 1245 M4VENC_FREE(video->pMP[idx]); 1246 } 1247 } 1248 /* // End /////////////////////////////////////// */ 1249 1250 if (video->vol) 1251 { 1252 for (idx = 0; idx < video->encParams->nLayers; idx++) 1253 { 1254 if (video->vol[idx]) 1255 { 1256 if (video->vol[idx]->stream) 1257 M4VENC_FREE(video->vol[idx]->stream); 1258 M4VENC_FREE(video->vol[idx]); 1259 } 1260 } 1261 M4VENC_FREE(video->vol); 1262 } 1263 1264 /***************************************************/ 1265 /* stop rate control parameters */ 1266 /***************************************************/ 1267 1268 /* ANNEX L RATE CONTROL */ 1269 if (video->encParams->RC_Type != CONSTANT_Q) 1270 { 1271 RC_Cleanup(video->rc, video->encParams->nLayers); 1272 1273 for (idx = 0; idx < video->encParams->nLayers; idx++) 1274 { 1275 if (video->rc[idx]) 1276 M4VENC_FREE(video->rc[idx]); 1277 } 1278 } 1279 1280 if (video->functionPointer) M4VENC_FREE(video->functionPointer); 1281 1282 /* If application has called PVCleanUpVideoEncoder then we deallocate */ 1283 /* If PVInitVideoEncoder class it, then we DO NOT deallocate */ 1284 if (video->encParams) 1285 { 1286 M4VENC_FREE(video->encParams); 1287 } 1288 1289 M4VENC_FREE(video); 1290 encoderControl->videoEncoderData = NULL; /* video */ 1291 } 1292 1293 encoderControl->videoEncoderInit = 0; 1294 1295 return PV_TRUE; 1296} 1297 1298/* ======================================================================== */ 1299/* Function : PVGetVolHeader() */ 1300/* Date : 7/17/2001, */ 1301/* Purpose : */ 1302/* In/out : */ 1303/* Return : PV_TRUE if successed, PV_FALSE if failed. */ 1304/* Modified : */ 1305/* */ 1306/* ======================================================================== */ 1307 1308OSCL_EXPORT_REF Bool PVGetVolHeader(VideoEncControls *encCtrl, UChar *volHeader, Int *size, Int layer) 1309{ 1310 VideoEncData *encData; 1311 PV_STATUS EncodeVOS_Start(VideoEncControls *encCtrl); 1312 encData = (VideoEncData *)encCtrl->videoEncoderData; 1313 1314 1315 if (encData == NULL) 1316 return PV_FALSE; 1317 if (encData->encParams == NULL) 1318 return PV_FALSE; 1319 1320 1321 encData->currLayer = layer; /* Set Layer */ 1322 /*pv_status = */ 1323 EncodeVOS_Start(encCtrl); /* Encode VOL Header */ 1324 1325 encData->encParams->GetVolHeader[layer] = 1; /* Set usage flag: Needed to support old method*/ 1326 1327 /* Copy bitstream to buffer and set the size */ 1328 1329 if (*size > encData->bitstream1->byteCount) 1330 { 1331 *size = encData->bitstream1->byteCount; 1332 M4VENC_MEMCPY(volHeader, encData->bitstream1->bitstreamBuffer, *size); 1333 } 1334 else 1335 return PV_FALSE; 1336 1337 /* Reset bitstream1 buffer parameters */ 1338 BitstreamEncReset(encData->bitstream1); 1339 1340 return PV_TRUE; 1341} 1342 1343/* ======================================================================== */ 1344/* Function : PVGetOverrunBuffer() */ 1345/* Purpose : Get the overrun buffer ` */ 1346/* In/out : */ 1347/* Return : Pointer to overrun buffer. */ 1348/* Modified : */ 1349/* ======================================================================== */ 1350 1351OSCL_EXPORT_REF UChar* PVGetOverrunBuffer(VideoEncControls *encCtrl) 1352{ 1353 VideoEncData *video = (VideoEncData *)encCtrl->videoEncoderData; 1354 Int currLayer = video->currLayer; 1355 Vol *currVol = video->vol[currLayer]; 1356 1357 if (currVol->stream->bitstreamBuffer != video->overrunBuffer) // not used 1358 { 1359 return NULL; 1360 } 1361 1362 return video->overrunBuffer; 1363} 1364 1365 1366 1367 1368/* ======================================================================== */ 1369/* Function : EncodeVideoFrame() */ 1370/* Date : 08/22/2000 */ 1371/* Purpose : Encode video frame and return bitstream */ 1372/* In/out : */ 1373/* Return : PV_TRUE if successed, PV_FALSE if failed. */ 1374/* Modified : */ 1375/* 02.14.2001 */ 1376/* Finishing new timestamp 32-bit input */ 1377/* Applications need to take care of wrap-around */ 1378/* ======================================================================== */ 1379OSCL_EXPORT_REF Bool PVEncodeVideoFrame(VideoEncControls *encCtrl, VideoEncFrameIO *vid_in, VideoEncFrameIO *vid_out, 1380 ULong *nextModTime, UChar *bstream, Int *size, Int *nLayer) 1381{ 1382 Bool status = PV_TRUE; 1383 PV_STATUS pv_status; 1384 VideoEncData *video = (VideoEncData *)encCtrl->videoEncoderData; 1385 VideoEncParams *encParams = video->encParams; 1386 Vol *currVol; 1387 Vop *tempForwRefVop = NULL; 1388 Int tempRefSelCode = 0; 1389 PV_STATUS EncodeVOS_Start(VideoEncControls *encCtrl); 1390 Int width_16, height_16; 1391 Int width, height; 1392 Vop *temp; 1393 Int encodeVop = 0; 1394 void PaddingEdge(Vop *padVop); 1395 Int currLayer = -1; 1396 //Int nLayers = encParams->nLayers; 1397 1398 ULong modTime = vid_in->timestamp; 1399 1400#ifdef RANDOM_REFSELCODE /* add random selection of reference Vop */ 1401 Int random_val[30] = {0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 0}; 1402 static Int rand_idx = 0; 1403#endif 1404 1405 /*******************************************************/ 1406 /* Determine Next Vop to encode, if any, and nLayer */ 1407 /*******************************************************/ 1408 //i = nLayers-1; 1409 1410 if (video->volInitialize[0]) /* first vol to code */ 1411 { 1412 video->nextModTime = video->modTimeRef = ((modTime) - ((modTime) % 1000)); 1413 } 1414 1415 encodeVop = DetermineCodingLayer(video, nLayer, modTime); 1416 currLayer = *nLayer; 1417 if ((currLayer < 0) || (currLayer > encParams->nLayers - 1)) 1418 return PV_FALSE; 1419 1420 /******************************************/ 1421 /* If post-skipping still effective --- return */ 1422 /******************************************/ 1423 1424 if (!encodeVop) /* skip enh layer, no base layer coded --- return */ 1425 { 1426#ifdef _PRINT_STAT 1427 printf("No frame coded. Continue to next frame."); 1428#endif 1429 /* expected next code time, convert back to millisec */ 1430 *nextModTime = video->nextModTime; 1431 1432#ifdef ALLOW_VOP_NOT_CODED 1433 if (video->vol[0]->shortVideoHeader) /* Short Video Header = 1 */ 1434 { 1435 *size = 0; 1436 *nLayer = -1; 1437 } 1438 else 1439 { 1440 *nLayer = 0; 1441 EncodeVopNotCoded(video, bstream, size, modTime); 1442 *size = video->vol[0]->stream->byteCount; 1443 } 1444#else 1445 *size = 0; 1446 *nLayer = -1; 1447#endif 1448 return status; 1449 } 1450 1451 1452//ENCODE_VOP_AGAIN: /* 12/30/00 */ 1453 1454 /**************************************************************/ 1455 /* Initialize Vol stream structure with application bitstream */ 1456 /**************************************************************/ 1457 1458 currVol = video->vol[currLayer]; 1459 currVol->stream->bitstreamBuffer = bstream; 1460 currVol->stream->bufferSize = *size; 1461 BitstreamEncReset(currVol->stream); 1462 BitstreamSetOverrunBuffer(currVol->stream, video->overrunBuffer, video->oBSize, video); 1463 1464 /***********************************************************/ 1465 /* Encode VOS and VOL Headers on first call for each layer */ 1466 /***********************************************************/ 1467 1468 if (video->volInitialize[currLayer]) 1469 { 1470 video->currVop->timeInc = 0; 1471 video->prevBaseVop->timeInc = 0; 1472 if (!video->encParams->GetVolHeader[currLayer]) 1473 pv_status = EncodeVOS_Start(encCtrl); 1474 } 1475 1476 /***************************************************/ 1477 /* Copy Input Video Frame to Internal Video Buffer */ 1478 /***************************************************/ 1479 /* Determine Width and Height of Vop Layer */ 1480 1481 width = encParams->LayerWidth[currLayer]; /* Get input width */ 1482 height = encParams->LayerHeight[currLayer]; /* Get input height */ 1483 /* Round Up to nearest multiple of 16 : MPEG-4 Standard */ 1484 1485 width_16 = ((width + 15) / 16) * 16; /* Round up to nearest multiple of 16 */ 1486 height_16 = ((height + 15) / 16) * 16; /* Round up to nearest multiple of 16 */ 1487 1488 video->input = vid_in; /* point to the frame input */ 1489 1490 /*// End ////////////////////////////// */ 1491 1492 1493 /**************************************/ 1494 /* Determine VOP Type */ 1495 /* 6/2/2001, separate function */ 1496 /**************************************/ 1497 DetermineVopType(video, currLayer); 1498 1499 /****************************/ 1500 /* Initialize VOP */ 1501 /****************************/ 1502 video->currVop->volID = currVol->volID; 1503 video->currVop->width = width_16; 1504 video->currVop->height = height_16; 1505 if (video->encParams->H263_Enabled) /* 11/28/05 */ 1506 { 1507 video->currVop->pitch = width_16; 1508 } 1509 else 1510 { 1511 video->currVop->pitch = width_16 + 32; 1512 } 1513 video->currVop->timeInc = currVol->timeIncrement; 1514 video->currVop->vopCoded = 1; 1515 video->currVop->roundingType = 0; 1516 video->currVop->intraDCVlcThr = encParams->IntraDCVlcThr; 1517 1518 if (currLayer == 0 1519#ifdef RANDOM_REFSELCODE /* add random selection of reference Vop */ 1520 || random_val[rand_idx] || video->volInitialize[currLayer] 1521#endif 1522 ) 1523 { 1524 tempForwRefVop = video->forwardRefVop; /* keep initial state */ 1525 if (tempForwRefVop != NULL) tempRefSelCode = tempForwRefVop->refSelectCode; 1526 1527 video->forwardRefVop = video->prevBaseVop; 1528 video->forwardRefVop->refSelectCode = 1; 1529 } 1530#ifdef RANDOM_REFSELCODE 1531 else 1532 { 1533 tempForwRefVop = video->forwardRefVop; /* keep initial state */ 1534 if (tempForwRefVop != NULL) tempRefSelCode = tempForwRefVop->refSelectCode; 1535 1536 video->forwardRefVop = video->prevEnhanceVop; 1537 video->forwardRefVop->refSelectCode = 0; 1538 } 1539 rand_idx++; 1540 rand_idx %= 30; 1541#endif 1542 1543 video->currVop->refSelectCode = video->forwardRefVop->refSelectCode; 1544 video->currVop->gobNumber = 0; 1545 video->currVop->gobFrameID = video->currVop->predictionType; 1546 video->currVop->temporalRef = (modTime * 30 / 1001) % 256; 1547 1548 video->currVop->temporalInterval = 0; 1549 1550 if (video->currVop->predictionType == I_VOP) 1551 video->currVop->quantizer = encParams->InitQuantIvop[currLayer]; 1552 else 1553 video->currVop->quantizer = encParams->InitQuantPvop[currLayer]; 1554 1555 1556 /****************/ 1557 /* Encode Vop */ 1558 /****************/ 1559 video->slice_coding = 0; 1560 1561 pv_status = EncodeVop(video); 1562#ifdef _PRINT_STAT 1563 if (video->currVop->predictionType == I_VOP) 1564 printf(" I-VOP "); 1565 else 1566 printf(" P-VOP (ref.%d)", video->forwardRefVop->refSelectCode); 1567#endif 1568 1569 /************************************/ 1570 /* Update Skip Next Frame */ 1571 /************************************/ 1572 *nLayer = UpdateSkipNextFrame(video, nextModTime, size, pv_status); 1573 if (*nLayer == -1) /* skip current frame */ 1574 { 1575 /* make sure that pointers are restored to the previous state */ 1576 if (currLayer == 0) 1577 { 1578 video->forwardRefVop = tempForwRefVop; /* For P-Vop base only */ 1579 video->forwardRefVop->refSelectCode = tempRefSelCode; 1580 } 1581 1582 return status; 1583 } 1584 1585 /* If I-VOP was encoded, reset IntraPeriod */ 1586 if ((currLayer == 0) && (encParams->IntraPeriod > 0) && (video->currVop->predictionType == I_VOP)) 1587 video->nextEncIVop = encParams->IntraPeriod; 1588 1589 /* Set HintTrack Information */ 1590 if (currLayer != -1) 1591 { 1592 if (currVol->prevModuloTimeBase) 1593 video->hintTrackInfo.MTB = 1; 1594 else 1595 video->hintTrackInfo.MTB = 0; 1596 video->hintTrackInfo.LayerID = (UChar)currVol->volID; 1597 video->hintTrackInfo.CodeType = (UChar)video->currVop->predictionType; 1598 video->hintTrackInfo.RefSelCode = (UChar)video->currVop->refSelectCode; 1599 } 1600 1601 /************************************************/ 1602 /* Determine nLayer and timeInc for next encode */ 1603 /* 12/27/00 always go by the highest layer*/ 1604 /************************************************/ 1605 1606 /**********************************************************/ 1607 /* Copy Reconstructed Buffer to Output Video Frame Buffer */ 1608 /**********************************************************/ 1609 vid_out->yChan = video->currVop->yChan; 1610 vid_out->uChan = video->currVop->uChan; 1611 vid_out->vChan = video->currVop->vChan; 1612 if (video->encParams->H263_Enabled) 1613 { 1614 vid_out->height = video->currVop->height; /* padded height */ 1615 vid_out->pitch = video->currVop->width; /* padded width */ 1616 } 1617 else 1618 { 1619 vid_out->height = video->currVop->height + 32; /* padded height */ 1620 vid_out->pitch = video->currVop->width + 32; /* padded width */ 1621 } 1622 //video_out->timestamp = video->modTime; 1623 vid_out->timestamp = (ULong)(((video->prevFrameNum[currLayer] * 1000) / encParams->LayerFrameRate[currLayer]) + video->modTimeRef + 0.5); 1624 1625 /*// End /////////////////////// */ 1626 1627 /***********************************/ 1628 /* Update Ouput bstream byte count */ 1629 /***********************************/ 1630 1631 *size = currVol->stream->byteCount; 1632 1633 /****************************************/ 1634 /* Swap Vop Pointers for Base Layer */ 1635 /****************************************/ 1636 if (currLayer == 0) 1637 { 1638 temp = video->prevBaseVop; 1639 video->prevBaseVop = video->currVop; 1640 video->prevBaseVop->padded = 0; /* not padded */ 1641 video->currVop = temp; 1642 video->forwardRefVop = video->prevBaseVop; /* For P-Vop base only */ 1643 video->forwardRefVop->refSelectCode = 1; 1644 } 1645 else 1646 { 1647 temp = video->prevEnhanceVop; 1648 video->prevEnhanceVop = video->currVop; 1649 video->prevEnhanceVop->padded = 0; /* not padded */ 1650 video->currVop = temp; 1651 video->forwardRefVop = video->prevEnhanceVop; 1652 video->forwardRefVop->refSelectCode = 0; 1653 } 1654 1655 /****************************************/ 1656 /* Modify the intialize flag at the end.*/ 1657 /****************************************/ 1658 if (video->volInitialize[currLayer]) 1659 video->volInitialize[currLayer] = 0; 1660 1661 return status; 1662} 1663 1664#ifndef NO_SLICE_ENCODE 1665/* ======================================================================== */ 1666/* Function : PVEncodeFrameSet() */ 1667/* Date : 04/18/2000 */ 1668/* Purpose : Enter a video frame and perform front-end time check plus ME */ 1669/* In/out : */ 1670/* Return : PV_TRUE if successed, PV_FALSE if failed. */ 1671/* Modified : */ 1672/* */ 1673/* ======================================================================== */ 1674OSCL_EXPORT_REF Bool PVEncodeFrameSet(VideoEncControls *encCtrl, VideoEncFrameIO *vid_in, ULong *nextModTime, Int *nLayer) 1675{ 1676 Bool status = PV_TRUE; 1677 VideoEncData *video = (VideoEncData *)encCtrl->videoEncoderData; 1678 VideoEncParams *encParams = video->encParams; 1679 Vol *currVol; 1680 PV_STATUS EncodeVOS_Start(VideoEncControls *encCtrl); 1681 Int width_16, height_16; 1682 Int width, height; 1683 Int encodeVop = 0; 1684 void PaddingEdge(Vop *padVop); 1685 Int currLayer = -1; 1686 //Int nLayers = encParams->nLayers; 1687 1688 ULong modTime = vid_in->timestamp; 1689 1690#ifdef RANDOM_REFSELCODE /* add random selection of reference Vop */ 1691 Int random_val[30] = {0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 0}; 1692 static Int rand_idx = 0; 1693#endif 1694 /*******************************************************/ 1695 /* Determine Next Vop to encode, if any, and nLayer */ 1696 /*******************************************************/ 1697 1698 video->modTime = modTime; 1699 1700 //i = nLayers-1; 1701 1702 if (video->volInitialize[0]) /* first vol to code */ 1703 { 1704 video->nextModTime = video->modTimeRef = ((modTime) - ((modTime) % 1000)); 1705 } 1706 1707 1708 encodeVop = DetermineCodingLayer(video, nLayer, modTime); 1709 1710 currLayer = *nLayer; 1711 1712 /******************************************/ 1713 /* If post-skipping still effective --- return */ 1714 /******************************************/ 1715 1716 if (!encodeVop) /* skip enh layer, no base layer coded --- return */ 1717 { 1718#ifdef _PRINT_STAT 1719 printf("No frame coded. Continue to next frame."); 1720#endif 1721 *nLayer = -1; 1722 1723 /* expected next code time, convert back to millisec */ 1724 *nextModTime = video->nextModTime;; 1725 return status; 1726 } 1727 1728 /**************************************************************/ 1729 /* Initialize Vol stream structure with application bitstream */ 1730 /**************************************************************/ 1731 1732 currVol = video->vol[currLayer]; 1733 currVol->stream->bufferSize = 0; 1734 BitstreamEncReset(currVol->stream); 1735 1736 /***********************************************************/ 1737 /* Encode VOS and VOL Headers on first call for each layer */ 1738 /***********************************************************/ 1739 1740 if (video->volInitialize[currLayer]) 1741 { 1742 video->currVop->timeInc = 0; 1743 video->prevBaseVop->timeInc = 0; 1744 } 1745 1746 /***************************************************/ 1747 /* Copy Input Video Frame to Internal Video Buffer */ 1748 /***************************************************/ 1749 /* Determine Width and Height of Vop Layer */ 1750 1751 width = encParams->LayerWidth[currLayer]; /* Get input width */ 1752 height = encParams->LayerHeight[currLayer]; /* Get input height */ 1753 /* Round Up to nearest multiple of 16 : MPEG-4 Standard */ 1754 1755 width_16 = ((width + 15) / 16) * 16; /* Round up to nearest multiple of 16 */ 1756 height_16 = ((height + 15) / 16) * 16; /* Round up to nearest multiple of 16 */ 1757 1758 video->input = vid_in; /* point to the frame input */ 1759 1760 /*// End ////////////////////////////// */ 1761 1762 1763 /**************************************/ 1764 /* Determine VOP Type */ 1765 /* 6/2/2001, separate function */ 1766 /**************************************/ 1767 DetermineVopType(video, currLayer); 1768 1769 /****************************/ 1770 /* Initialize VOP */ 1771 /****************************/ 1772 video->currVop->volID = currVol->volID; 1773 video->currVop->width = width_16; 1774 video->currVop->height = height_16; 1775 if (video->encParams->H263_Enabled) /* 11/28/05 */ 1776 { 1777 video->currVop->pitch = width_16; 1778 } 1779 else 1780 { 1781 video->currVop->pitch = width_16 + 32; 1782 } 1783 video->currVop->timeInc = currVol->timeIncrement; 1784 video->currVop->vopCoded = 1; 1785 video->currVop->roundingType = 0; 1786 video->currVop->intraDCVlcThr = encParams->IntraDCVlcThr; 1787 1788 if (currLayer == 0 1789#ifdef RANDOM_REFSELCODE /* add random selection of reference Vop */ 1790 || random_val[rand_idx] || video->volInitialize[currLayer] 1791#endif 1792 ) 1793 { 1794 video->tempForwRefVop = video->forwardRefVop; /* keep initial state */ 1795 if (video->tempForwRefVop != NULL) video->tempRefSelCode = video->tempForwRefVop->refSelectCode; 1796 1797 video->forwardRefVop = video->prevBaseVop; 1798 video->forwardRefVop->refSelectCode = 1; 1799 } 1800#ifdef RANDOM_REFSELCODE 1801 else 1802 { 1803 video->tempForwRefVop = video->forwardRefVop; /* keep initial state */ 1804 if (video->tempForwRefVop != NULL) video->tempRefSelCode = video->tempForwRefVop->refSelectCode; 1805 1806 video->forwardRefVop = video->prevEnhanceVop; 1807 video->forwardRefVop->refSelectCode = 0; 1808 } 1809 rand_idx++; 1810 rand_idx %= 30; 1811#endif 1812 1813 video->currVop->refSelectCode = video->forwardRefVop->refSelectCode; 1814 video->currVop->gobNumber = 0; 1815 video->currVop->gobFrameID = video->currVop->predictionType; 1816 video->currVop->temporalRef = ((modTime) * 30 / 1001) % 256; 1817 1818 video->currVop->temporalInterval = 0; 1819 1820 if (video->currVop->predictionType == I_VOP) 1821 video->currVop->quantizer = encParams->InitQuantIvop[currLayer]; 1822 else 1823 video->currVop->quantizer = encParams->InitQuantPvop[currLayer]; 1824 1825 /****************/ 1826 /* Encode Vop */ 1827 /****************/ 1828 video->slice_coding = 1; 1829 1830 /*pv_status =*/ 1831 EncodeVop(video); 1832 1833#ifdef _PRINT_STAT 1834 if (video->currVop->predictionType == I_VOP) 1835 printf(" I-VOP "); 1836 else 1837 printf(" P-VOP (ref.%d)", video->forwardRefVop->refSelectCode); 1838#endif 1839 1840 /* Set HintTrack Information */ 1841 if (currVol->prevModuloTimeBase) 1842 video->hintTrackInfo.MTB = 1; 1843 else 1844 video->hintTrackInfo.MTB = 0; 1845 1846 video->hintTrackInfo.LayerID = (UChar)currVol->volID; 1847 video->hintTrackInfo.CodeType = (UChar)video->currVop->predictionType; 1848 video->hintTrackInfo.RefSelCode = (UChar)video->currVop->refSelectCode; 1849 1850 return status; 1851} 1852#endif /* NO_SLICE_ENCODE */ 1853 1854#ifndef NO_SLICE_ENCODE 1855/* ======================================================================== */ 1856/* Function : PVEncodePacket() */ 1857/* Date : 04/18/2002 */ 1858/* Purpose : Encode one packet and return bitstream */ 1859/* In/out : */ 1860/* Return : PV_TRUE if successed, PV_FALSE if failed. */ 1861/* Modified : */ 1862/* */ 1863/* ======================================================================== */ 1864OSCL_EXPORT_REF Bool PVEncodeSlice(VideoEncControls *encCtrl, UChar *bstream, Int *size, 1865 Int *endofFrame, VideoEncFrameIO *vid_out, ULong *nextModTime) 1866{ 1867 PV_STATUS pv_status; 1868 VideoEncData *video = (VideoEncData *)encCtrl->videoEncoderData; 1869 VideoEncParams *encParams = video->encParams; 1870 Vol *currVol; 1871 PV_STATUS EncodeVOS_Start(VideoEncControls *encCtrl); 1872 Vop *temp; 1873 void PaddingEdge(Vop *padVop); 1874 Int currLayer = video->currLayer; 1875 Int pre_skip; 1876 Int pre_size; 1877 /**************************************************************/ 1878 /* Initialize Vol stream structure with application bitstream */ 1879 /**************************************************************/ 1880 1881 currVol = video->vol[currLayer]; 1882 currVol->stream->bitstreamBuffer = bstream; 1883 pre_size = currVol->stream->byteCount; 1884 currVol->stream->bufferSize = pre_size + (*size); 1885 1886 /***********************************************************/ 1887 /* Encode VOS and VOL Headers on first call for each layer */ 1888 /***********************************************************/ 1889 1890 if (video->volInitialize[currLayer]) 1891 { 1892 if (!video->encParams->GetVolHeader[currLayer]) 1893 pv_status = EncodeVOS_Start(encCtrl); 1894 } 1895 1896 /****************/ 1897 /* Encode Slice */ 1898 /****************/ 1899 pv_status = EncodeSlice(video); 1900 1901 *endofFrame = 0; 1902 1903 if (video->mbnum >= currVol->nTotalMB && !video->end_of_buf) 1904 { 1905 *endofFrame = 1; 1906 1907 /************************************/ 1908 /* Update Skip Next Frame */ 1909 /************************************/ 1910 pre_skip = UpdateSkipNextFrame(video, nextModTime, size, pv_status); /* modified such that no pre-skipped */ 1911 1912 if (pre_skip == -1) /* error */ 1913 { 1914 *endofFrame = -1; 1915 /* make sure that pointers are restored to the previous state */ 1916 if (currLayer == 0) 1917 { 1918 video->forwardRefVop = video->tempForwRefVop; /* For P-Vop base only */ 1919 video->forwardRefVop->refSelectCode = video->tempRefSelCode; 1920 } 1921 1922 return pv_status; 1923 } 1924 1925 /* If I-VOP was encoded, reset IntraPeriod */ 1926 if ((currLayer == 0) && (encParams->IntraPeriod > 0) && (video->currVop->predictionType == I_VOP)) 1927 video->nextEncIVop = encParams->IntraPeriod; 1928 1929 /**********************************************************/ 1930 /* Copy Reconstructed Buffer to Output Video Frame Buffer */ 1931 /**********************************************************/ 1932 vid_out->yChan = video->currVop->yChan; 1933 vid_out->uChan = video->currVop->uChan; 1934 vid_out->vChan = video->currVop->vChan; 1935 if (video->encParams->H263_Enabled) 1936 { 1937 vid_out->height = video->currVop->height; /* padded height */ 1938 vid_out->pitch = video->currVop->width; /* padded width */ 1939 } 1940 else 1941 { 1942 vid_out->height = video->currVop->height + 32; /* padded height */ 1943 vid_out->pitch = video->currVop->width + 32; /* padded width */ 1944 } 1945 //vid_out->timestamp = video->modTime; 1946 vid_out->timestamp = (ULong)(((video->prevFrameNum[currLayer] * 1000) / encParams->LayerFrameRate[currLayer]) + video->modTimeRef + 0.5); 1947 1948 /*// End /////////////////////// */ 1949 1950 /****************************************/ 1951 /* Swap Vop Pointers for Base Layer */ 1952 /****************************************/ 1953 1954 if (currLayer == 0) 1955 { 1956 temp = video->prevBaseVop; 1957 video->prevBaseVop = video->currVop; 1958 video->prevBaseVop->padded = 0; /* not padded */ 1959 video->currVop = temp; 1960 video->forwardRefVop = video->prevBaseVop; /* For P-Vop base only */ 1961 video->forwardRefVop->refSelectCode = 1; 1962 } 1963 else 1964 { 1965 temp = video->prevEnhanceVop; 1966 video->prevEnhanceVop = video->currVop; 1967 video->prevEnhanceVop->padded = 0; /* not padded */ 1968 video->currVop = temp; 1969 video->forwardRefVop = video->prevEnhanceVop; 1970 video->forwardRefVop->refSelectCode = 0; 1971 } 1972 } 1973 1974 /***********************************/ 1975 /* Update Ouput bstream byte count */ 1976 /***********************************/ 1977 1978 *size = currVol->stream->byteCount - pre_size; 1979 1980 /****************************************/ 1981 /* Modify the intialize flag at the end.*/ 1982 /****************************************/ 1983 if (video->volInitialize[currLayer]) 1984 video->volInitialize[currLayer] = 0; 1985 1986 return pv_status; 1987} 1988#endif /* NO_SLICE_ENCODE */ 1989 1990 1991/* ======================================================================== */ 1992/* Function : PVGetH263ProfileLevelID() */ 1993/* Date : 02/05/2003 */ 1994/* Purpose : Get H.263 Profile ID and level ID for profile 0 */ 1995/* In/out : Profile ID=0, levelID is what we want */ 1996/* Return : PV_TRUE if successed, PV_FALSE if failed. */ 1997/* Modified : */ 1998/* Note : h263Level[8], rBR_bound[8], max_h263_framerate[2] */ 1999/* max_h263_width[2], max_h263_height[2] are global */ 2000/* */ 2001/* ======================================================================== */ 2002OSCL_EXPORT_REF Bool PVGetH263ProfileLevelID(VideoEncControls *encCtrl, Int *profileID, Int *levelID) 2003{ 2004 VideoEncData *encData; 2005 Int width, height; 2006 float bitrate_r, framerate; 2007 2008 2009 /* For this version, we only support H.263 profile 0 */ 2010 *profileID = 0; 2011 2012 *levelID = 0; 2013 encData = (VideoEncData *)encCtrl->videoEncoderData; 2014 2015 if (encData == NULL) 2016 return PV_FALSE; 2017 if (encData->encParams == NULL) 2018 return PV_FALSE; 2019 2020 if (!encData->encParams->H263_Enabled) return PV_FALSE; 2021 2022 2023 /* get image width, height, bitrate and framerate */ 2024 width = encData->encParams->LayerWidth[0]; 2025 height = encData->encParams->LayerHeight[0]; 2026 bitrate_r = (float)(encData->encParams->LayerBitRate[0]) / (float)64000.0; 2027 framerate = encData->encParams->LayerFrameRate[0]; 2028 if (!width || !height || !(bitrate_r > 0 && framerate > 0)) return PV_FALSE; 2029 2030 /* This is the most frequent case : level 10 */ 2031 if (bitrate_r <= rBR_bound[1] && framerate <= max_h263_framerate[0] && 2032 (width <= max_h263_width[0] && height <= max_h263_height[0])) 2033 { 2034 *levelID = h263Level[1]; 2035 return PV_TRUE; 2036 } 2037 else if (bitrate_r > rBR_bound[4] || 2038 (width > max_h263_width[1] || height > max_h263_height[1]) || 2039 framerate > max_h263_framerate[1]) /* check the highest level 70 */ 2040 { 2041 *levelID = h263Level[7]; 2042 return PV_TRUE; 2043 } 2044 else /* search level 20, 30, 40 */ 2045 { 2046 2047 /* pick out level 20 */ 2048 if (bitrate_r <= rBR_bound[2] && 2049 ((width <= max_h263_width[0] && height <= max_h263_height[0] && framerate <= max_h263_framerate[1]) || 2050 (width <= max_h263_width[1] && height <= max_h263_height[1] && framerate <= max_h263_framerate[0]))) 2051 { 2052 *levelID = h263Level[2]; 2053 return PV_TRUE; 2054 } 2055 else /* width, height and framerate are ok, now choose level 30 or 40 */ 2056 { 2057 *levelID = (bitrate_r <= rBR_bound[3] ? h263Level[3] : h263Level[4]); 2058 return PV_TRUE; 2059 } 2060 } 2061} 2062 2063/* ======================================================================== */ 2064/* Function : PVGetMPEG4ProfileLevelID() */ 2065/* Date : 26/06/2008 */ 2066/* Purpose : Get MPEG4 Level after initialized */ 2067/* In/out : profile_level according to interface */ 2068/* Return : PV_TRUE if successed, PV_FALSE if failed. */ 2069/* Modified : */ 2070/* */ 2071/* ======================================================================== */ 2072OSCL_EXPORT_REF Bool PVGetMPEG4ProfileLevelID(VideoEncControls *encCtrl, Int *profile_level, Int nLayer) 2073{ 2074 VideoEncData* video; 2075 Int i; 2076 2077 video = (VideoEncData *)encCtrl->videoEncoderData; 2078 2079 if (nLayer == 0) 2080 { 2081 for (i = 0; i < 8; i++) 2082 { 2083 if (video->encParams->ProfileLevel[0] == profile_level_code[i]) 2084 { 2085 break; 2086 } 2087 } 2088 *profile_level = i; 2089 } 2090 else 2091 { 2092 for (i = 0; i < 8; i++) 2093 { 2094 if (video->encParams->ProfileLevel[0] == scalable_profile_level_code[i]) 2095 { 2096 break; 2097 } 2098 } 2099 *profile_level = i + SIMPLE_SCALABLE_PROFILE_LEVEL0; 2100 } 2101 2102 return true; 2103} 2104 2105#ifndef LIMITED_API 2106/* ======================================================================== */ 2107/* Function : PVUpdateEncFrameRate */ 2108/* Date : 04/08/2002 */ 2109/* Purpose : Update target frame rates of the encoded base and enhance */ 2110/* layer(if any) while encoding operation is ongoing */ 2111/* In/out : */ 2112/* Return : PV_TRUE if successed, PV_FALSE if failed. */ 2113/* Modified : */ 2114/* */ 2115/* ======================================================================== */ 2116 2117OSCL_EXPORT_REF Bool PVUpdateEncFrameRate(VideoEncControls *encCtrl, float *frameRate) 2118{ 2119 VideoEncData *encData; 2120 Int i;// nTotalMB, mbPerSec; 2121 2122 encData = (VideoEncData *)encCtrl->videoEncoderData; 2123 2124 if (encData == NULL) 2125 return PV_FALSE; 2126 if (encData->encParams == NULL) 2127 return PV_FALSE; 2128 2129 /* Update the framerates for all the layers */ 2130 for (i = 0; i < encData->encParams->nLayers; i++) 2131 { 2132 2133 /* New check: encoding framerate should be consistent with the given profile and level */ 2134 //nTotalMB = (((encData->encParams->LayerWidth[i]+15)/16)*16)*(((encData->encParams->LayerHeight[i]+15)/16)*16)/(16*16); 2135 //mbPerSec = (Int)(nTotalMB * frameRate[i]); 2136 //if(mbPerSec > encData->encParams->LayerMaxMbsPerSec[i]) return PV_FALSE; 2137 if (frameRate[i] > encData->encParams->LayerMaxFrameRate[i]) return PV_FALSE; /* set by users or profile */ 2138 2139 encData->encParams->LayerFrameRate[i] = frameRate[i]; 2140 } 2141 2142 return RC_UpdateBXRCParams((void*) encData); 2143 2144} 2145#endif 2146#ifndef LIMITED_API 2147/* ======================================================================== */ 2148/* Function : PVUpdateBitRate */ 2149/* Date : 04/08/2002 */ 2150/* Purpose : Update target bit rates of the encoded base and enhance */ 2151/* layer(if any) while encoding operation is ongoing */ 2152/* In/out : */ 2153/* Return : PV_TRUE if successed, PV_FALSE if failed. */ 2154/* Modified : */ 2155/* */ 2156/* ======================================================================== */ 2157 2158OSCL_EXPORT_REF Bool PVUpdateBitRate(VideoEncControls *encCtrl, Int *bitRate) 2159{ 2160 VideoEncData *encData; 2161 Int i; 2162 2163 encData = (VideoEncData *)encCtrl->videoEncoderData; 2164 2165 if (encData == NULL) 2166 return PV_FALSE; 2167 if (encData->encParams == NULL) 2168 return PV_FALSE; 2169 2170 /* Update the bitrates for all the layers */ 2171 for (i = 0; i < encData->encParams->nLayers; i++) 2172 { 2173 if (bitRate[i] > encData->encParams->LayerMaxBitRate[i]) /* set by users or profile */ 2174 { 2175 return PV_FALSE; 2176 } 2177 encData->encParams->LayerBitRate[i] = bitRate[i]; 2178 } 2179 2180 return RC_UpdateBXRCParams((void*) encData); 2181 2182} 2183#endif 2184#ifndef LIMITED_API 2185/* ============================================================================ */ 2186/* Function : PVUpdateVBVDelay() */ 2187/* Date : 4/23/2004 */ 2188/* Purpose : Update VBV buffer size(in delay) */ 2189/* In/out : */ 2190/* Return : PV_TRUE if successed, PV_FALSE if failed. */ 2191/* Modified : */ 2192/* */ 2193/* ============================================================================ */ 2194 2195Bool PVUpdateVBVDelay(VideoEncControls *encCtrl, float delay) 2196{ 2197 2198 VideoEncData *encData; 2199 Int total_bitrate, max_buffer_size; 2200 int index; 2201 2202 encData = (VideoEncData *)encCtrl->videoEncoderData; 2203 2204 if (encData == NULL) 2205 return PV_FALSE; 2206 if (encData->encParams == NULL) 2207 return PV_FALSE; 2208 2209 /* Check whether the input delay is valid based on the given profile */ 2210 total_bitrate = (encData->encParams->nLayers == 1 ? encData->encParams->LayerBitRate[0] : 2211 encData->encParams->LayerBitRate[1]); 2212 index = encData->encParams->profile_table_index; 2213 max_buffer_size = (encData->encParams->nLayers == 1 ? profile_level_max_VBV_size[index] : 2214 scalable_profile_level_max_VBV_size[index]); 2215 2216 if (total_bitrate*delay > (float)max_buffer_size) 2217 return PV_FALSE; 2218 2219 encData->encParams->VBV_delay = delay; 2220 return PV_TRUE; 2221 2222} 2223#endif 2224#ifndef LIMITED_API 2225/* ======================================================================== */ 2226/* Function : PVUpdateIFrameInterval() */ 2227/* Date : 04/10/2002 */ 2228/* Purpose : updates the INTRA frame refresh interval while encoding */ 2229/* is ongoing */ 2230/* In/out : */ 2231/* Return : PV_TRUE if successed, PV_FALSE if failed. */ 2232/* Modified : */ 2233/* */ 2234/* ======================================================================== */ 2235 2236OSCL_EXPORT_REF Bool PVUpdateIFrameInterval(VideoEncControls *encCtrl, Int aIFramePeriod) 2237{ 2238 VideoEncData *encData; 2239 2240 encData = (VideoEncData *)encCtrl->videoEncoderData; 2241 2242 if (encData == NULL) 2243 return PV_FALSE; 2244 if (encData->encParams == NULL) 2245 return PV_FALSE; 2246 2247 encData->encParams->IntraPeriod = aIFramePeriod; 2248 return PV_TRUE; 2249} 2250#endif 2251#ifndef LIMITED_API 2252/* ======================================================================== */ 2253/* Function : PVSetNumIntraMBRefresh() */ 2254/* Date : 08/05/2003 */ 2255/* Purpose : */ 2256/* In/out : */ 2257/* Return : PV_TRUE if successed, PV_FALSE if failed. */ 2258/* Modified : */ 2259/* */ 2260/* ======================================================================== */ 2261OSCL_EXPORT_REF Bool PVUpdateNumIntraMBRefresh(VideoEncControls *encCtrl, Int numMB) 2262{ 2263 VideoEncData *encData; 2264 2265 encData = (VideoEncData *)encCtrl->videoEncoderData; 2266 2267 if (encData == NULL) 2268 return PV_FALSE; 2269 2270 encData->encParams->Refresh = numMB; 2271 2272 return PV_TRUE; 2273} 2274#endif 2275#ifndef LIMITED_API 2276/* ======================================================================== */ 2277/* Function : PVIFrameRequest() */ 2278/* Date : 04/10/2002 */ 2279/* Purpose : encodes the next base frame as an I-Vop */ 2280/* In/out : */ 2281/* Return : PV_TRUE if successed, PV_FALSE if failed. */ 2282/* Modified : */ 2283/* */ 2284/* ======================================================================== */ 2285 2286OSCL_EXPORT_REF Bool PVIFrameRequest(VideoEncControls *encCtrl) 2287{ 2288 VideoEncData *encData; 2289 2290 encData = (VideoEncData *)encCtrl->videoEncoderData; 2291 2292 if (encData == NULL) 2293 return PV_FALSE; 2294 if (encData->encParams == NULL) 2295 return PV_FALSE; 2296 2297 encData->nextEncIVop = 1; 2298 return PV_TRUE; 2299} 2300#endif 2301#ifndef LIMITED_API 2302/* ======================================================================== */ 2303/* Function : PVGetEncMemoryUsage() */ 2304/* Date : 10/17/2000 */ 2305/* Purpose : */ 2306/* In/out : */ 2307/* Return : PV_TRUE if successed, PV_FALSE if failed. */ 2308/* Modified : */ 2309/* */ 2310/* ======================================================================== */ 2311 2312OSCL_EXPORT_REF Int PVGetEncMemoryUsage(VideoEncControls *encCtrl) 2313{ 2314 VideoEncData *encData; 2315 2316 encData = (VideoEncData *)encCtrl->videoEncoderData; 2317 2318 if (encData == NULL) 2319 return PV_FALSE; 2320 if (encData->encParams == NULL) 2321 return PV_FALSE; 2322 return encData->encParams->MemoryUsage; 2323} 2324#endif 2325 2326/* ======================================================================== */ 2327/* Function : PVGetHintTrack() */ 2328/* Date : 1/17/2001, */ 2329/* Purpose : */ 2330/* In/out : */ 2331/* Return : PV_TRUE if successed, PV_FALSE if failed. */ 2332/* Modified : */ 2333/* */ 2334/* ======================================================================== */ 2335 2336OSCL_EXPORT_REF Bool PVGetHintTrack(VideoEncControls *encCtrl, MP4HintTrack *info) 2337{ 2338 VideoEncData *encData; 2339 2340 encData = (VideoEncData *)encCtrl->videoEncoderData; 2341 2342 if (encData == NULL) 2343 return PV_FALSE; 2344 if (encData->encParams == NULL) 2345 return PV_FALSE; 2346 info->MTB = encData->hintTrackInfo.MTB; 2347 info->LayerID = encData->hintTrackInfo.LayerID; 2348 info->CodeType = encData->hintTrackInfo.CodeType; 2349 info->RefSelCode = encData->hintTrackInfo.RefSelCode; 2350 2351 return PV_TRUE; 2352} 2353 2354/* ======================================================================== */ 2355/* Function : PVGetMaxVideoFrameSize() */ 2356/* Date : 7/17/2001, */ 2357/* Purpose : Function merely returns the maximum buffer size */ 2358/* In/out : */ 2359/* Return : PV_TRUE if successed, PV_FALSE if failed. */ 2360/* Modified : */ 2361/* */ 2362/* ======================================================================== */ 2363 2364OSCL_EXPORT_REF Bool PVGetMaxVideoFrameSize(VideoEncControls *encCtrl, Int *maxVideoFrameSize) 2365{ 2366 VideoEncData *encData; 2367 2368 encData = (VideoEncData *)encCtrl->videoEncoderData; 2369 2370 if (encData == NULL) 2371 return PV_FALSE; 2372 if (encData->encParams == NULL) 2373 return PV_FALSE; 2374 2375 2376 2377 *maxVideoFrameSize = encData->encParams->BufferSize[0]; 2378 2379 if (encData->encParams->nLayers == 2) 2380 if (*maxVideoFrameSize < encData->encParams->BufferSize[1]) 2381 *maxVideoFrameSize = encData->encParams->BufferSize[1]; 2382 *maxVideoFrameSize >>= 3; /* Convert to Bytes */ 2383 2384 if (*maxVideoFrameSize <= 4000) 2385 *maxVideoFrameSize = 4000; 2386 2387 return PV_TRUE; 2388} 2389#ifndef LIMITED_API 2390/* ======================================================================== */ 2391/* Function : PVGetVBVSize() */ 2392/* Date : 4/15/2002 */ 2393/* Purpose : Function merely returns the maximum buffer size */ 2394/* In/out : */ 2395/* Return : PV_TRUE if successed, PV_FALSE if failed. */ 2396/* Modified : */ 2397/* */ 2398/* ======================================================================== */ 2399 2400OSCL_EXPORT_REF Bool PVGetVBVSize(VideoEncControls *encCtrl, Int *VBVSize) 2401{ 2402 VideoEncData *encData; 2403 2404 encData = (VideoEncData *)encCtrl->videoEncoderData; 2405 2406 if (encData == NULL) 2407 return PV_FALSE; 2408 if (encData->encParams == NULL) 2409 return PV_FALSE; 2410 2411 *VBVSize = encData->encParams->BufferSize[0]; 2412 if (encData->encParams->nLayers == 2) 2413 *VBVSize += encData->encParams->BufferSize[1]; 2414 2415 return PV_TRUE; 2416 2417} 2418#endif 2419/* ======================================================================== */ 2420/* Function : EncodeVOS_Start() */ 2421/* Date : 08/22/2000 */ 2422/* Purpose : Encodes the VOS,VO, and VOL or Short Headers */ 2423/* In/out : */ 2424/* Return : PV_TRUE if successed, PV_FALSE if failed. */ 2425/* Modified : */ 2426/* */ 2427/* ======================================================================== */ 2428PV_STATUS EncodeVOS_Start(VideoEncControls *encoderControl) 2429{ 2430 2431 VideoEncData *video = (VideoEncData *)encoderControl->videoEncoderData; 2432 Vol *currVol = video->vol[video->currLayer]; 2433 PV_STATUS status = PV_SUCCESS; 2434 //int profile_level=0x01; 2435 BitstreamEncVideo *stream = video->bitstream1; 2436 int i, j; 2437 2438 /********************************/ 2439 /* Check for short_video_header */ 2440 /********************************/ 2441 if (currVol->shortVideoHeader == 1) 2442 return status; 2443 else 2444 { 2445 /* Short Video Header or M4V */ 2446 2447 /**************************/ 2448 /* VisualObjectSequence ()*/ 2449 /**************************/ 2450 status = BitstreamPutGT16Bits(stream, 32, SESSION_START_CODE); 2451 /* Determine profile_level */ 2452 status = BitstreamPutBits(stream, 8, video->encParams->ProfileLevel[video->currLayer]); 2453 2454 /******************/ 2455 /* VisualObject() */ 2456 /******************/ 2457 2458 status = BitstreamPutGT16Bits(stream, 32, VISUAL_OBJECT_START_CODE); 2459 status = BitstreamPut1Bits(stream, 0x00); /* visual object identifier */ 2460 status = BitstreamPutBits(stream, 4, 0x01); /* visual object Type == "video ID" */ 2461 status = BitstreamPut1Bits(stream, 0x00); /* no video signal type */ 2462 2463 /*temp = */ 2464 BitstreamMpeg4ByteAlignStuffing(stream); 2465 2466 2467 status = BitstreamPutGT16Bits(stream, 27, VO_START_CODE);/* byte align: should be 2 bits */ 2468 status = BitstreamPutBits(stream, 5, 0x00);/* Video ID = 0 */ 2469 2470 2471 2472 /**********************/ 2473 /* VideoObjectLayer() */ 2474 /**********************/ 2475 if (currVol->shortVideoHeader == 0) 2476 { /* M4V else Short Video Header */ 2477 status = BitstreamPutGT16Bits(stream, VOL_START_CODE_LENGTH, VOL_START_CODE); 2478 status = BitstreamPutBits(stream, 4, currVol->volID);/* video_object_layer_id */ 2479 status = BitstreamPut1Bits(stream, 0x00);/* Random Access = 0 */ 2480 2481 if (video->currLayer == 0) 2482 status = BitstreamPutBits(stream, 8, 0x01);/* Video Object Type Indication = 1 ... Simple Object Type */ 2483 else 2484 status = BitstreamPutBits(stream, 8, 0x02);/* Video Object Type Indication = 2 ... Simple Scalable Object Type */ 2485 2486 status = BitstreamPut1Bits(stream, 0x00);/* is_object_layer_identifer = 0 */ 2487 2488 2489 status = BitstreamPutBits(stream, 4, 0x01); /* aspect_ratio_info = 1 ... 1:1(Square) */ 2490 status = BitstreamPut1Bits(stream, 0x00);/* vol_control_parameters = 0 */ 2491 status = BitstreamPutBits(stream, 2, 0x00);/* video_object_layer_shape = 00 ... rectangular */ 2492 status = BitstreamPut1Bits(stream, 0x01);/* marker bit */ 2493 status = BitstreamPutGT8Bits(stream, 16, currVol->timeIncrementResolution);/* vop_time_increment_resolution */ 2494 status = BitstreamPut1Bits(stream, 0x01);/* marker bit */ 2495 status = BitstreamPut1Bits(stream, currVol->fixedVopRate);/* fixed_vop_rate = 0 */ 2496 2497 /* For Rectangular VO layer shape */ 2498 status = BitstreamPut1Bits(stream, 0x01);/* marker bit */ 2499 status = BitstreamPutGT8Bits(stream, 13, currVol->width);/* video_object_layer_width */ 2500 status = BitstreamPut1Bits(stream, 0x01);/* marker bit */ 2501 status = BitstreamPutGT8Bits(stream, 13, currVol->height);/* video_object_layer_height */ 2502 status = BitstreamPut1Bits(stream, 0x01);/*marker bit */ 2503 2504 status = BitstreamPut1Bits(stream, 0x00);/*interlaced = 0 */ 2505 status = BitstreamPut1Bits(stream, 0x01);/* obmc_disable = 1 */ 2506 status = BitstreamPut1Bits(stream, 0x00);/* sprite_enable = 0 */ 2507 status = BitstreamPut1Bits(stream, 0x00);/* not_8_bit = 0 */ 2508 status = BitstreamPut1Bits(stream, currVol->quantType);/* quant_type */ 2509 2510 if (currVol->quantType) 2511 { 2512 status = BitstreamPut1Bits(stream, currVol->loadIntraQuantMat); /* Intra quant matrix */ 2513 if (currVol->loadIntraQuantMat) 2514 { 2515 for (j = 63; j >= 1; j--) 2516 if (currVol->iqmat[*(zigzag_i+j)] != currVol->iqmat[*(zigzag_i+j-1)]) 2517 break; 2518 if ((j == 1) && (currVol->iqmat[*(zigzag_i+j)] == currVol->iqmat[*(zigzag_i+j-1)])) 2519 j = 0; 2520 for (i = 0; i < j + 1; i++) 2521 BitstreamPutBits(stream, 8, currVol->iqmat[*(zigzag_i+i)]); 2522 if (j < 63) 2523 BitstreamPutBits(stream, 8, 0); 2524 } 2525 else 2526 { 2527 for (j = 0; j < 64; j++) 2528 currVol->iqmat[j] = mpeg_iqmat_def[j]; 2529 2530 } 2531 status = BitstreamPut1Bits(stream, currVol->loadNonIntraQuantMat); /* Non-Intra quant matrix */ 2532 if (currVol->loadNonIntraQuantMat) 2533 { 2534 for (j = 63; j >= 1; j--) 2535 if (currVol->niqmat[*(zigzag_i+j)] != currVol->niqmat[*(zigzag_i+j-1)]) 2536 break; 2537 if ((j == 1) && (currVol->niqmat[*(zigzag_i+j)] == currVol->niqmat[*(zigzag_i+j-1)])) 2538 j = 0; 2539 for (i = 0; i < j + 1; i++) 2540 BitstreamPutBits(stream, 8, currVol->niqmat[*(zigzag_i+i)]); 2541 if (j < 63) 2542 BitstreamPutBits(stream, 8, 0); 2543 } 2544 else 2545 { 2546 for (j = 0; j < 64; j++) 2547 currVol->niqmat[j] = mpeg_nqmat_def[j]; 2548 } 2549 } 2550 2551 status = BitstreamPut1Bits(stream, 0x01); /* complexity_estimation_disable = 1 */ 2552 status = BitstreamPut1Bits(stream, currVol->ResyncMarkerDisable);/* Resync_marker_disable */ 2553 status = BitstreamPut1Bits(stream, currVol->dataPartitioning);/* Data partitioned */ 2554 2555 if (currVol->dataPartitioning) 2556 status = BitstreamPut1Bits(stream, currVol->useReverseVLC); /* Reversible_vlc */ 2557 2558 2559 if (currVol->scalability) /* Scalability*/ 2560 { 2561 2562 status = BitstreamPut1Bits(stream, currVol->scalability);/* Scalability = 1 */ 2563 status = BitstreamPut1Bits(stream, currVol->scalType);/* hierarchy _type ... Spatial= 0 and Temporal = 1 */ 2564 status = BitstreamPutBits(stream, 4, currVol->refVolID);/* ref_layer_id */ 2565 status = BitstreamPut1Bits(stream, currVol->refSampDir);/* ref_layer_sampling_direc*/ 2566 status = BitstreamPutBits(stream, 5, currVol->horSamp_n);/*hor_sampling_factor_n*/ 2567 status = BitstreamPutBits(stream, 5, currVol->horSamp_m);/*hor_sampling_factor_m*/ 2568 status = BitstreamPutBits(stream, 5, currVol->verSamp_n);/*vert_sampling_factor_n*/ 2569 status = BitstreamPutBits(stream, 5, currVol->verSamp_m);/*vert_sampling_factor_m*/ 2570 status = BitstreamPut1Bits(stream, currVol->enhancementType);/* enhancement_type*/ 2571 } 2572 else /* No Scalability */ 2573 status = BitstreamPut1Bits(stream, currVol->scalability);/* Scalability = 0 */ 2574 2575 /*temp = */ 2576 BitstreamMpeg4ByteAlignStuffing(stream); /* Byte align Headers for VOP */ 2577 } 2578 } 2579 2580 return status; 2581} 2582 2583/* ======================================================================== */ 2584/* Function : VOS_End() */ 2585/* Date : 08/22/2000 */ 2586/* Purpose : Visual Object Sequence End */ 2587/* In/out : */ 2588/* Return : PV_TRUE if successed, PV_FALSE if failed. */ 2589/* Modified : */ 2590/* */ 2591/* ======================================================================== */ 2592 2593PV_STATUS VOS_End(VideoEncControls *encoderControl) 2594{ 2595 PV_STATUS status = PV_SUCCESS; 2596 VideoEncData *video = (VideoEncData *)encoderControl->videoEncoderData; 2597 Vol *currVol = video->vol[video->currLayer]; 2598 BitstreamEncVideo *stream = currVol->stream; 2599 2600 2601 status = BitstreamPutBits(stream, SESSION_END_CODE, 32); 2602 2603 return status; 2604} 2605 2606/* ======================================================================== */ 2607/* Function : DetermineCodingLayer */ 2608/* Date : 06/02/2001 */ 2609/* Purpose : Find layer to code based on current mod time, assuming that 2610 it's time to encode enhanced layer. */ 2611/* In/out : */ 2612/* Return : Number of layer to code. */ 2613/* Modified : */ 2614/* */ 2615/* ======================================================================== */ 2616 2617Int DetermineCodingLayer(VideoEncData *video, Int *nLayer, ULong modTime) 2618{ 2619 Vol **vol = video->vol; 2620 VideoEncParams *encParams = video->encParams; 2621 Int numLayers = encParams->nLayers; 2622 UInt modTimeRef = video->modTimeRef; 2623 float *LayerFrameRate = encParams->LayerFrameRate; 2624 UInt frameNum[4], frameTick; 2625 ULong frameModTime, nextFrmModTime; 2626#ifdef REDUCE_FRAME_VARIANCE /* To limit how close 2 frames can be */ 2627 float frameInterval; 2628#endif 2629 float srcFrameInterval; 2630 Int frameInc; 2631 Int i, extra_skip; 2632 Int encodeVop = 0; 2633 2634 i = numLayers - 1; 2635 2636 if (modTime - video->nextModTime > ((ULong)(-1)) >> 1) /* next time wrapped around */ 2637 return 0; /* not time to code it yet */ 2638 2639 video->relLayerCodeTime[i] -= 1000; 2640 video->nextEncIVop--; /* number of Vops in highest layer resolution. */ 2641 video->numVopsInGOP++; 2642 2643 /* from this point frameModTime and nextFrmModTime are internal */ 2644 2645 frameNum[i] = (UInt)((modTime - modTimeRef) * LayerFrameRate[i] + 500) / 1000; 2646 if (video->volInitialize[i]) 2647 { 2648 video->prevFrameNum[i] = frameNum[i] - 1; 2649 } 2650 else if (frameNum[i] <= video->prevFrameNum[i]) 2651 { 2652 return 0; /* do not encode this frame */ 2653 } 2654 2655 /**** this part computes expected next frame *******/ 2656 frameModTime = (ULong)(((frameNum[i] * 1000) / LayerFrameRate[i]) + modTimeRef + 0.5); /* rec. time */ 2657 nextFrmModTime = (ULong)((((frameNum[i] + 1) * 1000) / LayerFrameRate[i]) + modTimeRef + 0.5); /* rec. time */ 2658 2659 srcFrameInterval = 1000 / video->FrameRate; 2660 2661 video->nextModTime = nextFrmModTime - (ULong)(srcFrameInterval / 2.) - 1; /* between current and next frame */ 2662 2663#ifdef REDUCE_FRAME_VARIANCE /* To limit how close 2 frames can be */ 2664 frameInterval = 1000 / LayerFrameRate[i]; /* next rec. time */ 2665 delta = (Int)(frameInterval / 4); /* empirical number */ 2666 if (video->nextModTime - modTime < (ULong)delta) /* need to move nextModTime further. */ 2667 { 2668 video->nextModTime += ((delta - video->nextModTime + modTime)); /* empirical formula */ 2669 } 2670#endif 2671 /****************************************************/ 2672 2673 /* map frame no.to tick from modTimeRef */ 2674 /*frameTick = (frameNum[i]*vol[i]->timeIncrementResolution) ; 2675 frameTick = (UInt)((frameTick + (encParams->LayerFrameRate[i]/2))/encParams->LayerFrameRate[i]);*/ 2676 /* 11/16/01, change frameTick to be the closest tick from the actual modTime */ 2677 /* 12/12/02, add (double) to prevent large number wrap-around */ 2678 frameTick = (Int)(((double)(modTime - modTimeRef) * vol[i]->timeIncrementResolution + 500) / 1000); 2679 2680 /* find timeIncrement to be put in the bitstream */ 2681 /* refTick is second boundary reference. */ 2682 vol[i]->timeIncrement = frameTick - video->refTick[i]; 2683 2684 2685 vol[i]->moduloTimeBase = 0; 2686 while (vol[i]->timeIncrement >= vol[i]->timeIncrementResolution) 2687 { 2688 vol[i]->timeIncrement -= vol[i]->timeIncrementResolution; 2689 vol[i]->moduloTimeBase++; 2690 /* do not update refTick and modTimeRef yet, do it after encoding!! */ 2691 } 2692 2693 if (video->relLayerCodeTime[i] <= 0) /* no skipping */ 2694 { 2695 encodeVop = 1; 2696 video->currLayer = *nLayer = i; 2697 video->relLayerCodeTime[i] += 1000; 2698 2699 /* takes care of more dropped frame than expected */ 2700 extra_skip = -1; 2701 frameInc = (frameNum[i] - video->prevFrameNum[i]); 2702 extra_skip += frameInc; 2703 2704 if (extra_skip > 0) 2705 { /* update rc->Nr, rc->B, (rc->Rr)*/ 2706 video->nextEncIVop -= extra_skip; 2707 video->numVopsInGOP += extra_skip; 2708 if (encParams->RC_Type != CONSTANT_Q) 2709 { 2710 RC_UpdateBuffer(video, i, extra_skip); 2711 } 2712 } 2713 2714 } 2715 /* update frame no. */ 2716 video->prevFrameNum[i] = frameNum[i]; 2717 2718 /* go through all lower layer */ 2719 for (i = (numLayers - 2); i >= 0; i--) 2720 { 2721 2722 video->relLayerCodeTime[i] -= 1000; 2723 2724 /* find timeIncrement to be put in the bitstream */ 2725 vol[i]->timeIncrement = frameTick - video->refTick[i]; 2726 2727 if (video->relLayerCodeTime[i] <= 0) /* time to encode base */ 2728 { 2729 /* 12/27/00 */ 2730 encodeVop = 1; 2731 video->currLayer = *nLayer = i; 2732 video->relLayerCodeTime[i] += 2733 (Int)((1000.0 * encParams->LayerFrameRate[numLayers-1]) / encParams->LayerFrameRate[i]); 2734 2735 vol[i]->moduloTimeBase = 0; 2736 while (vol[i]->timeIncrement >= vol[i]->timeIncrementResolution) 2737 { 2738 vol[i]->timeIncrement -= vol[i]->timeIncrementResolution; 2739 vol[i]->moduloTimeBase++; 2740 /* do not update refTick and modTimeRef yet, do it after encoding!! */ 2741 } 2742 2743 /* takes care of more dropped frame than expected */ 2744 frameNum[i] = (UInt)((frameModTime - modTimeRef) * encParams->LayerFrameRate[i] + 500) / 1000; 2745 if (video->volInitialize[i]) 2746 video->prevFrameNum[i] = frameNum[i] - 1; 2747 2748 extra_skip = -1; 2749 frameInc = (frameNum[i] - video->prevFrameNum[i]); 2750 extra_skip += frameInc; 2751 2752 if (extra_skip > 0) 2753 { /* update rc->Nr, rc->B, (rc->Rr)*/ 2754 if (encParams->RC_Type != CONSTANT_Q) 2755 { 2756 RC_UpdateBuffer(video, i, extra_skip); 2757 } 2758 } 2759 /* update frame no. */ 2760 video->prevFrameNum[i] = frameNum[i]; 2761 } 2762 } 2763 2764#ifdef _PRINT_STAT 2765 if (encodeVop) 2766 printf(" TI: %d ", vol[*nLayer]->timeIncrement); 2767#endif 2768 2769 return encodeVop; 2770} 2771 2772/* ======================================================================== */ 2773/* Function : DetermineVopType */ 2774/* Date : 06/02/2001 */ 2775/* Purpose : The name says it all. */ 2776/* In/out : */ 2777/* Return : void . */ 2778/* Modified : */ 2779/* */ 2780/* ======================================================================== */ 2781 2782void DetermineVopType(VideoEncData *video, Int currLayer) 2783{ 2784 VideoEncParams *encParams = video->encParams; 2785// Vol *currVol = video->vol[currLayer]; 2786 2787 if (encParams->IntraPeriod == 0) /* I-VOPs only */ 2788 { 2789 if (video->currLayer > 0) 2790 video->currVop->predictionType = P_VOP; 2791 else 2792 { 2793 video->currVop->predictionType = I_VOP; 2794 if (video->numVopsInGOP >= 132) 2795 video->numVopsInGOP = 0; 2796 } 2797 } 2798 else if (encParams->IntraPeriod == -1) /* IPPPPP... */ 2799 { 2800 2801 /* maintain frame type if previous frame is pre-skipped, 06/02/2001 */ 2802 if (encParams->RC_Type == CONSTANT_Q || video->rc[currLayer]->skip_next_frame != -1) 2803 video->currVop->predictionType = P_VOP; 2804 2805 if (video->currLayer == 0) 2806 { 2807 if (/*video->numVopsInGOP>=132 || */video->volInitialize[currLayer]) 2808 { 2809 video->currVop->predictionType = I_VOP; 2810 video->numVopsInGOP = 0; /* force INTRA update every 132 base frames*/ 2811 video->nextEncIVop = 1; 2812 } 2813 else if (video->nextEncIVop == 0 || video->currVop->predictionType == I_VOP) 2814 { 2815 video->numVopsInGOP = 0; 2816 video->nextEncIVop = 1; 2817 } 2818 } 2819 } 2820 else /* IntraPeriod>0 : IPPPPPIPPPPPI... */ 2821 { 2822 2823 /* maintain frame type if previous frame is pre-skipped, 06/02/2001 */ 2824 if (encParams->RC_Type == CONSTANT_Q || video->rc[currLayer]->skip_next_frame != -1) 2825 video->currVop->predictionType = P_VOP; 2826 2827 if (currLayer == 0) 2828 { 2829 if (video->nextEncIVop <= 0 || video->currVop->predictionType == I_VOP) 2830 { 2831 video->nextEncIVop = encParams->IntraPeriod; 2832 video->currVop->predictionType = I_VOP; 2833 video->numVopsInGOP = 0; 2834 } 2835 } 2836 } 2837 2838 return ; 2839} 2840 2841/* ======================================================================== */ 2842/* Function : UpdateSkipNextFrame */ 2843/* Date : 06/02/2001 */ 2844/* Purpose : From rate control frame skipping decision, update timing 2845 related parameters. */ 2846/* In/out : */ 2847/* Return : Current coded layer. */ 2848/* Modified : */ 2849/* */ 2850/* ======================================================================== */ 2851 2852Int UpdateSkipNextFrame(VideoEncData *video, ULong *modTime, Int *size, PV_STATUS status) 2853{ 2854 Int currLayer = video->currLayer; 2855 Int nLayer = currLayer; 2856 VideoEncParams *encParams = video->encParams; 2857 Int numLayers = encParams->nLayers; 2858 Vol *currVol = video->vol[currLayer]; 2859 Vol **vol = video->vol; 2860 Int num_skip, extra_skip; 2861 Int i; 2862 UInt newRefTick, deltaModTime; 2863 UInt temp; 2864 2865 if (encParams->RC_Type != CONSTANT_Q) 2866 { 2867 if (video->volInitialize[0] && currLayer == 0) /* always encode the first frame */ 2868 { 2869 RC_ResetSkipNextFrame(video, currLayer); 2870 //return currLayer; 09/15/05 2871 } 2872 else 2873 { 2874 if (RC_GetSkipNextFrame(video, currLayer) < 0 || status == PV_END_OF_BUF) /* Skip Current Frame */ 2875 { 2876 2877#ifdef _PRINT_STAT 2878 printf("Skip current frame"); 2879#endif 2880 currVol->moduloTimeBase = currVol->prevModuloTimeBase; 2881 2882 /*********************/ 2883 /* prepare to return */ 2884 /*********************/ 2885 *size = 0; /* Set Bitstream buffer to zero */ 2886 2887 /* Determine nLayer and modTime for next encode */ 2888 2889 *modTime = video->nextModTime; 2890 nLayer = -1; 2891 2892 return nLayer; /* return immediately without updating RefTick & modTimeRef */ 2893 /* If I-VOP was attempted, then ensure next base is I-VOP */ 2894 /*if((encParams->IntraPeriod>0) && (video->currVop->predictionType == I_VOP)) 2895 video->nextEncIVop = 0; commented out by 06/05/01 */ 2896 2897 } 2898 else if ((num_skip = RC_GetSkipNextFrame(video, currLayer)) > 0) 2899 { 2900 2901#ifdef _PRINT_STAT 2902 printf("Skip next %d frames", num_skip); 2903#endif 2904 /* to keep the Nr of enh layer the same */ 2905 /* adjust relLayerCodeTime only, do not adjust layerCodeTime[numLayers-1] */ 2906 extra_skip = 0; 2907 for (i = 0; i < currLayer; i++) 2908 { 2909 if (video->relLayerCodeTime[i] <= 1000) 2910 { 2911 extra_skip = 1; 2912 break; 2913 } 2914 } 2915 2916 for (i = currLayer; i < numLayers; i++) 2917 { 2918 video->relLayerCodeTime[i] += (num_skip + extra_skip) * 2919 ((Int)((1000.0 * encParams->LayerFrameRate[numLayers-1]) / encParams->LayerFrameRate[i])); 2920 } 2921 } 2922 }/* first frame */ 2923 } 2924 /***** current frame is encoded, now update refTick ******/ 2925 2926 video->refTick[currLayer] += vol[currLayer]->prevModuloTimeBase * vol[currLayer]->timeIncrementResolution; 2927 2928 /* Reset layerCodeTime every I-VOP to prevent overflow */ 2929 if (currLayer == 0) 2930 { 2931 /* 12/12/02, fix for weird targer frame rate of 9.99 fps or 3.33 fps */ 2932 if (((encParams->IntraPeriod != 0) /*&& (video->currVop->predictionType==I_VOP)*/) || 2933 ((encParams->IntraPeriod == 0) && (video->numVopsInGOP == 0))) 2934 { 2935 newRefTick = video->refTick[0]; 2936 2937 for (i = 1; i < numLayers; i++) 2938 { 2939 if (video->refTick[i] < newRefTick) 2940 newRefTick = video->refTick[i]; 2941 } 2942 2943 /* check to make sure that the update is integer multiple of frame number */ 2944 /* how many msec elapsed from last modTimeRef */ 2945 deltaModTime = (newRefTick / vol[0]->timeIncrementResolution) * 1000; 2946 2947 for (i = numLayers - 1; i >= 0; i--) 2948 { 2949 temp = (UInt)(deltaModTime * encParams->LayerFrameRate[i]); /* 12/12/02 */ 2950 if (temp % 1000) 2951 newRefTick = 0; 2952 2953 } 2954 if (newRefTick > 0) 2955 { 2956 video->modTimeRef += deltaModTime; 2957 for (i = numLayers - 1; i >= 0; i--) 2958 { 2959 video->prevFrameNum[i] -= (UInt)(deltaModTime * encParams->LayerFrameRate[i]) / 1000; 2960 video->refTick[i] -= newRefTick; 2961 } 2962 } 2963 } 2964 } 2965 2966 *modTime = video->nextModTime; 2967 2968 return nLayer; 2969} 2970 2971 2972#ifndef ORIGINAL_VERSION 2973 2974/* ======================================================================== */ 2975/* Function : SetProfile_BufferSize */ 2976/* Date : 04/08/2002 */ 2977/* Purpose : Set profile and video buffer size, copied from Jim's code */ 2978/* in PVInitVideoEncoder(.), since we have different places */ 2979/* to reset profile and video buffer size */ 2980/* In/out : */ 2981/* Return : */ 2982/* Modified : */ 2983/* */ 2984/* ======================================================================== */ 2985 2986Bool SetProfile_BufferSize(VideoEncData *video, float delay, Int bInitialized) 2987{ 2988 Int i, j, start, end; 2989// Int BaseMBsPerSec = 0, EnhMBsPerSec = 0; 2990 Int nTotalMB = 0; 2991 Int idx, temp_w, temp_h, max = 0, max_width, max_height; 2992 2993 Int nLayers = video->encParams->nLayers; /* Number of Layers to be encoded */ 2994 2995 Int total_bitrate = 0, base_bitrate; 2996 Int total_packet_size = 0, base_packet_size; 2997 Int total_MBsPerSec = 0, base_MBsPerSec; 2998 Int total_VBV_size = 0, base_VBV_size, enhance_VBV_size = 0; 2999 float total_framerate, base_framerate; 3000 float upper_bound_ratio; 3001 Int bFound = 0; 3002 Int k = 0, width16, height16, index; 3003 Int lowest_level; 3004 3005#define MIN_BUFF 16000 /* 16k minimum buffer size */ 3006#define BUFF_CONST 2.0 /* 2000ms */ 3007#define UPPER_BOUND_RATIO 8.54 /* upper_bound = 1.4*(1.1+bound/10)*bitrate/framerate */ 3008 3009#define QCIF_WIDTH 176 3010#define QCIF_HEIGHT 144 3011 3012 index = video->encParams->profile_table_index; 3013 3014 /* Calculate "nTotalMB" */ 3015 /* Find the maximum width*height for memory allocation of the VOPs */ 3016 for (idx = 0; idx < nLayers; idx++) 3017 { 3018 temp_w = video->encParams->LayerWidth[idx]; 3019 temp_h = video->encParams->LayerHeight[idx]; 3020 3021 if ((temp_w*temp_h) > max) 3022 { 3023 max = temp_w * temp_h; 3024 max_width = temp_w; 3025 max_height = temp_h; 3026 nTotalMB = ((max_width + 15) >> 4) * ((max_height + 15) >> 4); 3027 } 3028 } 3029 upper_bound_ratio = (video->encParams->RC_Type == CBR_LOWDELAY ? (float)5.0 : (float)UPPER_BOUND_RATIO); 3030 3031 3032 /* Get the basic information: bitrate, packet_size, MBs/s and VBV_size */ 3033 base_bitrate = video->encParams->LayerBitRate[0]; 3034 if (video->encParams->LayerMaxBitRate[0] != 0) /* video->encParams->LayerMaxBitRate[0] == 0 means it has not been set */ 3035 { 3036 base_bitrate = PV_MAX(base_bitrate, video->encParams->LayerMaxBitRate[0]); 3037 } 3038 else /* if the max is not set, set it to the specified profile/level */ 3039 { 3040 video->encParams->LayerMaxBitRate[0] = profile_level_max_bitrate[index]; 3041 } 3042 3043 base_framerate = video->encParams->LayerFrameRate[0]; 3044 if (video->encParams->LayerMaxFrameRate[0] != 0) 3045 { 3046 base_framerate = PV_MAX(base_framerate, video->encParams->LayerMaxFrameRate[0]); 3047 } 3048 else /* if the max is not set, set it to the specified profile/level */ 3049 { 3050 video->encParams->LayerMaxFrameRate[0] = (float)profile_level_max_mbsPerSec[index] / nTotalMB; 3051 } 3052 3053 base_packet_size = video->encParams->ResyncPacketsize; 3054 base_MBsPerSec = (Int)(base_framerate * nTotalMB); 3055 base_VBV_size = PV_MAX((Int)(base_bitrate * delay), 3056 (Int)(upper_bound_ratio * base_bitrate / base_framerate)); 3057 base_VBV_size = PV_MAX(base_VBV_size, MIN_BUFF); 3058 3059 /* if the buffer is larger than maximum buffer size, we'll clip it */ 3060 if (base_VBV_size > profile_level_max_VBV_size[5]) 3061 base_VBV_size = profile_level_max_VBV_size[5]; 3062 3063 3064 /* Check if the buffer exceeds the maximum buffer size given the maximum profile and level */ 3065 if (nLayers == 1 && base_VBV_size > profile_level_max_VBV_size[index]) 3066 return FALSE; 3067 3068 3069 if (nLayers == 2) 3070 { 3071 total_bitrate = video->encParams->LayerBitRate[1]; 3072 if (video->encParams->LayerMaxBitRate[1] != 0) 3073 { 3074 total_bitrate = PV_MIN(total_bitrate, video->encParams->LayerMaxBitRate[1]); 3075 } 3076 else /* if the max is not set, set it to the specified profile/level */ 3077 { 3078 video->encParams->LayerMaxBitRate[1] = scalable_profile_level_max_bitrate[index]; 3079 } 3080 3081 total_framerate = video->encParams->LayerFrameRate[1]; 3082 if (video->encParams->LayerMaxFrameRate[1] != 0) 3083 { 3084 total_framerate = PV_MIN(total_framerate, video->encParams->LayerMaxFrameRate[1]); 3085 } 3086 else /* if the max is not set, set it to the specified profile/level */ 3087 { 3088 video->encParams->LayerMaxFrameRate[1] = (float)scalable_profile_level_max_mbsPerSec[index] / nTotalMB; 3089 } 3090 3091 total_packet_size = video->encParams->ResyncPacketsize; 3092 total_MBsPerSec = (Int)(total_framerate * nTotalMB); 3093 3094 enhance_VBV_size = PV_MAX((Int)((total_bitrate - base_bitrate) * delay), 3095 (Int)(upper_bound_ratio * (total_bitrate - base_bitrate) / (total_framerate - base_framerate))); 3096 enhance_VBV_size = PV_MAX(enhance_VBV_size, MIN_BUFF); 3097 3098 total_VBV_size = base_VBV_size + enhance_VBV_size; 3099 3100 /* if the buffer is larger than maximum buffer size, we'll clip it */ 3101 if (total_VBV_size > scalable_profile_level_max_VBV_size[6]) 3102 { 3103 total_VBV_size = scalable_profile_level_max_VBV_size[6]; 3104 enhance_VBV_size = total_VBV_size - base_VBV_size; 3105 } 3106 3107 /* Check if the buffer exceeds the maximum buffer size given the maximum profile and level */ 3108 if (total_VBV_size > scalable_profile_level_max_VBV_size[index]) 3109 return FALSE; 3110 } 3111 3112 3113 if (!bInitialized) /* Has been initialized --> profile @ level has been figured out! */ 3114 { 3115 video->encParams->BufferSize[0] = base_VBV_size; 3116 if (nLayers > 1) 3117 video->encParams->BufferSize[1] = enhance_VBV_size; 3118 3119 return PV_TRUE; 3120 } 3121 3122 3123 /* Profile @ level determination */ 3124 if (nLayers == 1) 3125 { 3126 /* BASE ONLY : Simple Profile(SP) Or Core Profile(CP) */ 3127 if (base_bitrate > profile_level_max_bitrate[index] || 3128 base_packet_size > profile_level_max_packet_size[index] || 3129 base_MBsPerSec > profile_level_max_mbsPerSec[index] || 3130 base_VBV_size > profile_level_max_VBV_size[index]) 3131 3132 return PV_FALSE; /* Beyond the bound of Core Profile @ Level2 */ 3133 3134 /* For H263/Short header, determine k*16384 */ 3135 width16 = ((video->encParams->LayerWidth[0] + 15) >> 4) << 4; 3136 height16 = ((video->encParams->LayerHeight[0] + 15) >> 4) << 4; 3137 if (video->encParams->H263_Enabled) 3138 { 3139 k = 4; 3140 if (width16 == 2*QCIF_WIDTH && height16 == 2*QCIF_HEIGHT) /* CIF */ 3141 k = 16; 3142 3143 else if (width16 == 4*QCIF_WIDTH && height16 == 4*QCIF_HEIGHT) /* 4CIF */ 3144 k = 32; 3145 3146 else if (width16 == 8*QCIF_WIDTH && height16 == 8*QCIF_HEIGHT) /* 16CIF */ 3147 k = 64; 3148 3149 video->encParams->maxFrameSize = k * 16384; 3150 3151 /* Make sure the buffer size is limited to the top profile and level: the Core profile and level 2 */ 3152 if (base_VBV_size > (Int)(k*16384 + 4*(float)profile_level_max_bitrate[5]*1001.0 / 30000.0)) 3153 base_VBV_size = (Int)(k * 16384 + 4 * (float)profile_level_max_bitrate[5] * 1001.0 / 30000.0); 3154 3155 if (base_VBV_size > (Int)(k*16384 + 4*(float)profile_level_max_bitrate[index]*1001.0 / 30000.0)) 3156 return PV_FALSE; 3157 } 3158 3159 /* Search the appropriate profile@level index */ 3160 if (!video->encParams->H263_Enabled && 3161 (video->encParams->IntraDCVlcThr != 0 || video->encParams->SearchRange > 16)) 3162 { 3163 lowest_level = 1; /* cannot allow SPL0 */ 3164 } 3165 else 3166 { 3167 lowest_level = 0; /* SPL0 */ 3168 } 3169 3170 for (i = lowest_level; i <= index; i++) 3171 { 3172 if (i != 4 && /* skip Core Profile@Level1 because the parameters in it are smaller than those in Simple Profile@Level3 */ 3173 base_bitrate <= profile_level_max_bitrate[i] && 3174 base_packet_size <= profile_level_max_packet_size[i] && 3175 base_MBsPerSec <= profile_level_max_mbsPerSec[i] && 3176 base_VBV_size <= (video->encParams->H263_Enabled ? (Int)(k*16384 + 4*(float)profile_level_max_bitrate[i]*1001.0 / 30000.0) : 3177 profile_level_max_VBV_size[i])) 3178 break; 3179 } 3180 if (i > index) return PV_FALSE; /* Nothing found!! */ 3181 3182 /* Found out the actual profile @ level : index "i" */ 3183 if (i == 0) 3184 { 3185 /* For Simple Profile @ Level 0, we need to do one more check: image size <= QCIF */ 3186 if (width16 > QCIF_WIDTH || height16 > QCIF_HEIGHT) 3187 i = 1; /* image size > QCIF, then set SP level1 */ 3188 } 3189 3190 video->encParams->ProfileLevel[0] = profile_level_code[i]; 3191 video->encParams->BufferSize[0] = base_VBV_size; 3192 3193 if (video->encParams->LayerMaxBitRate[0] == 0) 3194 video->encParams->LayerMaxBitRate[0] = profile_level_max_bitrate[i]; 3195 3196 if (video->encParams->LayerMaxFrameRate[0] == 0) 3197 video->encParams->LayerMaxFrameRate[0] = PV_MIN(30, (float)profile_level_max_mbsPerSec[i] / nTotalMB); 3198 3199 /* For H263/Short header, one special constraint for VBV buffer size */ 3200 if (video->encParams->H263_Enabled) 3201 video->encParams->BufferSize[0] = (Int)(k * 16384 + 4 * (float)profile_level_max_bitrate[i] * 1001.0 / 30000.0); 3202 3203 } 3204 else 3205 { 3206 /* SCALABALE MODE: Simple Scalable Profile(SSP) Or Core Scalable Profile(CSP) */ 3207 3208 if (total_bitrate > scalable_profile_level_max_bitrate[index] || 3209 total_packet_size > scalable_profile_level_max_packet_size[index] || 3210 total_MBsPerSec > scalable_profile_level_max_mbsPerSec[index] || 3211 total_VBV_size > scalable_profile_level_max_VBV_size[index]) 3212 3213 return PV_FALSE; /* Beyond given profile and level */ 3214 3215 /* One-time check: Simple Scalable Profile or Core Scalable Profile */ 3216 if (total_bitrate <= scalable_profile_level_max_bitrate[2] && 3217 total_packet_size <= scalable_profile_level_max_packet_size[2] && 3218 total_MBsPerSec <= scalable_profile_level_max_mbsPerSec[2] && 3219 total_VBV_size <= scalable_profile_level_max_VBV_size[2]) 3220 3221 { 3222 start = 0; 3223 end = index; 3224 } 3225 3226 else 3227 { 3228 start = 4; 3229 end = index; 3230 } 3231 3232 3233 /* Search the scalable profile */ 3234 for (i = start; i <= end; i++) 3235 { 3236 if (total_bitrate <= scalable_profile_level_max_bitrate[i] && 3237 total_packet_size <= scalable_profile_level_max_packet_size[i] && 3238 total_MBsPerSec <= scalable_profile_level_max_mbsPerSec[i] && 3239 total_VBV_size <= scalable_profile_level_max_VBV_size[i]) 3240 3241 break; 3242 } 3243 if (i > end) return PV_FALSE; 3244 3245 /* Search the base profile */ 3246 if (i == 0) 3247 { 3248 j = 0; 3249 bFound = 1; 3250 } 3251 else bFound = 0; 3252 3253 for (j = start; !bFound && j <= i; j++) 3254 { 3255 if (base_bitrate <= profile_level_max_bitrate[j] && 3256 base_packet_size <= profile_level_max_packet_size[j] && 3257 base_MBsPerSec <= profile_level_max_mbsPerSec[j] && 3258 base_VBV_size <= profile_level_max_VBV_size[j]) 3259 3260 { 3261 bFound = 1; 3262 break; 3263 } 3264 } 3265 3266 if (!bFound) // && start == 4) 3267 return PV_FALSE; /* mis-match in the profiles between base layer and enhancement layer */ 3268 3269 /* j for base layer, i for enhancement layer */ 3270 video->encParams->ProfileLevel[0] = profile_level_code[j]; 3271 video->encParams->ProfileLevel[1] = scalable_profile_level_code[i]; 3272 video->encParams->BufferSize[0] = base_VBV_size; 3273 video->encParams->BufferSize[1] = enhance_VBV_size; 3274 3275 if (video->encParams->LayerMaxBitRate[0] == 0) 3276 video->encParams->LayerMaxBitRate[0] = profile_level_max_bitrate[j]; 3277 3278 if (video->encParams->LayerMaxBitRate[1] == 0) 3279 video->encParams->LayerMaxBitRate[1] = scalable_profile_level_max_bitrate[i]; 3280 3281 if (video->encParams->LayerMaxFrameRate[0] == 0) 3282 video->encParams->LayerMaxFrameRate[0] = PV_MIN(30, (float)profile_level_max_mbsPerSec[j] / nTotalMB); 3283 3284 if (video->encParams->LayerMaxFrameRate[1] == 0) 3285 video->encParams->LayerMaxFrameRate[1] = PV_MIN(30, (float)scalable_profile_level_max_mbsPerSec[i] / nTotalMB); 3286 3287 3288 } /* end of: if(nLayers == 1) */ 3289 3290 3291 if (!video->encParams->H263_Enabled && (video->encParams->ProfileLevel[0] == 0x08)) /* SPL0 restriction*/ 3292 { 3293 /* PV only allow frame-based rate control, no QP change from one MB to another 3294 if(video->encParams->ACDCPrediction == TRUE && MB-based rate control) 3295 return PV_FALSE */ 3296 } 3297 3298 return PV_TRUE; 3299} 3300 3301#endif /* #ifndef ORIGINAL_VERSION */ 3302 3303 3304 3305