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 #include "mp4def.h" 19 #include "mp4lib_int.h" 20 #include "mp4enc_lib.h" 21 #include "bitstream_io.h" 22 #include "m4venc_oscl.h" 23 24 PV_STATUS EncodeShortHeader(BitstreamEncVideo *stream, Vop *currVop); 25 PV_STATUS EncodeVOPHeader(BitstreamEncVideo *stream, Vol *currVol, Vop *currVop); 26 PV_STATUS EncodeGOVHeader(BitstreamEncVideo *stream, UInt seconds); 27 28 PV_STATUS EncodeVop_BXRC(VideoEncData *video); 29 PV_STATUS EncodeVop_NoME(VideoEncData *video); 30 31 /* ======================================================================== */ 32 /* Function : DecodeVop() */ 33 /* Date : 08/23/2000 */ 34 /* Purpose : Encode VOP Header */ 35 /* In/out : */ 36 /* Return : */ 37 /* Modified : */ 38 /* ======================================================================== */ 39 PV_STATUS EncodeVop(VideoEncData *video) 40 { 41 42 PV_STATUS status; 43 Int currLayer = video->currLayer; 44 Vol *currVol = video->vol[currLayer]; 45 Vop *currVop = video->currVop; 46 // BitstreamEncVideo *stream=video->bitstream1; 47 UChar *Mode = video->headerInfo.Mode; 48 rateControl **rc = video->rc; 49 // UInt time=0; 50 51 /*******************/ 52 /* Initialize mode */ 53 /*******************/ 54 55 switch (currVop->predictionType) 56 { 57 case I_VOP: 58 M4VENC_MEMSET(Mode, MODE_INTRA, sizeof(UChar)*currVol->nTotalMB); 59 break; 60 case P_VOP: 61 M4VENC_MEMSET(Mode, MODE_INTER, sizeof(UChar)*currVol->nTotalMB); 62 break; 63 case B_VOP: 64 /*M4VENC_MEMSET(Mode, MODE_INTER_B,sizeof(UChar)*nTotalMB);*/ 65 return PV_FAIL; 66 default: 67 return PV_FAIL; 68 } 69 70 /*********************/ 71 /* Motion Estimation */ 72 /* compute MVs, scene change detection, edge padding, */ 73 /* intra refresh, compute block activity */ 74 /*********************/ 75 MotionEstimation(video); /* do ME for the whole frame */ 76 77 /***************************/ 78 /* rate Control (assign QP) */ 79 /* 4/11/01, clean-up, and put into a separate function */ 80 /***************************/ 81 status = RC_VopQPSetting(video, rc); 82 if (status == PV_FAIL) 83 return PV_FAIL; 84 85 /**********************/ 86 /* Encode VOP */ 87 /**********************/ 88 if (video->slice_coding) /* end here */ 89 { 90 /* initialize state variable for slice-based APIs */ 91 video->totalSAD = 0; 92 video->mbnum = 0; 93 video->sliceNo[0] = 0; 94 video->numIntra = 0; 95 video->offset = 0; 96 video->end_of_buf = 0; 97 video->hp_guess = -1; 98 return status; 99 } 100 101 status = EncodeVop_NoME(video); 102 103 /******************************/ 104 /* rate control (update stat) */ 105 /* 6/2/01 separate function */ 106 /******************************/ 107 108 RC_VopUpdateStat(video, rc[currLayer]); 109 110 return status; 111 } 112 113 /* ======================================================================== */ 114 /* Function : EncodeVop_NoME() */ 115 /* Date : 08/28/2001 */ 116 /* History : */ 117 /* Purpose : EncodeVop without motion est. */ 118 /* In/out : */ 119 /* Return : */ 120 /* Modified : */ 121 /* */ 122 /* ======================================================================== */ 123 124 PV_STATUS EncodeVop_NoME(VideoEncData *video) 125 { 126 Vop *currVop = video->currVop; 127 Vol *currVol = video->vol[video->currLayer]; 128 BitstreamEncVideo *stream = video->bitstream1; 129 Int time = 0; /* follows EncodeVop value */ 130 PV_STATUS status = PV_SUCCESS; 131 132 if (currVol->shortVideoHeader) /* Short Video Header = 1 */ 133 { 134 135 status = EncodeShortHeader(stream, currVop); /* Encode Short Header */ 136 137 video->header_bits = BitstreamGetPos(stream); /* Header Bits */ 138 139 status = EncodeFrameCombinedMode(video); 140 141 } 142 #ifndef H263_ONLY 143 else /* Short Video Header = 0 */ 144 { 145 146 if (currVol->GOVStart && currVop->predictionType == I_VOP) 147 status = EncodeGOVHeader(stream, time); /* Encode GOV Header */ 148 149 status = EncodeVOPHeader(stream, currVol, currVop); /* Encode VOP Header */ 150 151 video->header_bits = BitstreamGetPos(stream); /* Header Bits */ 152 153 if (currVop->vopCoded) 154 { 155 if (!currVol->scalability) 156 { 157 if (currVol->dataPartitioning) 158 { 159 status = EncodeFrameDataPartMode(video); /* Encode Data Partitioning Mode VOP */ 160 } 161 else 162 { 163 status = EncodeFrameCombinedMode(video); /* Encode Combined Mode VOP */ 164 } 165 } 166 else 167 status = EncodeFrameCombinedMode(video); /* Encode Combined Mode VOP */ 168 } 169 else /* Vop Not coded */ 170 { 171 172 return status; 173 } 174 } 175 #endif /* H263_ONLY */ 176 return status; 177 178 } 179 180 #ifndef NO_SLICE_ENCODE 181 /* ======================================================================== */ 182 /* Function : EncodeSlice() */ 183 /* Date : 04/19/2002 */ 184 /* History : */ 185 /* Purpose : Encode one slice. */ 186 /* In/out : */ 187 /* Return : */ 188 /* Modified : */ 189 /* */ 190 /* ======================================================================== */ 191 192 PV_STATUS EncodeSlice(VideoEncData *video) 193 { 194 Vop *currVop = video->currVop; 195 Int currLayer = video->currLayer; 196 Vol *currVol = video->vol[currLayer]; 197 BitstreamEncVideo *stream = video->bitstream1; /* different from frame-based */ 198 Int time = 0; /* follows EncodeVop value */ 199 PV_STATUS status = PV_SUCCESS; 200 rateControl **rc = video->rc; 201 202 if (currVol->shortVideoHeader) /* Short Video Header = 1 */ 203 { 204 205 if (video->mbnum == 0) 206 { 207 status = EncodeShortHeader(stream, currVop); /* Encode Short Header */ 208 209 video->header_bits = BitstreamGetPos(stream); /* Header Bits */ 210 } 211 212 status = EncodeSliceCombinedMode(video); 213 214 } 215 #ifndef H263_ONLY 216 else /* Short Video Header = 0 */ 217 { 218 219 if (video->mbnum == 0) 220 { 221 if (currVol->GOVStart) 222 status = EncodeGOVHeader(stream, time); /* Encode GOV Header */ 223 224 status = EncodeVOPHeader(stream, currVol, currVop); /* Encode VOP Header */ 225 226 video->header_bits = BitstreamGetPos(stream); /* Header Bits */ 227 } 228 229 if (currVop->vopCoded) 230 { 231 if (!currVol->scalability) 232 { 233 if (currVol->dataPartitioning) 234 { 235 status = EncodeSliceDataPartMode(video); /* Encode Data Partitioning Mode VOP */ 236 } 237 else 238 { 239 status = EncodeSliceCombinedMode(video); /* Encode Combined Mode VOP */ 240 } 241 } 242 else 243 status = EncodeSliceCombinedMode(video); /* Encode Combined Mode VOP */ 244 } 245 else /* Vop Not coded */ 246 { 247 248 return status; 249 } 250 } 251 #endif /* H263_ONLY */ 252 if (video->mbnum >= currVol->nTotalMB && status != PV_END_OF_BUF) /* end of Vop */ 253 { 254 /******************************/ 255 /* rate control (update stat) */ 256 /* 6/2/01 separate function */ 257 /******************************/ 258 259 status = RC_VopUpdateStat(video, rc[currLayer]); 260 } 261 262 return status; 263 264 } 265 #endif /* NO_SLICE_ENCODE */ 266 267 #ifndef H263_ONLY 268 /* ======================================================================== */ 269 /* Function : EncodeGOVHeader() */ 270 /* Date : 08/23/2000 */ 271 /* Purpose : Encode GOV Header */ 272 /* In/out : */ 273 /* Return : */ 274 /* Modified : */ 275 /* ======================================================================== */ 276 PV_STATUS EncodeGOVHeader(BitstreamEncVideo *stream, UInt seconds) 277 { 278 PV_STATUS status; 279 // int temp; 280 UInt tmpvar; 281 282 /********************************/ 283 /* Group_of_VideoObjectPlane() */ 284 /********************************/ 285 286 status = BitstreamPutGT16Bits(stream, 32, GROUP_START_CODE); 287 /* time_code */ 288 tmpvar = seconds / 3600; 289 status = BitstreamPutBits(stream, 5, tmpvar); /* Hours*/ 290 291 tmpvar = (seconds - tmpvar * 3600) / 60; 292 status = BitstreamPutBits(stream, 6, tmpvar); /* Minutes*/ 293 294 status = BitstreamPut1Bits(stream, 1); /* Marker*/ 295 296 tmpvar = seconds % 60; 297 status = BitstreamPutBits(stream, 6, tmpvar); /* Seconds*/ 298 299 status = BitstreamPut1Bits(stream, 1); /* closed_gov */ 300 status = BitstreamPut1Bits(stream, 0); /* broken_link */ 301 /*temp =*/ 302 BitstreamMpeg4ByteAlignStuffing(stream); /* Byte align GOV Header */ 303 304 return status; 305 } 306 307 #ifdef ALLOW_VOP_NOT_CODED 308 309 PV_STATUS EncodeVopNotCoded(VideoEncData *video, UChar *bstream, Int *size, ULong modTime) 310 { 311 PV_STATUS status; 312 Vol *currVol = video->vol[0]; 313 Vop *currVop = video->currVop; 314 BitstreamEncVideo *stream = currVol->stream; 315 UInt frameTick; 316 Int timeInc; 317 318 stream->bitstreamBuffer = bstream; 319 stream->bufferSize = *size; 320 BitstreamEncReset(stream); 321 322 status = BitstreamPutGT16Bits(stream, 32, VOP_START_CODE); /*Start Code for VOP*/ 323 status = BitstreamPutBits(stream, 2, P_VOP);/* VOP Coding Type*/ 324 325 frameTick = (Int)(((double)(modTime - video->modTimeRef) * currVol->timeIncrementResolution + 500) / 1000); 326 timeInc = frameTick - video->refTick[0]; 327 while (timeInc >= currVol->timeIncrementResolution) 328 { 329 timeInc -= currVol->timeIncrementResolution; 330 status = BitstreamPut1Bits(stream, 1); 331 /* do not update refTick and modTimeRef yet, do it after encoding!! */ 332 } 333 status = BitstreamPut1Bits(stream, 0); 334 status = BitstreamPut1Bits(stream, 1); /* marker bit */ 335 status = BitstreamPutBits(stream, currVol->nbitsTimeIncRes, timeInc); /* vop_time_increment */ 336 status = BitstreamPut1Bits(stream, 1); /* marker bit */ 337 status = BitstreamPut1Bits(stream, 0); /* vop_coded bit */ 338 BitstreamMpeg4ByteAlignStuffing(stream); 339 340 return status; 341 } 342 #endif 343 344 /* ======================================================================== */ 345 /* Function : EncodeVOPHeader() */ 346 /* Date : 08/23/2000 */ 347 /* Purpose : Encode VOP Header */ 348 /* In/out : */ 349 /* Return : */ 350 /* Modified : */ 351 /* ======================================================================== */ 352 353 PV_STATUS EncodeVOPHeader(BitstreamEncVideo *stream, Vol *currVol, Vop *currVop) 354 { 355 PV_STATUS status; 356 //int temp; 357 358 int MTB = currVol->moduloTimeBase; 359 /************************/ 360 /* VideoObjectPlane() */ 361 /************************/ 362 363 status = BitstreamPutGT16Bits(stream, 32, VOP_START_CODE); /*Start Code for VOP*/ 364 status = BitstreamPutBits(stream, 2, currVop->predictionType);/* VOP Coding Type*/ 365 366 currVol->prevModuloTimeBase = currVol->moduloTimeBase; 367 368 while (MTB) 369 { 370 status = BitstreamPut1Bits(stream, 1); 371 MTB--; 372 } 373 status = BitstreamPut1Bits(stream, 0); 374 375 status = BitstreamPut1Bits(stream, 1); /* marker bit */ 376 status = BitstreamPutBits(stream, currVol->nbitsTimeIncRes, currVop->timeInc); /* vop_time_increment */ 377 status = BitstreamPut1Bits(stream, 1); /* marker bit */ 378 status = BitstreamPut1Bits(stream, currVop->vopCoded); /* vop_coded bit */ 379 if (currVop->vopCoded == 0) 380 { 381 /*temp =*/ 382 BitstreamMpeg4ByteAlignStuffing(stream); /* Byte align VOP Header */ 383 return status; 384 } 385 if (currVop->predictionType == P_VOP) 386 status = BitstreamPut1Bits(stream, currVop->roundingType); /* vop_rounding_type */ 387 388 status = BitstreamPutBits(stream, 3, currVop->intraDCVlcThr); /* intra_dc_vlc_thr */ 389 status = BitstreamPutBits(stream, 5, currVop->quantizer); /* vop_quant */ 390 391 if (currVop->predictionType != I_VOP) 392 status = BitstreamPutBits(stream, 3, currVop->fcodeForward); /* vop_fcode_forward */ 393 if (currVop->predictionType == B_VOP) 394 status = BitstreamPutBits(stream, 3, currVop->fcodeBackward);/* vop_fcode_backward */ 395 396 if (currVol->scalability) 397 /* enhancement_type = 0 */ 398 status = BitstreamPutBits(stream, 2, currVop->refSelectCode); /* ref_select_code */ 399 400 return status; 401 } 402 #endif /* H263_ONLY */ 403 /* ======================================================================== */ 404 /* Function : EncodeShortHeader() */ 405 /* Date : 08/23/2000 */ 406 /* Purpose : Encode VOP Header */ 407 /* In/out : */ 408 /* Return : */ 409 /* Modified : */ 410 /* ======================================================================== */ 411 412 PV_STATUS EncodeShortHeader(BitstreamEncVideo *stream, Vop *currVop) 413 { 414 415 PV_STATUS status; 416 417 status = BitstreamPutGT16Bits(stream, 22, SHORT_VIDEO_START_MARKER); /* Short_video_start_marker */ 418 status = BitstreamPutBits(stream, 8, currVop->temporalRef); /* temporal_reference */ 419 status = BitstreamPut1Bits(stream, 1); /* marker bit */ 420 status = BitstreamPut1Bits(stream, 0); /* zero bit */ 421 status = BitstreamPut1Bits(stream, 0); /* split_screen_indicator=0*/ 422 status = BitstreamPut1Bits(stream, 0); /* document_camera_indicator=0*/ 423 status = BitstreamPut1Bits(stream, 0); /* full_picture_freeze_release=0*/ 424 425 switch (currVop->width) 426 { 427 case 128: 428 if (currVop->height == 96) 429 status = BitstreamPutBits(stream, 3, 1); /* source_format = 1 */ 430 else 431 { 432 status = PV_FAIL; 433 return status; 434 } 435 break; 436 437 case 176: 438 if (currVop->height == 144) 439 status = BitstreamPutBits(stream, 3, 2); /* source_format = 2 */ 440 else 441 { 442 status = PV_FAIL; 443 return status; 444 } 445 break; 446 447 case 352: 448 if (currVop->height == 288) 449 status = BitstreamPutBits(stream, 3, 3); /* source_format = 3 */ 450 else 451 { 452 status = PV_FAIL; 453 return status; 454 } 455 break; 456 457 case 704: 458 if (currVop->height == 576) 459 status = BitstreamPutBits(stream, 3, 4); /* source_format = 4 */ 460 else 461 { 462 status = PV_FAIL; 463 return status; 464 } 465 break; 466 467 case 1408: 468 if (currVop->height == 1152) 469 status = BitstreamPutBits(stream, 3, 5); /* source_format = 5 */ 470 else 471 { 472 status = PV_FAIL; 473 return status; 474 } 475 break; 476 477 default: 478 status = PV_FAIL; 479 return status; 480 } 481 482 483 status = BitstreamPut1Bits(stream, currVop->predictionType); /* picture_coding type */ 484 status = BitstreamPutBits(stream, 4, 0); /* four_reserved_zero_bits */ 485 status = BitstreamPutBits(stream, 5, currVop->quantizer); /* vop_quant*/ 486 status = BitstreamPut1Bits(stream, 0); /* zero_bit*/ 487 status = BitstreamPut1Bits(stream, 0); /* pei=0 */ 488 489 return status; 490 } 491 492 #ifndef H263_ONLY 493 /* ======================================================================== */ 494 /* Function : EncodeVideoPacketHeader() */ 495 /* Date : 09/05/2000 */ 496 /* History : */ 497 /* Purpose : Encode a frame of MPEG4 bitstream in Combined mode. */ 498 /* In/out : */ 499 /* Return : */ 500 /* Modified : 04/25/2002 */ 501 /* Add bitstream structure as input argument */ 502 /* */ 503 /* ======================================================================== */ 504 PV_STATUS EncodeVideoPacketHeader(VideoEncData *video, int MB_number, 505 int quant_scale, Int insert) 506 { 507 // PV_STATUS status=PV_SUCCESS; 508 int fcode; 509 Vop *currVop = video->currVop; 510 Vol *currVol = video->vol[video->currLayer]; 511 BitstreamEncVideo *bs, tmp; 512 UChar buffer[30]; 513 514 if (insert) /* insert packet header to the beginning of bs1 */ 515 { 516 tmp.bitstreamBuffer = buffer; /* use temporary buffer */ 517 tmp.bufferSize = 30; 518 BitstreamEncReset(&tmp); 519 bs = &tmp; 520 } 521 else 522 bs = video->bitstream1; 523 524 525 if (currVop->predictionType == I_VOP) 526 BitstreamPutGT16Bits(bs, 17, 1); /* resync_marker I_VOP */ 527 else if (currVop->predictionType == P_VOP) 528 { 529 fcode = currVop->fcodeForward; 530 BitstreamPutGT16Bits(bs, 16 + fcode, 1); /* resync_marker P_VOP */ 531 532 } 533 else 534 { 535 fcode = currVop->fcodeForward; 536 if (currVop->fcodeBackward > fcode) 537 fcode = currVop->fcodeBackward; 538 BitstreamPutGT16Bits(bs, 16 + fcode, 1); /* resync_marker B_VOP */ 539 } 540 541 BitstreamPutBits(bs, currVol->nBitsForMBID, MB_number); /* resync_marker */ 542 BitstreamPutBits(bs, 5, quant_scale); /* quant_scale */ 543 BitstreamPut1Bits(bs, 0); /* header_extension_code = 0 */ 544 545 if (0) /* header_extension_code = 1 */ 546 { 547 /* NEED modulo_time_base code here ... default 0x01 belo*/ 548 /*status =*/ 549 BitstreamPut1Bits(bs, 1); 550 /*status = */ 551 BitstreamPut1Bits(bs, 0); 552 553 /*status = */ 554 BitstreamPut1Bits(bs, 1); /* marker bit */ 555 /*status = */ 556 BitstreamPutBits(bs, currVol->nbitsTimeIncRes, currVop->timeInc); /* vop_time_increment */ 557 /*status = */ 558 BitstreamPut1Bits(bs, 1); /* marker bit */ 559 560 /*status = */ 561 BitstreamPutBits(bs, 2, currVop->predictionType);/* VOP Coding Type*/ 562 563 /*status = */ 564 BitstreamPutBits(bs, 3, currVop->intraDCVlcThr); /* intra_dc_vlc_thr */ 565 566 if (currVop->predictionType != I_VOP) 567 /*status = */ BitstreamPutBits(bs, 3, currVop->fcodeForward); 568 if (currVop->predictionType == B_VOP) 569 /*status = */ BitstreamPutBits(bs, 3, currVop->fcodeBackward); 570 } 571 #ifndef NO_SLICE_ENCODE 572 if (insert) 573 BitstreamPrependPacket(video->bitstream1, bs); 574 #endif 575 return PV_SUCCESS; 576 } 577 578 #endif /* H263_ONLY */ 579 580 581 582