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
24PV_STATUS EncodeShortHeader(BitstreamEncVideo *stream, Vop *currVop);
25PV_STATUS EncodeVOPHeader(BitstreamEncVideo *stream, Vol *currVol, Vop *currVop);
26PV_STATUS EncodeGOVHeader(BitstreamEncVideo *stream, UInt seconds);
27
28PV_STATUS EncodeVop_BXRC(VideoEncData *video);
29PV_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/* ======================================================================== */
39PV_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
124PV_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
192PV_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/* ======================================================================== */
276PV_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
309PV_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
353PV_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
412PV_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/* ======================================================================== */
504PV_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