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 "mp4enc_lib.h" 20 #include "mp4lib_int.h" 21 #include "bitstream_io.h" 22 #include "vlc_encode.h" 23 #include "m4venc_oscl.h" 24 25 PV_STATUS EncodeGOBHeader(VideoEncData *video, Int GOB_number, Int quant_scale, Int bs1stream); 26 27 /* ======================================================================== */ 28 /* Function : EncodeFrameCombinedMode() */ 29 /* Date : 09/01/2000 */ 30 /* History : */ 31 /* Purpose : Encode a frame of MPEG4 bitstream in Combined mode. */ 32 /* In/out : */ 33 /* Return : PV_SUCCESS if successful else PV_FAIL */ 34 /* Modified : */ 35 /* */ 36 /* ======================================================================== */ 37 PV_STATUS EncodeFrameCombinedMode(VideoEncData *video) 38 { 39 PV_STATUS status = PV_SUCCESS; 40 Vol *currVol = video->vol[video->currLayer]; 41 Vop *currVop = video->currVop; 42 VideoEncParams *encParams = video->encParams; 43 Int width = currVop->width; /* has to be Vop, for multiple of 16 */ 44 Int lx = currVop->pitch; /* with padding */ 45 Int offset = 0; 46 Int ind_x, ind_y; 47 Int start_packet_header = 0; 48 UChar *QPMB = video->QPMB; 49 Int QP; 50 Int mbnum = 0, slice_counter = 0, curr_slice_counter = 0; 51 Int num_bits, packet_size = encParams->ResyncPacketsize; 52 Int GOB_Header_Interval = encParams->GOB_Header_Interval; 53 BitstreamEncVideo *bs1 = video->bitstream1; 54 Int numHeaderBits; 55 approxDCT fastDCTfunction; 56 Int ncoefblck[6] = {64, 64, 64, 64, 64, 64}; /* for FastCodeMB, 5/18/2001 */ 57 PV_STATUS(*CodeMB)(VideoEncData *, approxDCT *, Int, Int[]); 58 void (*MBVlcEncode)(VideoEncData*, Int[], void *); 59 void (*BlockCodeCoeff)(RunLevelBlock*, BitstreamEncVideo*, Int, Int, UChar); 60 61 /* for H263 GOB changes */ 62 //MP4RateControlType rc_type = encParams->RC_Type; 63 64 video->QP_prev = currVop->quantizer; 65 66 numHeaderBits = BitstreamGetPos(bs1); 67 68 /* determine type of quantization */ 69 #ifndef NO_MPEG_QUANT 70 if (currVol->quantType == 0) 71 CodeMB = &CodeMB_H263; 72 else 73 CodeMB = &CodeMB_MPEG; 74 #else 75 CodeMB = &CodeMB_H263; 76 #endif 77 78 /* determine which functions to be used, in MB-level */ 79 if (currVop->predictionType == P_VOP) 80 MBVlcEncode = &MBVlcEncodeCombined_P_VOP; 81 else if (currVop->predictionType == I_VOP) 82 MBVlcEncode = &MBVlcEncodeCombined_I_VOP; 83 else /* B_VOP not implemented yet */ 84 return PV_FAIL; 85 86 /* determine which VLC table to be used */ 87 #ifndef H263_ONLY 88 if (currVol->shortVideoHeader) 89 BlockCodeCoeff = &BlockCodeCoeff_ShortHeader; 90 #ifndef NO_RVLC 91 else if (currVol->useReverseVLC) 92 BlockCodeCoeff = &BlockCodeCoeff_RVLC; 93 #endif 94 else 95 BlockCodeCoeff = &BlockCodeCoeff_Normal; 96 #else 97 BlockCodeCoeff = &BlockCodeCoeff_ShortHeader; 98 #endif 99 100 /* gob_frame_id is the same for different vop types - the reason should be SCD */ 101 if (currVol->shortVideoHeader && currVop->gobFrameID != currVop->predictionType) 102 currVop->gobFrameID = currVop->predictionType; 103 104 105 video->usePrevQP = 0; 106 107 for (ind_y = 0; ind_y < currVol->nMBPerCol; ind_y++) /* Col MB Loop */ 108 { 109 110 video->outputMB->mb_y = ind_y; /* 5/28/01 */ 111 112 if (currVol->shortVideoHeader) /* ShortVideoHeader Mode */ 113 { 114 115 if (slice_counter && GOB_Header_Interval && (ind_y % GOB_Header_Interval == 0)) /* Encode GOB Header */ 116 { 117 QP = QPMB[mbnum]; /* Get quant_scale */ 118 video->header_bits -= BitstreamGetPos(currVol->stream); /* Header Bits */ 119 status = EncodeGOBHeader(video, slice_counter, QP, 0); //ind_y /* Encode GOB Header */ 120 video->header_bits += BitstreamGetPos(currVol->stream); /* Header Bits */ 121 curr_slice_counter = slice_counter; 122 } 123 } 124 125 for (ind_x = 0; ind_x < currVol->nMBPerRow; ind_x++) /* Row MB Loop */ 126 { 127 video->outputMB->mb_x = ind_x; /* 5/28/01 */ 128 video->mbnum = mbnum; 129 QP = QPMB[mbnum]; /* always read new QP */ 130 131 if (GOB_Header_Interval) 132 video->sliceNo[mbnum] = curr_slice_counter; /* Update MB slice number */ 133 else 134 video->sliceNo[mbnum] = slice_counter; 135 136 /****************************************************************************************/ 137 /* MB Prediction:Put into MC macroblock, substract from currVop, put in predMB */ 138 /****************************************************************************************/ 139 getMotionCompensatedMB(video, ind_x, ind_y, offset); 140 141 #ifndef H263_ONLY 142 if (start_packet_header) 143 { 144 slice_counter++; /* Increment slice counter */ 145 video->sliceNo[mbnum] = slice_counter; /* Update MB slice number*/ 146 video->header_bits -= BitstreamGetPos(bs1); /* Header Bits */ 147 video->QP_prev = currVop->quantizer; 148 status = EncodeVideoPacketHeader(video, mbnum, video->QP_prev, 0); 149 video->header_bits += BitstreamGetPos(bs1); /* Header Bits */ 150 numHeaderBits = BitstreamGetPos(bs1); 151 start_packet_header = 0; 152 video->usePrevQP = 0; 153 } 154 #endif 155 /***********************************************/ 156 /* Code_MB: DCT, Q, Q^(-1), IDCT, Motion Comp */ 157 /***********************************************/ 158 159 status = (*CodeMB)(video, &fastDCTfunction, (offset << 5) + QP, ncoefblck); 160 161 /************************************/ 162 /* MB VLC Encode: VLC Encode MB */ 163 /************************************/ 164 165 (*MBVlcEncode)(video, ncoefblck, (void*)BlockCodeCoeff); 166 167 /*************************************************************/ 168 /* Assemble Packets: Assemble the MB VLC codes into Packets */ 169 /*************************************************************/ 170 171 /* Assemble_Packet(video) */ 172 #ifndef H263_ONLY 173 if (!currVol->shortVideoHeader) /* Not in ShortVideoHeader mode */ 174 { 175 if (!currVol->ResyncMarkerDisable) /* RESYNC MARKER MODE */ 176 { 177 num_bits = BitstreamGetPos(bs1) - numHeaderBits; 178 if (num_bits > packet_size) 179 { 180 video->header_bits += BitstreamMpeg4ByteAlignStuffing(bs1); /* Byte align Packet */ 181 182 status = BitstreamAppendPacket(currVol->stream, bs1); /* Put Packet to Buffer */ 183 /* continue even if status == PV_END_OF_BUF, to get the stats */ 184 185 BitstreamEncReset(bs1); 186 187 start_packet_header = 1; 188 } 189 } 190 else /* NO RESYNC MARKER MODE */ 191 { 192 status = BitstreamAppendEnc(currVol->stream, bs1); /* Initialize to 0 */ 193 /* continue even if status == PV_END_OF_BUF, to get the stats */ 194 195 BitstreamEncReset(bs1); 196 } 197 } 198 else 199 #endif /* H263_ONLY */ 200 { /* ShortVideoHeader Mode */ 201 status = BitstreamAppendEnc(currVol->stream, bs1); /* Initialize to 0 */ 202 /* continue even if status == PV_END_OF_BUF, to get the stats */ 203 204 BitstreamEncReset(bs1); 205 } 206 mbnum++; 207 offset += 16; 208 } /* End of For ind_x */ 209 210 offset += (lx << 4) - width; 211 if (currVol->shortVideoHeader) /* ShortVideoHeader = 1 */ 212 { 213 214 if (GOB_Header_Interval) slice_counter++; 215 } 216 217 } /* End of For ind_y */ 218 219 if (currVol->shortVideoHeader) /* ShortVideoHeader = 1 */ 220 { 221 222 video->header_bits += BitstreamShortHeaderByteAlignStuffing(currVol->stream); /* Byte Align */ 223 } 224 #ifndef H263_ONLY 225 else /* Combined Mode*/ 226 { 227 if (!currVol->ResyncMarkerDisable) /* Resync Markers */ 228 { 229 230 if (!start_packet_header) 231 { 232 video->header_bits += BitstreamMpeg4ByteAlignStuffing(bs1);/* Byte Align */ 233 234 status = BitstreamAppendPacket(currVol->stream, bs1); /* Put Packet to Buffer */ 235 /* continue even if status == PV_END_OF_BUF, to get the stats */ 236 237 BitstreamEncReset(bs1); 238 } 239 } 240 else /* No Resync Markers */ 241 { 242 video->header_bits += BitstreamMpeg4ByteAlignStuffing(currVol->stream); /* Byte Align */ 243 } 244 } 245 #endif /* H263_ONLY */ 246 247 return status; /* if status == PV_END_OF_BUF, this frame will be pre-skipped */ 248 } 249 250 #ifndef NO_SLICE_ENCODE 251 /* ======================================================================== */ 252 /* Function : EncodeSliceCombinedMode() */ 253 /* Date : 04/19/2002 */ 254 /* History : */ 255 /* Purpose : Encode a slice of MPEG4 bitstream in Combined mode and save */ 256 /* the current MB to continue next time it is called. */ 257 /* In/out : */ 258 /* Return : PV_SUCCESS if successful else PV_FAIL */ 259 /* Modified : */ 260 /* */ 261 /* ======================================================================== */ 262 PV_STATUS EncodeSliceCombinedMode(VideoEncData *video) 263 { 264 PV_STATUS status = PV_SUCCESS; 265 Vol *currVol = video->vol[video->currLayer]; 266 Vop *currVop = video->currVop; 267 UChar mode = MODE_INTRA; 268 UChar *Mode = video->headerInfo.Mode; 269 VideoEncParams *encParams = video->encParams; 270 Int nTotalMB = currVol->nTotalMB; 271 Int width = currVop->width; /* has to be Vop, for multiple of 16 */ 272 Int lx = currVop->pitch; /* , with padding */ 273 // rateControl *rc = encParams->rc[video->currLayer]; 274 UChar *QPMB = video->QPMB; 275 Int QP; 276 Int ind_x = video->outputMB->mb_x, ind_y = video->outputMB->mb_y; 277 Int offset = video->offset; /* get current MB location */ 278 Int mbnum = video->mbnum, slice_counter = video->sliceNo[mbnum]; /* get current MB location */ 279 Int firstMB = mbnum; 280 Int start_packet_header = 0; 281 Int num_bits = 0; 282 Int packet_size = encParams->ResyncPacketsize - 1; 283 Int resync_marker = ((!currVol->shortVideoHeader) && (!currVol->ResyncMarkerDisable)); 284 BitstreamEncVideo *bs1 = video->bitstream1; 285 Int byteCount = 0, byteCount1 = 0, bitCount = 0; 286 Int numHeaderBits = 0; 287 approxDCT fastDCTfunction; 288 Int ncoefblck[6] = {64, 64, 64, 64, 64, 64}; /* for FastCodeMB, 5/18/2001 */ 289 UChar CBP = 0; 290 Short outputMB[6][64]; 291 Int k; 292 PV_STATUS(*CodeMB)(VideoEncData *, approxDCT *, Int, Int[]); 293 void (*MBVlcEncode)(VideoEncData*, Int[], void *); 294 void (*BlockCodeCoeff)(RunLevelBlock*, BitstreamEncVideo*, Int, Int, UChar); 295 296 video->QP_prev = 31; 297 298 #define H263_GOB_CHANGES 299 300 301 if (video->end_of_buf) /* left-over from previous run */ 302 { 303 status = BitstreamAppendPacketNoOffset(currVol->stream, bs1); 304 if (status != PV_END_OF_BUF) 305 { 306 BitstreamEncReset(bs1); 307 video->end_of_buf = 0; 308 } 309 return status; 310 } 311 312 313 if (mbnum == 0) /* only do this at the start of a frame */ 314 { 315 QPMB[0] = video->QP_prev = QP = currVop->quantizer; 316 video->usePrevQP = 0; 317 318 numHeaderBits = BitstreamGetPos(bs1); 319 } 320 321 /* Re-assign fast functions on every slice, don't have to put it in the memory */ 322 QP = QPMB[mbnum]; 323 if (mbnum > 0) video->QP_prev = QPMB[mbnum-1]; 324 325 /* determine type of quantization */ 326 #ifndef NO_MPEG_QUANT 327 if (currVol->quantType == 0) 328 CodeMB = &CodeMB_H263; 329 else 330 CodeMB = &CodeMB_MPEG; 331 #else 332 CodeMB = &CodeMB_H263; 333 #endif 334 335 /* determine which functions to be used, in MB-level */ 336 if (currVop->predictionType == P_VOP) 337 MBVlcEncode = &MBVlcEncodeCombined_P_VOP; 338 else if (currVop->predictionType == I_VOP) 339 MBVlcEncode = &MBVlcEncodeCombined_I_VOP; 340 else /* B_VOP not implemented yet */ 341 return PV_FAIL; 342 343 /* determine which VLC table to be used */ 344 #ifndef H263_ONLY 345 if (currVol->shortVideoHeader) 346 BlockCodeCoeff = &BlockCodeCoeff_ShortHeader; 347 #ifndef NO_RVLC 348 else if (currVol->useReverseVLC) 349 BlockCodeCoeff = &BlockCodeCoeff_RVLC; 350 #endif 351 else 352 BlockCodeCoeff = &BlockCodeCoeff_Normal; 353 #else 354 BlockCodeCoeff = &BlockCodeCoeff_ShortHeader; 355 #endif 356 357 /* (gob_frame_id is the same for different vop types) The reason should be SCD */ 358 if (currVol->shortVideoHeader && currVop->gobFrameID != currVop->predictionType) 359 currVop->gobFrameID = currVop->predictionType; 360 361 362 if (mbnum != 0) 363 { 364 if (currVol->shortVideoHeader) 365 { 366 /* Encode GOB Header */ 367 bitCount = BitstreamGetPos(bs1); 368 byteCount1 = byteCount = bitCount >> 3; /* save the position before GOB header */ 369 bitCount = bitCount & 0x7; 370 371 #ifdef H263_GOB_CHANGES 372 video->header_bits -= BitstreamGetPos(bs1); /* Header Bits */ 373 status = EncodeGOBHeader(video, slice_counter, QP, 1); //ind_y /* Encode GOB Header */ 374 video->header_bits += BitstreamGetPos(bs1); /* Header Bits */ 375 #endif 376 goto JUMP_IN_SH; 377 } 378 else if (currVol->ResyncMarkerDisable) 379 { 380 goto JUMP_IN_SH; 381 } 382 else 383 { 384 start_packet_header = 1; 385 goto JUMP_IN; 386 } 387 } 388 389 for (ind_y = 0; ind_y < currVol->nMBPerCol; ind_y++) /* Col MB Loop */ 390 { 391 392 video->outputMB->mb_y = ind_y; /* 5/28/01, do not remove */ 393 394 for (ind_x = 0; ind_x < currVol->nMBPerRow; ind_x++) /* Row MB Loop */ 395 { 396 397 video->outputMB->mb_x = ind_x; /* 5/28/01, do not remove */ 398 video->mbnum = mbnum; 399 video->sliceNo[mbnum] = slice_counter; /* Update MB slice number */ 400 JUMP_IN_SH: 401 /****************************************************************************************/ 402 /* MB Prediction:Put into MC macroblock, substract from currVop, put in predMB */ 403 /****************************************************************************************/ 404 getMotionCompensatedMB(video, ind_x, ind_y, offset); 405 406 JUMP_IN: 407 QP = QPMB[mbnum]; /* always read new QP */ 408 #ifndef H263_ONLY 409 if (start_packet_header) 410 { 411 slice_counter++; /* Increment slice counter */ 412 video->sliceNo[mbnum] = slice_counter; /* Update MB slice number*/ 413 video->QP_prev = currVop->quantizer; /* store QP */ 414 num_bits = BitstreamGetPos(bs1); 415 status = EncodeVideoPacketHeader(video, mbnum, video->QP_prev, 1); 416 numHeaderBits = BitstreamGetPos(bs1) - num_bits; 417 video->header_bits += numHeaderBits; /* Header Bits */ 418 start_packet_header = 0; 419 video->usePrevQP = 0; 420 } 421 else /* don't encode the first MB in packet again */ 422 #endif /* H263_ONLY */ 423 { 424 /***********************************************/ 425 /* Code_MB: DCT, Q, Q^(-1), IDCT, Motion Comp */ 426 /***********************************************/ 427 status = (*CodeMB)(video, &fastDCTfunction, (offset << 5) + QP, ncoefblck); 428 } 429 430 /************************************/ 431 /* MB VLC Encode: VLC Encode MB */ 432 /************************************/ 433 434 /* save the state before VLC encoding */ 435 if (resync_marker) 436 { 437 bitCount = BitstreamGetPos(bs1); 438 byteCount = bitCount >> 3; /* save the state before encoding */ 439 bitCount = bitCount & 0x7; 440 mode = Mode[mbnum]; 441 CBP = video->headerInfo.CBP[mbnum]; 442 for (k = 0; k < 6; k++) 443 { 444 M4VENC_MEMCPY(outputMB[k], video->outputMB->block[k], sizeof(Short) << 6); 445 } 446 } 447 /*************************************/ 448 449 (*MBVlcEncode)(video, ncoefblck, (void*)BlockCodeCoeff); 450 451 /*************************************************************/ 452 /* Assemble Packets: Assemble the MB VLC codes into Packets */ 453 /*************************************************************/ 454 455 /* Assemble_Packet(video) */ 456 #ifndef H263_ONLY 457 if (!currVol->shortVideoHeader) 458 { 459 if (!currVol->ResyncMarkerDisable) 460 { 461 /* Not in ShortVideoHeader mode and RESYNC MARKER MODE */ 462 463 num_bits = BitstreamGetPos(bs1) ;//- numHeaderBits; // include header 464 465 /* Assemble packet and return when size reached */ 466 if (num_bits > packet_size && mbnum != firstMB) 467 { 468 469 BitstreamRepos(bs1, byteCount, bitCount); /* rewind one MB */ 470 471 video->header_bits += BitstreamMpeg4ByteAlignStuffing(bs1); /* Byte align Packet */ 472 473 status = BitstreamAppendPacketNoOffset(currVol->stream, bs1); /* Put Packet to Buffer */ 474 475 if (status == PV_END_OF_BUF) 476 { 477 video->end_of_buf = 1; 478 } 479 else 480 { 481 BitstreamEncReset(bs1); 482 } 483 484 start_packet_header = 1; 485 486 if (mbnum < nTotalMB || video->end_of_buf) /* return here */ 487 { 488 video->mbnum = mbnum; 489 video->sliceNo[mbnum] = slice_counter; 490 video->offset = offset; 491 Mode[mbnum] = mode; 492 video->headerInfo.CBP[mbnum] = CBP; 493 494 for (k = 0; k < 6; k++) 495 { 496 M4VENC_MEMCPY(video->outputMB->block[k], outputMB[k], sizeof(Short) << 6); 497 } 498 499 return status; 500 } 501 } 502 } 503 else /* NO RESYNC MARKER , return when buffer is full*/ 504 { 505 506 if (mbnum < nTotalMB - 1 && currVol->stream->byteCount + bs1->byteCount + 1 >= currVol->stream->bufferSize) 507 { 508 /* find maximum bytes to fit in the buffer */ 509 byteCount = currVol->stream->bufferSize - currVol->stream->byteCount - 1; 510 511 num_bits = BitstreamGetPos(bs1) - (byteCount << 3); 512 BitstreamRepos(bs1, byteCount, 0); 513 status = BitstreamAppendPacketNoOffset(currVol->stream, bs1); 514 BitstreamFlushBits(bs1, num_bits); 515 516 /* move on to next MB */ 517 mbnum++ ; 518 offset += 16; 519 video->outputMB->mb_x++; 520 if (video->outputMB->mb_x >= currVol->nMBPerRow) 521 { 522 video->outputMB->mb_x = 0; 523 video->outputMB->mb_y++; 524 offset += (lx << 4) - width; 525 } 526 video->mbnum = mbnum; 527 video->offset = offset; 528 video->sliceNo[mbnum] = slice_counter; 529 return status; 530 } 531 } 532 } 533 #endif /* H263_ONLY */ 534 offset += 16; 535 mbnum++; /* has to increment before SCD, to preserve Mode[mbnum] */ 536 537 } /* End of For ind_x */ 538 539 offset += (lx << 4) - width; 540 541 if (currVol->shortVideoHeader) /* ShortVideoHeader = 1 */ 542 { 543 #ifdef H263_GOB_CHANGES 544 slice_counter++; 545 video->header_bits += BitstreamShortHeaderByteAlignStuffing(bs1); 546 #endif 547 //video->header_bits+=BitstreamShortHeaderByteAlignStuffing(bs1); 548 549 /* check if time to packetize */ 550 if (currVol->stream->byteCount + bs1->byteCount > currVol->stream->bufferSize) 551 { 552 if (byteCount == byteCount1) /* a single GOB bigger than packet size */ 553 { 554 status = BitstreamAppendPacketNoOffset(currVol->stream, bs1); 555 status = PV_END_OF_BUF; 556 video->end_of_buf = 1; 557 start_packet_header = 1; 558 } 559 else /* for short_header scooch back to previous GOB */ 560 { 561 num_bits = ((bs1->byteCount - byteCount) << 3); 562 //num_bits = ((bs1->byteCount<<3) + bs1->bitCount) - ((byteCount<<3) + bitCount); 563 BitstreamRepos(bs1, byteCount, 0); 564 //BitstreamRepos(bs1,byteCount,bitCount); 565 // k = currVol->stream->byteCount; /* save state before appending */ 566 status = BitstreamAppendPacketNoOffset(currVol->stream, bs1); 567 BitstreamFlushBits(bs1, num_bits); 568 // if(mbnum == nTotalMB || k + bs1->byteCount >= currVol->stream->bufferSize){ 569 /* last GOB or current one with larger size will be returned next run */ 570 // status = PV_END_OF_BUF; 571 // video->end_of_buf = 1; 572 // } 573 start_packet_header = 1; 574 if (mbnum == nTotalMB) /* there's one more GOB to packetize for the next round */ 575 { 576 status = PV_END_OF_BUF; 577 video->end_of_buf = 1; 578 } 579 } 580 581 if (mbnum < nTotalMB) /* return here */ 582 { 583 /* move on to next MB */ 584 video->outputMB->mb_x = 0; 585 video->outputMB->mb_y++; 586 video->mbnum = mbnum; 587 video->offset = offset; 588 video->sliceNo[mbnum] = slice_counter; 589 return status; 590 } 591 } 592 else if (mbnum < nTotalMB) /* do not write GOB header if end of vop */ 593 { 594 bitCount = BitstreamGetPos(bs1); 595 byteCount = bitCount >> 3; /* save the position before GOB header */ 596 bitCount = bitCount & 0x7; 597 #ifdef H263_GOB_CHANGES 598 video->header_bits -= BitstreamGetPos(bs1); /* Header Bits */ 599 status = EncodeGOBHeader(video, slice_counter, QP, 1); /* Encode GOB Header */ 600 video->header_bits += BitstreamGetPos(bs1); /* Header Bits */ 601 #endif 602 } 603 } 604 605 } /* End of For ind_y */ 606 #ifndef H263_ONLY 607 if (!currVol->shortVideoHeader) /* Combined Mode*/ 608 { 609 if (!currVol->ResyncMarkerDisable) /* Resync Markers */ 610 { 611 612 if (!start_packet_header) 613 { 614 615 video->header_bits += BitstreamMpeg4ByteAlignStuffing(bs1);/* Byte Align */ 616 617 status = BitstreamAppendPacketNoOffset(currVol->stream, bs1); /* Put Packet to Buffer */ 618 if (status == PV_END_OF_BUF) 619 { 620 video->end_of_buf = 1; 621 } 622 else 623 { 624 BitstreamEncReset(bs1); 625 } 626 } 627 } 628 else /* No Resync Markers */ 629 { 630 video->header_bits += BitstreamMpeg4ByteAlignStuffing(bs1); /* Byte Align */ 631 status = BitstreamAppendPacketNoOffset(currVol->stream, bs1); /* Initialize to 0 */ 632 if (status == PV_END_OF_BUF) 633 { 634 video->end_of_buf = 1; 635 } 636 else 637 { 638 BitstreamEncReset(bs1); 639 } 640 } 641 } 642 else 643 #endif /* H263_ONLY */ 644 { 645 if (!start_packet_header) /* not yet packetized */ 646 { 647 video->header_bits += BitstreamShortHeaderByteAlignStuffing(bs1); 648 status = BitstreamAppendPacketNoOffset(currVol->stream, bs1); 649 if (status == PV_END_OF_BUF) 650 { 651 video->end_of_buf = 1; 652 } 653 else 654 { 655 BitstreamEncReset(bs1); 656 video->end_of_buf = 0; 657 } 658 } 659 } 660 661 video->mbnum = mbnum; 662 if (mbnum < nTotalMB) 663 video->sliceNo[mbnum] = slice_counter; 664 video->offset = offset; 665 666 return status; 667 } 668 #endif /* NO_SLICE_ENCODE */ 669 670 /* ======================================================================== */ 671 /* Function : EncodeGOBHeader() */ 672 /* Date : 09/05/2000 */ 673 /* History : */ 674 /* Purpose : Encode a frame of MPEG4 bitstream in Combined mode. */ 675 /* In/out : */ 676 /* Return : PV_SUCCESS if successful else PV_FAIL */ 677 /* Modified : */ 678 /* */ 679 /* ======================================================================== */ 680 681 PV_STATUS EncodeGOBHeader(VideoEncData *video, Int GOB_number, Int quant_scale, Int bs1stream) 682 { 683 PV_STATUS status = PV_SUCCESS; 684 BitstreamEncVideo *stream = (bs1stream ? video->bitstream1 : video->vol[video->currLayer]->stream); 685 686 status = BitstreamPutGT16Bits(stream, 17, GOB_RESYNC_MARKER); /* gob_resync_marker */ 687 status = BitstreamPutBits(stream, 5, GOB_number); /* Current gob_number */ 688 status = BitstreamPutBits(stream, 2, video->currVop->gobFrameID); /* gob_frame_id */ 689 status = BitstreamPutBits(stream, 5, quant_scale); /* quant_scale */ 690 return status; 691 } 692 693 694