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 /* ======================================================================== */
EncodeVop(VideoEncData * video)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
EncodeVop_NoME(VideoEncData * video)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
EncodeSlice(VideoEncData * video)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 /* ======================================================================== */
EncodeGOVHeader(BitstreamEncVideo * stream,UInt seconds)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
EncodeVopNotCoded(VideoEncData * video,UChar * bstream,Int * size,ULong modTime)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
EncodeVOPHeader(BitstreamEncVideo * stream,Vol * currVol,Vop * currVop)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
EncodeShortHeader(BitstreamEncVideo * stream,Vop * currVop)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 /* ======================================================================== */
EncodeVideoPacketHeader(VideoEncData * video,int MB_number,int quant_scale,Int insert)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