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