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