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 /* ======================================================================== */
EncodeFrameCombinedMode(VideoEncData * video)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 /* ======================================================================== */
EncodeSliceCombinedMode(VideoEncData * video)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
EncodeGOBHeader(VideoEncData * video,Int GOB_number,Int quant_scale,Int bs1stream)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