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 /* ======================================================================== */
EncodeVop(VideoEncData * video)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 
EncodeVop_NoME(VideoEncData * video)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 
EncodeSlice(VideoEncData * video)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 /* ======================================================================== */
EncodeGOVHeader(BitstreamEncVideo * stream,UInt seconds)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 
EncodeVopNotCoded(VideoEncData * video,UChar * bstream,Int * size,ULong modTime)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 
EncodeVOPHeader(BitstreamEncVideo * stream,Vol * currVol,Vop * currVop)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 
EncodeShortHeader(BitstreamEncVideo * stream,Vop * currVop)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 /* ======================================================================== */
EncodeVideoPacketHeader(VideoEncData * video,int MB_number,int quant_scale,Int insert)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