summaryrefslogtreecommitdiffstats
path: root/media/libstagefright/codecs/m4v_h263/enc/src/vop.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'media/libstagefright/codecs/m4v_h263/enc/src/vop.cpp')
-rw-r--r--media/libstagefright/codecs/m4v_h263/enc/src/vop.cpp581
1 files changed, 581 insertions, 0 deletions
diff --git a/media/libstagefright/codecs/m4v_h263/enc/src/vop.cpp b/media/libstagefright/codecs/m4v_h263/enc/src/vop.cpp
new file mode 100644
index 0000000..47076c3
--- /dev/null
+++ b/media/libstagefright/codecs/m4v_h263/enc/src/vop.cpp
@@ -0,0 +1,581 @@
+/* ------------------------------------------------------------------
+ * Copyright (C) 1998-2009 PacketVideo
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ * -------------------------------------------------------------------
+ */
+#include "mp4def.h"
+#include "mp4lib_int.h"
+#include "mp4enc_lib.h"
+#include "bitstream_io.h"
+#include "m4venc_oscl.h"
+
+PV_STATUS EncodeShortHeader(BitstreamEncVideo *stream, Vop *currVop);
+PV_STATUS EncodeVOPHeader(BitstreamEncVideo *stream, Vol *currVol, Vop *currVop);
+PV_STATUS EncodeGOVHeader(BitstreamEncVideo *stream, UInt seconds);
+
+PV_STATUS EncodeVop_BXRC(VideoEncData *video);
+PV_STATUS EncodeVop_NoME(VideoEncData *video);
+
+/* ======================================================================== */
+/* Function : DecodeVop() */
+/* Date : 08/23/2000 */
+/* Purpose : Encode VOP Header */
+/* In/out : */
+/* Return : */
+/* Modified : */
+/* ======================================================================== */
+PV_STATUS EncodeVop(VideoEncData *video)
+{
+
+ PV_STATUS status;
+ Int currLayer = video->currLayer;
+ Vol *currVol = video->vol[currLayer];
+ Vop *currVop = video->currVop;
+// BitstreamEncVideo *stream=video->bitstream1;
+ UChar *Mode = video->headerInfo.Mode;
+ rateControl **rc = video->rc;
+// UInt time=0;
+
+ /*******************/
+ /* Initialize mode */
+ /*******************/
+
+ switch (currVop->predictionType)
+ {
+ case I_VOP:
+ M4VENC_MEMSET(Mode, MODE_INTRA, sizeof(UChar)*currVol->nTotalMB);
+ break;
+ case P_VOP:
+ M4VENC_MEMSET(Mode, MODE_INTER, sizeof(UChar)*currVol->nTotalMB);
+ break;
+ case B_VOP:
+ /*M4VENC_MEMSET(Mode, MODE_INTER_B,sizeof(UChar)*nTotalMB);*/
+ return PV_FAIL;
+ default:
+ return PV_FAIL;
+ }
+
+ /*********************/
+ /* Motion Estimation */
+ /* compute MVs, scene change detection, edge padding, */
+ /* intra refresh, compute block activity */
+ /*********************/
+ MotionEstimation(video); /* do ME for the whole frame */
+
+ /***************************/
+ /* rate Control (assign QP) */
+ /* 4/11/01, clean-up, and put into a separate function */
+ /***************************/
+ status = RC_VopQPSetting(video, rc);
+ if (status == PV_FAIL)
+ return PV_FAIL;
+
+ /**********************/
+ /* Encode VOP */
+ /**********************/
+ if (video->slice_coding) /* end here */
+ {
+ /* initialize state variable for slice-based APIs */
+ video->totalSAD = 0;
+ video->mbnum = 0;
+ video->sliceNo[0] = 0;
+ video->numIntra = 0;
+ video->offset = 0;
+ video->end_of_buf = 0;
+ video->hp_guess = -1;
+ return status;
+ }
+
+ status = EncodeVop_NoME(video);
+
+ /******************************/
+ /* rate control (update stat) */
+ /* 6/2/01 separate function */
+ /******************************/
+
+ RC_VopUpdateStat(video, rc[currLayer]);
+
+ return status;
+}
+
+/* ======================================================================== */
+/* Function : EncodeVop_NoME() */
+/* Date : 08/28/2001 */
+/* History : */
+/* Purpose : EncodeVop without motion est. */
+/* In/out : */
+/* Return : */
+/* Modified : */
+/* */
+/* ======================================================================== */
+
+PV_STATUS EncodeVop_NoME(VideoEncData *video)
+{
+ Vop *currVop = video->currVop;
+ Vol *currVol = video->vol[video->currLayer];
+ BitstreamEncVideo *stream = video->bitstream1;
+ Int time = 0; /* follows EncodeVop value */
+ PV_STATUS status = PV_SUCCESS;
+
+ if (currVol->shortVideoHeader) /* Short Video Header = 1 */
+ {
+
+ status = EncodeShortHeader(stream, currVop); /* Encode Short Header */
+
+ video->header_bits = BitstreamGetPos(stream); /* Header Bits */
+
+ status = EncodeFrameCombinedMode(video);
+
+ }
+#ifndef H263_ONLY
+ else /* Short Video Header = 0 */
+ {
+
+ if (currVol->GOVStart && currVop->predictionType == I_VOP)
+ status = EncodeGOVHeader(stream, time); /* Encode GOV Header */
+
+ status = EncodeVOPHeader(stream, currVol, currVop); /* Encode VOP Header */
+
+ video->header_bits = BitstreamGetPos(stream); /* Header Bits */
+
+ if (currVop->vopCoded)
+ {
+ if (!currVol->scalability)
+ {
+ if (currVol->dataPartitioning)
+ {
+ status = EncodeFrameDataPartMode(video); /* Encode Data Partitioning Mode VOP */
+ }
+ else
+ {
+ status = EncodeFrameCombinedMode(video); /* Encode Combined Mode VOP */
+ }
+ }
+ else
+ status = EncodeFrameCombinedMode(video); /* Encode Combined Mode VOP */
+ }
+ else /* Vop Not coded */
+ {
+
+ return status;
+ }
+ }
+#endif /* H263_ONLY */
+ return status;
+
+}
+
+#ifndef NO_SLICE_ENCODE
+/* ======================================================================== */
+/* Function : EncodeSlice() */
+/* Date : 04/19/2002 */
+/* History : */
+/* Purpose : Encode one slice. */
+/* In/out : */
+/* Return : */
+/* Modified : */
+/* */
+/* ======================================================================== */
+
+PV_STATUS EncodeSlice(VideoEncData *video)
+{
+ Vop *currVop = video->currVop;
+ Int currLayer = video->currLayer;
+ Vol *currVol = video->vol[currLayer];
+ BitstreamEncVideo *stream = video->bitstream1; /* different from frame-based */
+ Int time = 0; /* follows EncodeVop value */
+ PV_STATUS status = PV_SUCCESS;
+ rateControl **rc = video->rc;
+
+ if (currVol->shortVideoHeader) /* Short Video Header = 1 */
+ {
+
+ if (video->mbnum == 0)
+ {
+ status = EncodeShortHeader(stream, currVop); /* Encode Short Header */
+
+ video->header_bits = BitstreamGetPos(stream); /* Header Bits */
+ }
+
+ status = EncodeSliceCombinedMode(video);
+
+ }
+#ifndef H263_ONLY
+ else /* Short Video Header = 0 */
+ {
+
+ if (video->mbnum == 0)
+ {
+ if (currVol->GOVStart)
+ status = EncodeGOVHeader(stream, time); /* Encode GOV Header */
+
+ status = EncodeVOPHeader(stream, currVol, currVop); /* Encode VOP Header */
+
+ video->header_bits = BitstreamGetPos(stream); /* Header Bits */
+ }
+
+ if (currVop->vopCoded)
+ {
+ if (!currVol->scalability)
+ {
+ if (currVol->dataPartitioning)
+ {
+ status = EncodeSliceDataPartMode(video); /* Encode Data Partitioning Mode VOP */
+ }
+ else
+ {
+ status = EncodeSliceCombinedMode(video); /* Encode Combined Mode VOP */
+ }
+ }
+ else
+ status = EncodeSliceCombinedMode(video); /* Encode Combined Mode VOP */
+ }
+ else /* Vop Not coded */
+ {
+
+ return status;
+ }
+ }
+#endif /* H263_ONLY */
+ if (video->mbnum >= currVol->nTotalMB && status != PV_END_OF_BUF) /* end of Vop */
+ {
+ /******************************/
+ /* rate control (update stat) */
+ /* 6/2/01 separate function */
+ /******************************/
+
+ status = RC_VopUpdateStat(video, rc[currLayer]);
+ }
+
+ return status;
+
+}
+#endif /* NO_SLICE_ENCODE */
+
+#ifndef H263_ONLY
+/* ======================================================================== */
+/* Function : EncodeGOVHeader() */
+/* Date : 08/23/2000 */
+/* Purpose : Encode GOV Header */
+/* In/out : */
+/* Return : */
+/* Modified : */
+/* ======================================================================== */
+PV_STATUS EncodeGOVHeader(BitstreamEncVideo *stream, UInt seconds)
+{
+ PV_STATUS status;
+// int temp;
+ UInt tmpvar;
+
+ /********************************/
+ /* Group_of_VideoObjectPlane() */
+ /********************************/
+
+ status = BitstreamPutGT16Bits(stream, 32, GROUP_START_CODE);
+ /* time_code */
+ tmpvar = seconds / 3600;
+ status = BitstreamPutBits(stream, 5, tmpvar); /* Hours*/
+
+ tmpvar = (seconds - tmpvar * 3600) / 60;
+ status = BitstreamPutBits(stream, 6, tmpvar); /* Minutes*/
+
+ status = BitstreamPut1Bits(stream, 1); /* Marker*/
+
+ tmpvar = seconds % 60;
+ status = BitstreamPutBits(stream, 6, tmpvar); /* Seconds*/
+
+ status = BitstreamPut1Bits(stream, 1); /* closed_gov */
+ status = BitstreamPut1Bits(stream, 0); /* broken_link */
+ /*temp =*/
+ BitstreamMpeg4ByteAlignStuffing(stream); /* Byte align GOV Header */
+
+ return status;
+}
+
+#ifdef ALLOW_VOP_NOT_CODED
+
+PV_STATUS EncodeVopNotCoded(VideoEncData *video, UChar *bstream, Int *size, ULong modTime)
+{
+ PV_STATUS status;
+ Vol *currVol = video->vol[0];
+ Vop *currVop = video->currVop;
+ BitstreamEncVideo *stream = currVol->stream;
+ UInt frameTick;
+ Int timeInc;
+
+ stream->bitstreamBuffer = bstream;
+ stream->bufferSize = *size;
+ BitstreamEncReset(stream);
+
+ status = BitstreamPutGT16Bits(stream, 32, VOP_START_CODE); /*Start Code for VOP*/
+ status = BitstreamPutBits(stream, 2, P_VOP);/* VOP Coding Type*/
+
+ frameTick = (Int)(((double)(modTime - video->modTimeRef) * currVol->timeIncrementResolution + 500) / 1000);
+ timeInc = frameTick - video->refTick[0];
+ while (timeInc >= currVol->timeIncrementResolution)
+ {
+ timeInc -= currVol->timeIncrementResolution;
+ status = BitstreamPut1Bits(stream, 1);
+ /* do not update refTick and modTimeRef yet, do it after encoding!! */
+ }
+ status = BitstreamPut1Bits(stream, 0);
+ status = BitstreamPut1Bits(stream, 1); /* marker bit */
+ status = BitstreamPutBits(stream, currVol->nbitsTimeIncRes, timeInc); /* vop_time_increment */
+ status = BitstreamPut1Bits(stream, 1); /* marker bit */
+ status = BitstreamPut1Bits(stream, 0); /* vop_coded bit */
+ BitstreamMpeg4ByteAlignStuffing(stream);
+
+ return status;
+}
+#endif
+
+/* ======================================================================== */
+/* Function : EncodeVOPHeader() */
+/* Date : 08/23/2000 */
+/* Purpose : Encode VOP Header */
+/* In/out : */
+/* Return : */
+/* Modified : */
+/* ======================================================================== */
+
+PV_STATUS EncodeVOPHeader(BitstreamEncVideo *stream, Vol *currVol, Vop *currVop)
+{
+ PV_STATUS status;
+ //int temp;
+
+ int MTB = currVol->moduloTimeBase;
+ /************************/
+ /* VideoObjectPlane() */
+ /************************/
+
+ status = BitstreamPutGT16Bits(stream, 32, VOP_START_CODE); /*Start Code for VOP*/
+ status = BitstreamPutBits(stream, 2, currVop->predictionType);/* VOP Coding Type*/
+
+ currVol->prevModuloTimeBase = currVol->moduloTimeBase;
+
+ while (MTB)
+ {
+ status = BitstreamPut1Bits(stream, 1);
+ MTB--;
+ }
+ status = BitstreamPut1Bits(stream, 0);
+
+ status = BitstreamPut1Bits(stream, 1); /* marker bit */
+ status = BitstreamPutBits(stream, currVol->nbitsTimeIncRes, currVop->timeInc); /* vop_time_increment */
+ status = BitstreamPut1Bits(stream, 1); /* marker bit */
+ status = BitstreamPut1Bits(stream, currVop->vopCoded); /* vop_coded bit */
+ if (currVop->vopCoded == 0)
+ {
+ /*temp =*/
+ BitstreamMpeg4ByteAlignStuffing(stream); /* Byte align VOP Header */
+ return status;
+ }
+ if (currVop->predictionType == P_VOP)
+ status = BitstreamPut1Bits(stream, currVop->roundingType); /* vop_rounding_type */
+
+ status = BitstreamPutBits(stream, 3, currVop->intraDCVlcThr); /* intra_dc_vlc_thr */
+ status = BitstreamPutBits(stream, 5, currVop->quantizer); /* vop_quant */
+
+ if (currVop->predictionType != I_VOP)
+ status = BitstreamPutBits(stream, 3, currVop->fcodeForward); /* vop_fcode_forward */
+ if (currVop->predictionType == B_VOP)
+ status = BitstreamPutBits(stream, 3, currVop->fcodeBackward);/* vop_fcode_backward */
+
+ if (currVol->scalability)
+ /* enhancement_type = 0 */
+ status = BitstreamPutBits(stream, 2, currVop->refSelectCode); /* ref_select_code */
+
+ return status;
+}
+#endif /* H263_ONLY */
+/* ======================================================================== */
+/* Function : EncodeShortHeader() */
+/* Date : 08/23/2000 */
+/* Purpose : Encode VOP Header */
+/* In/out : */
+/* Return : */
+/* Modified : */
+/* ======================================================================== */
+
+PV_STATUS EncodeShortHeader(BitstreamEncVideo *stream, Vop *currVop)
+{
+
+ PV_STATUS status;
+
+ status = BitstreamPutGT16Bits(stream, 22, SHORT_VIDEO_START_MARKER); /* Short_video_start_marker */
+ status = BitstreamPutBits(stream, 8, currVop->temporalRef); /* temporal_reference */
+ status = BitstreamPut1Bits(stream, 1); /* marker bit */
+ status = BitstreamPut1Bits(stream, 0); /* zero bit */
+ status = BitstreamPut1Bits(stream, 0); /* split_screen_indicator=0*/
+ status = BitstreamPut1Bits(stream, 0); /* document_camera_indicator=0*/
+ status = BitstreamPut1Bits(stream, 0); /* full_picture_freeze_release=0*/
+
+ switch (currVop->width)
+ {
+ case 128:
+ if (currVop->height == 96)
+ status = BitstreamPutBits(stream, 3, 1); /* source_format = 1 */
+ else
+ {
+ status = PV_FAIL;
+ return status;
+ }
+ break;
+
+ case 176:
+ if (currVop->height == 144)
+ status = BitstreamPutBits(stream, 3, 2); /* source_format = 2 */
+ else
+ {
+ status = PV_FAIL;
+ return status;
+ }
+ break;
+
+ case 352:
+ if (currVop->height == 288)
+ status = BitstreamPutBits(stream, 3, 3); /* source_format = 3 */
+ else
+ {
+ status = PV_FAIL;
+ return status;
+ }
+ break;
+
+ case 704:
+ if (currVop->height == 576)
+ status = BitstreamPutBits(stream, 3, 4); /* source_format = 4 */
+ else
+ {
+ status = PV_FAIL;
+ return status;
+ }
+ break;
+
+ case 1408:
+ if (currVop->height == 1152)
+ status = BitstreamPutBits(stream, 3, 5); /* source_format = 5 */
+ else
+ {
+ status = PV_FAIL;
+ return status;
+ }
+ break;
+
+ default:
+ status = PV_FAIL;
+ return status;
+ }
+
+
+ status = BitstreamPut1Bits(stream, currVop->predictionType); /* picture_coding type */
+ status = BitstreamPutBits(stream, 4, 0); /* four_reserved_zero_bits */
+ status = BitstreamPutBits(stream, 5, currVop->quantizer); /* vop_quant*/
+ status = BitstreamPut1Bits(stream, 0); /* zero_bit*/
+ status = BitstreamPut1Bits(stream, 0); /* pei=0 */
+
+ return status;
+}
+
+#ifndef H263_ONLY
+/* ======================================================================== */
+/* Function : EncodeVideoPacketHeader() */
+/* Date : 09/05/2000 */
+/* History : */
+/* Purpose : Encode a frame of MPEG4 bitstream in Combined mode. */
+/* In/out : */
+/* Return : */
+/* Modified : 04/25/2002 */
+/* Add bitstream structure as input argument */
+/* */
+/* ======================================================================== */
+PV_STATUS EncodeVideoPacketHeader(VideoEncData *video, int MB_number,
+ int quant_scale, Int insert)
+{
+// PV_STATUS status=PV_SUCCESS;
+ int fcode;
+ Vop *currVop = video->currVop;
+ Vol *currVol = video->vol[video->currLayer];
+ BitstreamEncVideo *bs, tmp;
+ UChar buffer[30];
+
+ if (insert) /* insert packet header to the beginning of bs1 */
+ {
+ tmp.bitstreamBuffer = buffer; /* use temporary buffer */
+ tmp.bufferSize = 30;
+ BitstreamEncReset(&tmp);
+ bs = &tmp;
+ }
+ else
+ bs = video->bitstream1;
+
+
+ if (currVop->predictionType == I_VOP)
+ BitstreamPutGT16Bits(bs, 17, 1); /* resync_marker I_VOP */
+ else if (currVop->predictionType == P_VOP)
+ {
+ fcode = currVop->fcodeForward;
+ BitstreamPutGT16Bits(bs, 16 + fcode, 1); /* resync_marker P_VOP */
+
+ }
+ else
+ {
+ fcode = currVop->fcodeForward;
+ if (currVop->fcodeBackward > fcode)
+ fcode = currVop->fcodeBackward;
+ BitstreamPutGT16Bits(bs, 16 + fcode, 1); /* resync_marker B_VOP */
+ }
+
+ BitstreamPutBits(bs, currVol->nBitsForMBID, MB_number); /* resync_marker */
+ BitstreamPutBits(bs, 5, quant_scale); /* quant_scale */
+ BitstreamPut1Bits(bs, 0); /* header_extension_code = 0 */
+
+ if (0) /* header_extension_code = 1 */
+ {
+ /* NEED modulo_time_base code here ... default 0x01 belo*/
+ /*status =*/
+ BitstreamPut1Bits(bs, 1);
+ /*status = */
+ BitstreamPut1Bits(bs, 0);
+
+ /*status = */
+ BitstreamPut1Bits(bs, 1); /* marker bit */
+ /*status = */
+ BitstreamPutBits(bs, currVol->nbitsTimeIncRes, currVop->timeInc); /* vop_time_increment */
+ /*status = */
+ BitstreamPut1Bits(bs, 1); /* marker bit */
+
+ /*status = */
+ BitstreamPutBits(bs, 2, currVop->predictionType);/* VOP Coding Type*/
+
+ /*status = */
+ BitstreamPutBits(bs, 3, currVop->intraDCVlcThr); /* intra_dc_vlc_thr */
+
+ if (currVop->predictionType != I_VOP)
+ /*status = */ BitstreamPutBits(bs, 3, currVop->fcodeForward);
+ if (currVop->predictionType == B_VOP)
+ /*status = */ BitstreamPutBits(bs, 3, currVop->fcodeBackward);
+ }
+#ifndef NO_SLICE_ENCODE
+ if (insert)
+ BitstreamPrependPacket(video->bitstream1, bs);
+#endif
+ return PV_SUCCESS;
+}
+
+#endif /* H263_ONLY */
+
+
+