Home | History | Annotate | Download | only in src
      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 /* ======================================================================== */
     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 
    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 
    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 /* ======================================================================== */
    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 
    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 
    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 
    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 /* ======================================================================== */
    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