diff options
Diffstat (limited to 'media/libstagefright/codecs/m4v_h263/enc/src/vop.cpp')
-rw-r--r-- | media/libstagefright/codecs/m4v_h263/enc/src/vop.cpp | 581 |
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 */ + + + |