1 /* ------------------------------------------------------------------
2 * Copyright (C) 1998-2009 PacketVideo
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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
14 * See the License for the specific language governing permissions
15 * and limitations under the License.
16 * -------------------------------------------------------------------
19 #include "mp4lib_int.h"
20 #include "mp4enc_lib.h"
21 #include "bitstream_io.h"
22 #include "m4venc_oscl.h"
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);
28 PV_STATUS EncodeVop_BXRC(VideoEncData *video);
29 PV_STATUS EncodeVop_NoME(VideoEncData *video);
31 /* ======================================================================== */
32 /* Function : DecodeVop() */
33 /* Date : 08/23/2000 */
34 /* Purpose : Encode VOP Header */
38 /* ======================================================================== */
39 PV_STATUS EncodeVop(VideoEncData *video)
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;
55 switch (currVop->predictionType)
58 M4VENC_MEMSET(Mode, MODE_INTRA, sizeof(UChar)*currVol->nTotalMB);
61 M4VENC_MEMSET(Mode, MODE_INTER, sizeof(UChar)*currVol->nTotalMB);
64 /*M4VENC_MEMSET(Mode, MODE_INTER_B,sizeof(UChar)*nTotalMB);*/
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 */
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)
85 /**********************/
87 /**********************/
88 if (video->slice_coding) /* end here */
90 /* initialize state variable for slice-based APIs */
93 video->sliceNo[0] = 0;
96 video->end_of_buf = 0;
101 status = EncodeVop_NoME(video);
103 /******************************/
104 /* rate control (update stat) */
105 /* 6/2/01 separate function */
106 /******************************/
108 RC_VopUpdateStat(video, rc[currLayer]);
113 /* ======================================================================== */
114 /* Function : EncodeVop_NoME() */
115 /* Date : 08/28/2001 */
117 /* Purpose : EncodeVop without motion est. */
122 /* ======================================================================== */
124 PV_STATUS EncodeVop_NoME(VideoEncData *video)
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;
132 if (currVol->shortVideoHeader) /* Short Video Header = 1 */
135 status = EncodeShortHeader(stream, currVop); /* Encode Short Header */
137 video->header_bits = BitstreamGetPos(stream); /* Header Bits */
139 status = EncodeFrameCombinedMode(video);
143 else /* Short Video Header = 0 */
146 if (currVol->GOVStart && currVop->predictionType == I_VOP)
147 status = EncodeGOVHeader(stream, time); /* Encode GOV Header */
149 status = EncodeVOPHeader(stream, currVol, currVop); /* Encode VOP Header */
151 video->header_bits = BitstreamGetPos(stream); /* Header Bits */
153 if (currVop->vopCoded)
155 if (!currVol->scalability)
157 if (currVol->dataPartitioning)
159 status = EncodeFrameDataPartMode(video); /* Encode Data Partitioning Mode VOP */
163 status = EncodeFrameCombinedMode(video); /* Encode Combined Mode VOP */
167 status = EncodeFrameCombinedMode(video); /* Encode Combined Mode VOP */
169 else /* Vop Not coded */
175 #endif /* H263_ONLY */
180 #ifndef NO_SLICE_ENCODE
181 /* ======================================================================== */
182 /* Function : EncodeSlice() */
183 /* Date : 04/19/2002 */
185 /* Purpose : Encode one slice. */
190 /* ======================================================================== */
192 PV_STATUS EncodeSlice(VideoEncData *video)
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;
202 if (currVol->shortVideoHeader) /* Short Video Header = 1 */
205 if (video->mbnum == 0)
207 status = EncodeShortHeader(stream, currVop); /* Encode Short Header */
209 video->header_bits = BitstreamGetPos(stream); /* Header Bits */
212 status = EncodeSliceCombinedMode(video);
216 else /* Short Video Header = 0 */
219 if (video->mbnum == 0)
221 if (currVol->GOVStart)
222 status = EncodeGOVHeader(stream, time); /* Encode GOV Header */
224 status = EncodeVOPHeader(stream, currVol, currVop); /* Encode VOP Header */
226 video->header_bits = BitstreamGetPos(stream); /* Header Bits */
229 if (currVop->vopCoded)
231 if (!currVol->scalability)
233 if (currVol->dataPartitioning)
235 status = EncodeSliceDataPartMode(video); /* Encode Data Partitioning Mode VOP */
239 status = EncodeSliceCombinedMode(video); /* Encode Combined Mode VOP */
243 status = EncodeSliceCombinedMode(video); /* Encode Combined Mode VOP */
245 else /* Vop Not coded */
251 #endif /* H263_ONLY */
252 if (video->mbnum >= currVol->nTotalMB && status != PV_END_OF_BUF) /* end of Vop */
254 /******************************/
255 /* rate control (update stat) */
256 /* 6/2/01 separate function */
257 /******************************/
259 status = RC_VopUpdateStat(video, rc[currLayer]);
265 #endif /* NO_SLICE_ENCODE */
268 /* ======================================================================== */
269 /* Function : EncodeGOVHeader() */
270 /* Date : 08/23/2000 */
271 /* Purpose : Encode GOV Header */
275 /* ======================================================================== */
276 PV_STATUS EncodeGOVHeader(BitstreamEncVideo *stream, UInt seconds)
282 /********************************/
283 /* Group_of_VideoObjectPlane() */
284 /********************************/
286 status = BitstreamPutGT16Bits(stream, 32, GROUP_START_CODE);
288 tmpvar = seconds / 3600;
289 status = BitstreamPutBits(stream, 5, tmpvar); /* Hours*/
291 tmpvar = (seconds - tmpvar * 3600) / 60;
292 status = BitstreamPutBits(stream, 6, tmpvar); /* Minutes*/
294 status = BitstreamPut1Bits(stream, 1); /* Marker*/
296 tmpvar = seconds % 60;
297 status = BitstreamPutBits(stream, 6, tmpvar); /* Seconds*/
299 status = BitstreamPut1Bits(stream, 1); /* closed_gov */
300 status = BitstreamPut1Bits(stream, 0); /* broken_link */
302 BitstreamMpeg4ByteAlignStuffing(stream); /* Byte align GOV Header */
307 #ifdef ALLOW_VOP_NOT_CODED
309 PV_STATUS EncodeVopNotCoded(VideoEncData *video, UChar *bstream, Int *size, ULong modTime)
312 Vol *currVol = video->vol[0];
313 Vop *currVop = video->currVop;
314 BitstreamEncVideo *stream = currVol->stream;
318 stream->bitstreamBuffer = bstream;
319 stream->bufferSize = *size;
320 BitstreamEncReset(stream);
322 status = BitstreamPutGT16Bits(stream, 32, VOP_START_CODE); /*Start Code for VOP*/
323 status = BitstreamPutBits(stream, 2, P_VOP);/* VOP Coding Type*/
325 frameTick = (Int)(((double)(modTime - video->modTimeRef) * currVol->timeIncrementResolution + 500) / 1000);
326 timeInc = frameTick - video->refTick[0];
327 while (timeInc >= currVol->timeIncrementResolution)
329 timeInc -= currVol->timeIncrementResolution;
330 status = BitstreamPut1Bits(stream, 1);
331 /* do not update refTick and modTimeRef yet, do it after encoding!! */
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);
344 /* ======================================================================== */
345 /* Function : EncodeVOPHeader() */
346 /* Date : 08/23/2000 */
347 /* Purpose : Encode VOP Header */
351 /* ======================================================================== */
353 PV_STATUS EncodeVOPHeader(BitstreamEncVideo *stream, Vol *currVol, Vop *currVop)
358 int MTB = currVol->moduloTimeBase;
359 /************************/
360 /* VideoObjectPlane() */
361 /************************/
363 status = BitstreamPutGT16Bits(stream, 32, VOP_START_CODE); /*Start Code for VOP*/
364 status = BitstreamPutBits(stream, 2, currVop->predictionType);/* VOP Coding Type*/
366 currVol->prevModuloTimeBase = currVol->moduloTimeBase;
370 status = BitstreamPut1Bits(stream, 1);
373 status = BitstreamPut1Bits(stream, 0);
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)
382 BitstreamMpeg4ByteAlignStuffing(stream); /* Byte align VOP Header */
385 if (currVop->predictionType == P_VOP)
386 status = BitstreamPut1Bits(stream, currVop->roundingType); /* vop_rounding_type */
388 status = BitstreamPutBits(stream, 3, currVop->intraDCVlcThr); /* intra_dc_vlc_thr */
389 status = BitstreamPutBits(stream, 5, currVop->quantizer); /* vop_quant */
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 */
396 if (currVol->scalability)
397 /* enhancement_type = 0 */
398 status = BitstreamPutBits(stream, 2, currVop->refSelectCode); /* ref_select_code */
402 #endif /* H263_ONLY */
403 /* ======================================================================== */
404 /* Function : EncodeShortHeader() */
405 /* Date : 08/23/2000 */
406 /* Purpose : Encode VOP Header */
410 /* ======================================================================== */
412 PV_STATUS EncodeShortHeader(BitstreamEncVideo *stream, Vop *currVop)
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*/
425 switch (currVop->width)
428 if (currVop->height == 96)
429 status = BitstreamPutBits(stream, 3, 1); /* source_format = 1 */
438 if (currVop->height == 144)
439 status = BitstreamPutBits(stream, 3, 2); /* source_format = 2 */
448 if (currVop->height == 288)
449 status = BitstreamPutBits(stream, 3, 3); /* source_format = 3 */
458 if (currVop->height == 576)
459 status = BitstreamPutBits(stream, 3, 4); /* source_format = 4 */
468 if (currVop->height == 1152)
469 status = BitstreamPutBits(stream, 3, 5); /* source_format = 5 */
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 */
493 /* ======================================================================== */
494 /* Function : EncodeVideoPacketHeader() */
495 /* Date : 09/05/2000 */
497 /* Purpose : Encode a frame of MPEG4 bitstream in Combined mode. */
500 /* Modified : 04/25/2002 */
501 /* Add bitstream structure as input argument */
503 /* ======================================================================== */
504 PV_STATUS EncodeVideoPacketHeader(VideoEncData *video, int MB_number,
505 int quant_scale, Int insert)
507 // PV_STATUS status=PV_SUCCESS;
509 Vop *currVop = video->currVop;
510 Vol *currVol = video->vol[video->currLayer];
511 BitstreamEncVideo *bs, tmp;
514 if (insert) /* insert packet header to the beginning of bs1 */
516 tmp.bitstreamBuffer = buffer; /* use temporary buffer */
518 BitstreamEncReset(&tmp);
522 bs = video->bitstream1;
525 if (currVop->predictionType == I_VOP)
526 BitstreamPutGT16Bits(bs, 17, 1); /* resync_marker I_VOP */
527 else if (currVop->predictionType == P_VOP)
529 fcode = currVop->fcodeForward;
530 BitstreamPutGT16Bits(bs, 16 + fcode, 1); /* resync_marker P_VOP */
535 fcode = currVop->fcodeForward;
536 if (currVop->fcodeBackward > fcode)
537 fcode = currVop->fcodeBackward;
538 BitstreamPutGT16Bits(bs, 16 + fcode, 1); /* resync_marker B_VOP */
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 */
545 if (0) /* header_extension_code = 1 */
547 /* NEED modulo_time_base code here ... default 0x01 belo*/
549 BitstreamPut1Bits(bs, 1);
551 BitstreamPut1Bits(bs, 0);
554 BitstreamPut1Bits(bs, 1); /* marker bit */
556 BitstreamPutBits(bs, currVol->nbitsTimeIncRes, currVop->timeInc); /* vop_time_increment */
558 BitstreamPut1Bits(bs, 1); /* marker bit */
561 BitstreamPutBits(bs, 2, currVop->predictionType);/* VOP Coding Type*/
564 BitstreamPutBits(bs, 3, currVop->intraDCVlcThr); /* intra_dc_vlc_thr */
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);
571 #ifndef NO_SLICE_ENCODE
573 BitstreamPrependPacket(video->bitstream1, bs);
578 #endif /* H263_ONLY */