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
19 #include "mp4enc_lib.h"
20 #include "bitstream_io.h"
21 #include "rate_control.h"
22 #include "m4venc_oscl.h"
23
24 #ifndef INT32_MAX
25 #define INT32_MAX 0x7fffffff
26 #endif
27
28 #ifndef SIZE_MAX
29 #define SIZE_MAX ((size_t) -1)
30 #endif
31
32 /* Inverse normal zigzag */
33 const static Int zigzag_i[NCOEFF_BLOCK] =
34 {
35 0, 1, 8, 16, 9, 2, 3, 10,
36 17, 24, 32, 25, 18, 11, 4, 5,
37 12, 19, 26, 33, 40, 48, 41, 34,
38 27, 20, 13, 6, 7, 14, 21, 28,
39 35, 42, 49, 56, 57, 50, 43, 36,
40 29, 22, 15, 23, 30, 37, 44, 51,
41 58, 59, 52, 45, 38, 31, 39, 46,
42 53, 60, 61, 54, 47, 55, 62, 63
43 };
44
45 /* INTRA */
46 const static Int mpeg_iqmat_def[NCOEFF_BLOCK] =
47 { 8, 17, 18, 19, 21, 23, 25, 27,
48 17, 18, 19, 21, 23, 25, 27, 28,
49 20, 21, 22, 23, 24, 26, 28, 30,
50 21, 22, 23, 24, 26, 28, 30, 32,
51 22, 23, 24, 26, 28, 30, 32, 35,
52 23, 24, 26, 28, 30, 32, 35, 38,
53 25, 26, 28, 30, 32, 35, 38, 41,
54 27, 28, 30, 32, 35, 38, 41, 45
55 };
56
57 /* INTER */
58 const static Int mpeg_nqmat_def[64] =
59 { 16, 17, 18, 19, 20, 21, 22, 23,
60 17, 18, 19, 20, 21, 22, 23, 24,
61 18, 19, 20, 21, 22, 23, 24, 25,
62 19, 20, 21, 22, 23, 24, 26, 27,
63 20, 21, 22, 23, 25, 26, 27, 28,
64 21, 22, 23, 24, 26, 27, 28, 30,
65 22, 23, 24, 26, 27, 28, 30, 31,
66 23, 24, 25, 27, 28, 30, 31, 33
67 };
68
69 /* Profiles and levels */
70 /* Simple profile(level 0-3) and Core profile (level 1-2) */
71 /* {SPL0, SPL1, SPL2, SPL3, CPL1, CPL2, CPL2, CPL2} , SPL0: Simple Profile@Level0, CPL1: Core Profile@Level1, the last two are redundant for easy table manipulation */
72 const static Int profile_level_code[8] =
73 {
74 0x08, 0x01, 0x02, 0x03, 0x21, 0x22, 0x22, 0x22
75 };
76
77 const static Int profile_level_max_bitrate[8] =
78 {
79 64000, 64000, 128000, 384000, 384000, 2000000, 2000000, 2000000
80 };
81
82 const static Int profile_level_max_packet_size[8] =
83 {
84 2048, 2048, 4096, 8192, 4096, 8192, 8192, 8192
85 };
86
87 const static Int profile_level_max_mbsPerSec[8] =
88 {
89 1485, 1485, 5940, 11880, 5940, 23760, 23760, 23760
90 };
91
92 const static Int profile_level_max_VBV_size[8] =
93 {
94 163840, 163840, 655360, 655360, 262144, 1310720, 1310720, 1310720
95 };
96
97
98 /* Simple scalable profile (level 0-2) and Core scalable profile (level 1-3) */
99 /* {SSPL0, SSPL1, SSPL2, SSPL2, CSPL1, CSPL2, CSPL3, CSPL3} , SSPL0: Simple Scalable Profile@Level0, CSPL1: Core Scalable Profile@Level1, the fourth is redundant for easy table manipulation */
100
101 const static Int scalable_profile_level_code[8] =
102 {
103 0x10, 0x11, 0x12, 0x12, 0xA1, 0xA2, 0xA3, 0xA3
104 };
105
106 const static Int scalable_profile_level_max_bitrate[8] =
107 {
108 128000, 128000, 256000, 256000, 768000, 1500000, 4000000, 4000000
109 };
110
111 /* in bits */
112 const static Int scalable_profile_level_max_packet_size[8] =
113 {
114 2048, 2048, 4096, 4096, 4096, 4096, 16384, 16384
115 };
116
117 const static Int scalable_profile_level_max_mbsPerSec[8] =
118 {
119 1485, 7425, 23760, 23760, 14850, 29700, 120960, 120960
120 };
121
122 const static Int scalable_profile_level_max_VBV_size[8] =
123 {
124 163840, 655360, 655360, 655360, 1048576, 1310720, 1310720, 1310720
125 };
126
127
128 /* H263 profile 0 @ level 10-70 */
129 const static Int h263Level[8] = {0, 10, 20, 30, 40, 50, 60, 70};
130 const static float rBR_bound[8] = {0, 1, 2, 6, 32, 64, 128, 256};
131 const static float max_h263_framerate[2] = {(float)30000 / (float)2002,
132 (float)30000 / (float)1001
133 };
134 const static Int max_h263_width[2] = {176, 352};
135 const static Int max_h263_height[2] = {144, 288};
136
137 /* 6/2/2001, newly added functions to make PVEncodeVop more readable. */
138 Int DetermineCodingLayer(VideoEncData *video, Int *nLayer, ULong modTime);
139 void DetermineVopType(VideoEncData *video, Int currLayer);
140 Int UpdateSkipNextFrame(VideoEncData *video, ULong *modTime, Int *size, PV_STATUS status);
141 Bool SetProfile_BufferSize(VideoEncData *video, float delay, Int bInitialized);
142
143 #ifdef PRINT_RC_INFO
144 extern FILE *facct;
145 extern int tiTotalNumBitsGenerated;
146 extern int iStuffBits;
147 #endif
148
149 #ifdef PRINT_EC
150 extern FILE *fec;
151 #endif
152
153
154 /* ======================================================================== */
155 /* Function : PVGetDefaultEncOption() */
156 /* Date : 12/12/2005 */
157 /* Purpose : */
158 /* In/out : */
159 /* Return : PV_TRUE if successed, PV_FALSE if failed. */
160 /* Modified : */
161 /* */
162 /* ======================================================================== */
163
PVGetDefaultEncOption(VideoEncOptions * encOption,Int encUseCase)164 OSCL_EXPORT_REF Bool PVGetDefaultEncOption(VideoEncOptions *encOption, Int encUseCase)
165 {
166 VideoEncOptions defaultUseCase = {H263_MODE, profile_level_max_packet_size[SIMPLE_PROFILE_LEVEL0] >> 3,
167 SIMPLE_PROFILE_LEVEL0, PV_OFF, 0, 1, 1000, 33, {144, 144}, {176, 176}, {15, 30}, {64000, 128000},
168 {10, 10}, {12, 12}, {0, 0}, CBR_1, 0.0, PV_OFF, -1, 0, PV_OFF, 16, PV_OFF, 0, PV_ON
169 };
170
171 OSCL_UNUSED_ARG(encUseCase); // unused for now. Later we can add more defaults setting and use this
172 // argument to select the right one.
173 /* in the future we can create more meaningful use-cases */
174 if (encOption == NULL)
175 {
176 return PV_FALSE;
177 }
178
179 M4VENC_MEMCPY(encOption, &defaultUseCase, sizeof(VideoEncOptions));
180
181 return PV_TRUE;
182 }
183
184 /* ======================================================================== */
185 /* Function : PVInitVideoEncoder() */
186 /* Date : 08/22/2000 */
187 /* Purpose : Initialization of MP4 Encoder and VO bitstream */
188 /* In/out : */
189 /* Return : PV_TRUE if successed, PV_FALSE if failed. */
190 /* Modified : 5/21/01, allocate only yChan and assign uChan & vChan */
191 /* 12/12/05, add encoding option as input argument */
192 /* ======================================================================== */
PVInitVideoEncoder(VideoEncControls * encoderControl,VideoEncOptions * encOption)193 OSCL_EXPORT_REF Bool PVInitVideoEncoder(VideoEncControls *encoderControl, VideoEncOptions *encOption)
194 {
195
196 Bool status = PV_TRUE;
197 Int nLayers, idx, i, j;
198 Int max = 0, max_width = 0, max_height = 0, pitch, offset;
199 Int size = 0, nTotalMB = 0;
200 VideoEncData *video;
201 Vol *pVol;
202 VideoEncParams *pEncParams;
203 Int temp_w, temp_h, mbsPerSec;
204
205 /******************************************/
206 /* this part use to be PVSetEncode() */
207 Int profile_table_index, *profile_level_table;
208 Int profile_level = encOption->profile_level;
209 Int PacketSize = encOption->packetSize << 3;
210 Int timeInc, timeIncRes;
211 float profile_max_framerate;
212 VideoEncParams *encParams;
213
214 if (encoderControl->videoEncoderData) /* this has been called */
215 {
216 if (encoderControl->videoEncoderInit) /* check if PVInitVideoEncoder() has been called */
217 {
218 PVCleanUpVideoEncoder(encoderControl);
219 encoderControl->videoEncoderInit = 0;
220 }
221
222 M4VENC_FREE(encoderControl->videoEncoderData);
223 encoderControl->videoEncoderData = NULL;
224 }
225 encoderControl->videoEncoderInit = 0; /* reset this value */
226
227 video = (VideoEncData *)M4VENC_MALLOC(sizeof(VideoEncData)); /* allocate memory for encData */
228
229 if (video == NULL)
230 return PV_FALSE;
231
232 M4VENC_MEMSET(video, 0, sizeof(VideoEncData));
233
234 encoderControl->videoEncoderData = (void *) video; /* set up pointer in VideoEncData structure */
235
236 video->encParams = (VideoEncParams *)M4VENC_MALLOC(sizeof(VideoEncParams));
237 if (video->encParams == NULL)
238 goto CLEAN_UP;
239
240 M4VENC_MEMSET(video->encParams, 0, sizeof(VideoEncParams));
241
242 encParams = video->encParams;
243 encParams->nLayers = encOption->numLayers;
244
245 /* Check whether the input packetsize is valid (Note: put code here (before any memory allocation) in order to avoid memory leak */
246 if ((Int)profile_level < (Int)(SIMPLE_SCALABLE_PROFILE_LEVEL0)) /* non-scalable profile */
247 {
248 profile_level_table = (Int *)profile_level_max_packet_size;
249 profile_table_index = (Int)profile_level;
250 if (encParams->nLayers != 1)
251 {
252 goto CLEAN_UP;
253 }
254
255 encParams->LayerMaxMbsPerSec[0] = profile_level_max_mbsPerSec[profile_table_index];
256
257 }
258 else /* scalable profile */
259 {
260 profile_level_table = (Int *)scalable_profile_level_max_packet_size;
261 profile_table_index = (Int)profile_level - (Int)(SIMPLE_SCALABLE_PROFILE_LEVEL0);
262 if (encParams->nLayers < 2)
263 {
264 goto CLEAN_UP;
265 }
266 for (i = 0; i < encParams->nLayers; i++)
267 {
268 encParams->LayerMaxMbsPerSec[i] = scalable_profile_level_max_mbsPerSec[profile_table_index];
269 }
270
271 }
272
273 /* cannot have zero size packet with these modes */
274 if (PacketSize == 0)
275 {
276 if (encOption->encMode == DATA_PARTITIONING_MODE)
277 {
278 goto CLEAN_UP;
279 }
280 if (encOption->encMode == COMBINE_MODE_WITH_ERR_RES)
281 {
282 encOption->encMode = COMBINE_MODE_NO_ERR_RES;
283 }
284 }
285
286 if (encOption->gobHeaderInterval == 0)
287 {
288 if (encOption->encMode == H263_MODE_WITH_ERR_RES)
289 {
290 encOption->encMode = H263_MODE;
291 }
292
293 if (encOption->encMode == SHORT_HEADER_WITH_ERR_RES)
294 {
295 encOption->encMode = SHORT_HEADER;
296 }
297 }
298
299 if (PacketSize > profile_level_table[profile_table_index])
300 goto CLEAN_UP;
301
302 /* Initial Defaults for all Modes */
303
304 encParams->SequenceStartCode = 1;
305 encParams->GOV_Enabled = 0;
306 encParams->RoundingType = 0;
307 encParams->IntraDCVlcThr = PV_MAX(PV_MIN(encOption->intraDCVlcTh, 7), 0);
308 encParams->ACDCPrediction = ((encOption->useACPred == PV_ON) ? TRUE : FALSE);
309 encParams->RC_Type = encOption->rcType;
310 encParams->Refresh = encOption->numIntraMB;
311 encParams->ResyncMarkerDisable = 0; /* Enable Resync Marker */
312
313 for (i = 0; i < encOption->numLayers; i++)
314 {
315 #ifdef NO_MPEG_QUANT
316 encParams->QuantType[i] = 0;
317 #else
318 encParams->QuantType[i] = encOption->quantType[i]; /* H263 */
319 #endif
320 if (encOption->pQuant[i] >= 1 && encOption->pQuant[i] <= 31)
321 {
322 encParams->InitQuantPvop[i] = encOption->pQuant[i];
323 }
324 else
325 {
326 goto CLEAN_UP;
327 }
328 if (encOption->iQuant[i] >= 1 && encOption->iQuant[i] <= 31)
329 {
330 encParams->InitQuantIvop[i] = encOption->iQuant[i];
331 }
332 else
333 {
334 goto CLEAN_UP;
335 }
336 }
337
338 encParams->HalfPel_Enabled = 1;
339 encParams->SearchRange = encOption->searchRange; /* 4/16/2001 */
340 encParams->FullSearch_Enabled = 0;
341 #ifdef NO_INTER4V
342 encParams->MV8x8_Enabled = 0;
343 #else
344 encParams->MV8x8_Enabled = 0;// comment out for now!! encOption->mv8x8Enable;
345 #endif
346 encParams->H263_Enabled = 0;
347 encParams->GOB_Header_Interval = 0; // need to be reset to 0
348 encParams->IntraPeriod = encOption->intraPeriod; /* Intra update period update default*/
349 encParams->SceneChange_Det = encOption->sceneDetect;
350 encParams->FineFrameSkip_Enabled = 0;
351 encParams->NoFrameSkip_Enabled = encOption->noFrameSkipped;
352 encParams->NoPreSkip_Enabled = encOption->noFrameSkipped;
353 encParams->GetVolHeader[0] = 0;
354 encParams->GetVolHeader[1] = 0;
355 encParams->ResyncPacketsize = encOption->packetSize << 3;
356 encParams->LayerMaxBitRate[0] = 0;
357 encParams->LayerMaxBitRate[1] = 0;
358 encParams->LayerMaxFrameRate[0] = (float)0.0;
359 encParams->LayerMaxFrameRate[1] = (float)0.0;
360 encParams->VBV_delay = encOption->vbvDelay; /* 2sec VBV buffer size */
361
362 switch (encOption->encMode)
363 {
364
365 case SHORT_HEADER:
366 case SHORT_HEADER_WITH_ERR_RES:
367
368 /* From Table 6-26 */
369 encParams->nLayers = 1;
370 encParams->QuantType[0] = 0; /*H263 */
371 encParams->ResyncMarkerDisable = 1; /* Disable Resync Marker */
372 encParams->DataPartitioning = 0; /* Combined Mode */
373 encParams->ReversibleVLC = 0; /* Disable RVLC */
374 encParams->RoundingType = 0;
375 encParams->IntraDCVlcThr = 7; /* use_intra_dc_vlc = 0 */
376 encParams->MV8x8_Enabled = 0;
377
378 encParams->GOB_Header_Interval = encOption->gobHeaderInterval;
379 encParams->H263_Enabled = 2;
380 encParams->GOV_Enabled = 0;
381 encParams->TimeIncrementRes = 30000; /* timeIncrementRes for H263 */
382 break;
383
384 case H263_MODE:
385 case H263_MODE_WITH_ERR_RES:
386
387 /* From Table 6-26 */
388 encParams->nLayers = 1;
389 encParams->QuantType[0] = 0; /*H263 */
390 encParams->ResyncMarkerDisable = 1; /* Disable Resync Marker */
391 encParams->DataPartitioning = 0; /* Combined Mode */
392 encParams->ReversibleVLC = 0; /* Disable RVLC */
393 encParams->RoundingType = 0;
394 encParams->IntraDCVlcThr = 7; /* use_intra_dc_vlc = 0 */
395 encParams->MV8x8_Enabled = 0;
396
397 encParams->H263_Enabled = 1;
398 encParams->GOV_Enabled = 0;
399 encParams->TimeIncrementRes = 30000; /* timeIncrementRes for H263 */
400
401 break;
402 #ifndef H263_ONLY
403 case DATA_PARTITIONING_MODE:
404
405 encParams->DataPartitioning = 1; /* Base Layer Data Partitioning */
406 encParams->ResyncMarkerDisable = 0; /* Resync Marker */
407 #ifdef NO_RVLC
408 encParams->ReversibleVLC = 0;
409 #else
410 encParams->ReversibleVLC = (encOption->rvlcEnable == PV_ON); /* RVLC when Data Partitioning */
411 #endif
412 encParams->ResyncPacketsize = PacketSize;
413 break;
414
415 case COMBINE_MODE_WITH_ERR_RES:
416
417 encParams->DataPartitioning = 0; /* Combined Mode */
418 encParams->ResyncMarkerDisable = 0; /* Resync Marker */
419 encParams->ReversibleVLC = 0; /* No RVLC */
420 encParams->ResyncPacketsize = PacketSize;
421 break;
422
423 case COMBINE_MODE_NO_ERR_RES:
424
425 encParams->DataPartitioning = 0; /* Combined Mode */
426 encParams->ResyncMarkerDisable = 1; /* Disable Resync Marker */
427 encParams->ReversibleVLC = 0; /* No RVLC */
428 break;
429 #endif
430 default:
431 goto CLEAN_UP;
432 }
433 /* Set the constraints (maximum values) according to the input profile and level */
434 /* Note that profile_table_index is already figured out above */
435
436 /* base layer */
437 encParams->profile_table_index = profile_table_index; /* Used to limit the profile and level in SetProfile_BufferSize() */
438
439 /* check timeIncRes */
440 timeIncRes = encOption->timeIncRes;
441 timeInc = encOption->tickPerSrc;
442
443 if ((timeIncRes >= 1) && (timeIncRes <= 65536) && (timeInc < timeIncRes) && (timeInc != 0))
444 {
445 if (!encParams->H263_Enabled)
446 {
447 encParams->TimeIncrementRes = timeIncRes;
448 }
449 else
450 {
451 encParams->TimeIncrementRes = 30000;
452 // video->FrameRate = 30000/(float)1001; /* fix it to 29.97 fps */
453 }
454 video->FrameRate = timeIncRes / ((float)timeInc);
455 }
456 else
457 {
458 goto CLEAN_UP;
459 }
460
461 /* check frame dimension */
462 if (encParams->H263_Enabled)
463 {
464 switch (encOption->encWidth[0])
465 {
466 case 128:
467 if (encOption->encHeight[0] != 96) /* source_format = 1 */
468 goto CLEAN_UP;
469 break;
470 case 176:
471 if (encOption->encHeight[0] != 144) /* source_format = 2 */
472 goto CLEAN_UP;
473 break;
474 case 352:
475 if (encOption->encHeight[0] != 288) /* source_format = 2 */
476 goto CLEAN_UP;
477 break;
478
479 case 704:
480 if (encOption->encHeight[0] != 576) /* source_format = 2 */
481 goto CLEAN_UP;
482 break;
483 case 1408:
484 if (encOption->encHeight[0] != 1152) /* source_format = 2 */
485 goto CLEAN_UP;
486 break;
487
488 default:
489 goto CLEAN_UP;
490 }
491 }
492 for (i = 0; i < encParams->nLayers; i++)
493 {
494 if (encOption->encHeight[i] == 0 || encOption->encWidth[i] == 0 ||
495 encOption->encHeight[i] % 16 != 0 || encOption->encWidth[i] % 16 != 0)
496 goto CLEAN_UP;
497 encParams->LayerHeight[i] = encOption->encHeight[i];
498 encParams->LayerWidth[i] = encOption->encWidth[i];
499 }
500
501 /* check frame rate */
502 for (i = 0; i < encParams->nLayers; i++)
503 {
504 encParams->LayerFrameRate[i] = encOption->encFrameRate[i];
505 }
506
507 if (encParams->nLayers > 1)
508 {
509 if (encOption->encFrameRate[0] == encOption->encFrameRate[1] ||
510 encOption->encFrameRate[0] == 0. || encOption->encFrameRate[1] == 0.) /* 7/31/03 */
511 goto CLEAN_UP;
512 }
513 /* set max frame rate */
514 for (i = 0; i < encParams->nLayers; i++)
515 {
516
517 /* Make sure the maximum framerate is consistent with the given profile and level */
518 nTotalMB = ((encParams->LayerWidth[i] + 15) / 16) * ((encParams->LayerHeight[i] + 15) / 16);
519
520 if (nTotalMB > 0)
521 profile_max_framerate = (float)encParams->LayerMaxMbsPerSec[i] / (float)nTotalMB;
522
523 else
524 profile_max_framerate = (float)30.0;
525
526 encParams->LayerMaxFrameRate[i] = PV_MIN(profile_max_framerate, encParams->LayerFrameRate[i]);
527 }
528
529 /* check bit rate */
530 for (i = 0; i < encParams->nLayers; i++)
531 {
532 encParams->LayerBitRate[i] = encOption->bitRate[i];
533 }
534 if (encParams->nLayers > 1)
535 {
536 if (encOption->bitRate[0] == encOption->bitRate[1] ||
537 encOption->bitRate[0] == 0 || encOption->bitRate[1] == 0) /* 7/31/03 */
538 goto CLEAN_UP;
539 }
540 /* check rate control and vbv delay*/
541 encParams->RC_Type = encOption->rcType;
542
543 if (encOption->vbvDelay == 0.0) /* set to default */
544 {
545 switch (encOption->rcType)
546 {
547 case CBR_1:
548 case CBR_2:
549 encParams->VBV_delay = (float)2.0; /* default 2sec VBV buffer size */
550 break;
551
552 case CBR_LOWDELAY:
553 encParams->VBV_delay = (float)0.5; /* default 0.5sec VBV buffer size */
554 break;
555
556 case VBR_1:
557 case VBR_2:
558 encParams->VBV_delay = (float)10.0; /* default 10sec VBV buffer size */
559 break;
560 default:
561 break;
562 }
563 }
564 else /* force this value */
565 {
566 encParams->VBV_delay = encOption->vbvDelay;
567 }
568
569 /* check search range */
570 if (encParams->H263_Enabled && encOption->searchRange > 16)
571 {
572 encParams->SearchRange = 16; /* 4/16/2001 */
573 }
574
575 /*****************************************/
576 /* checking for conflict between options */
577 /*****************************************/
578
579 if (video->encParams->RC_Type == CBR_1 || video->encParams->RC_Type == CBR_2 || video->encParams->RC_Type == CBR_LOWDELAY) /* if CBR */
580 {
581 #ifdef _PRINT_STAT
582 if (video->encParams->NoFrameSkip_Enabled == PV_ON ||
583 video->encParams->NoPreSkip_Enabled == PV_ON) /* don't allow frame skip*/
584 printf("WARNING!!!! CBR with NoFrameSkip\n");
585 #endif
586 }
587 else if (video->encParams->RC_Type == CONSTANT_Q) /* constant_Q */
588 {
589 video->encParams->NoFrameSkip_Enabled = PV_ON; /* no frame skip */
590 video->encParams->NoPreSkip_Enabled = PV_ON; /* no frame skip */
591 #ifdef _PRINT_STAT
592 printf("Turn on NoFrameSkip\n");
593 #endif
594 }
595
596 if (video->encParams->NoFrameSkip_Enabled == PV_ON) /* if no frame skip */
597 {
598 video->encParams->FineFrameSkip_Enabled = PV_OFF;
599 #ifdef _PRINT_STAT
600 printf("NoFrameSkip !!! may violate VBV_BUFFER constraint.\n");
601 printf("Turn off FineFrameSkip\n");
602 #endif
603 }
604
605 /******************************************/
606 /******************************************/
607
608 nLayers = video->encParams->nLayers; /* Number of Layers to be encoded */
609
610 /* Find the maximum width*height for memory allocation of the VOPs */
611 for (idx = 0; idx < nLayers; idx++)
612 {
613 temp_w = ((video->encParams->LayerWidth[idx] + 15) >> 4) << 4;
614 temp_h = ((video->encParams->LayerHeight[idx] + 15) >> 4) << 4;
615
616 if (temp_w > 2048 || temp_h > 2048) {
617 goto CLEAN_UP;
618 }
619
620 if ((temp_w*temp_h) > max)
621 {
622 max = temp_w * temp_h;
623 max_width = temp_w;
624 max_height = temp_h;
625
626 nTotalMB = ((max_width * max_height) >> 8);
627 }
628
629 /* Check if the video size and framerate(MBsPerSec) are vald */
630 mbsPerSec = (Int)(nTotalMB * video->encParams->LayerFrameRate[idx]);
631 if (mbsPerSec > video->encParams->LayerMaxMbsPerSec[idx]) status = PV_FALSE;
632 }
633
634 /****************************************************/
635 /* Set Profile and Video Buffer Size for each layer */
636 /****************************************************/
637 if (video->encParams->RC_Type == CBR_LOWDELAY) video->encParams->VBV_delay = 0.5; /* For CBR_LOWDELAY, we set 0.5sec buffer */
638 status = SetProfile_BufferSize(video, video->encParams->VBV_delay, 1);
639 if (status != PV_TRUE)
640 goto CLEAN_UP;
641
642 /****************************************/
643 /* memory allocation and initialization */
644 /****************************************/
645
646 if (video == NULL) goto CLEAN_UP;
647
648 /* cyclic reference for passing through both structures */
649 video->videoEncControls = encoderControl;
650
651 //video->currLayer = 0; /* Set current Layer to 0 */
652 //video->currFrameNo = 0; /* Set current frame Number to 0 */
653 video->nextModTime = 0;
654 video->nextEncIVop = 0; /* Sets up very first frame to be I-VOP! */
655 video->numVopsInGOP = 0; /* counter for Vops in Gop, 2/8/01 */
656
657 //video->frameRate = video->encParams->LayerFrameRate[0]; /* Set current layer frame rate */
658
659 video->QPMB = (UChar *) M4VENC_MALLOC(nTotalMB * sizeof(UChar)); /* Memory for MB quantizers */
660 if (video->QPMB == NULL) goto CLEAN_UP;
661
662
663 video->headerInfo.Mode = (UChar *) M4VENC_MALLOC(sizeof(UChar) * nTotalMB); /* Memory for MB Modes */
664 if (video->headerInfo.Mode == NULL) goto CLEAN_UP;
665 video->headerInfo.CBP = (UChar *) M4VENC_MALLOC(sizeof(UChar) * nTotalMB); /* Memory for CBP (Y and C) of each MB */
666 if (video->headerInfo.CBP == NULL) goto CLEAN_UP;
667
668 /* Allocating motion vector space and interpolation memory*/
669
670 if ((size_t)nTotalMB > SIZE_MAX / sizeof(MOT *)) {
671 goto CLEAN_UP;
672 }
673 video->mot = (MOT **)M4VENC_MALLOC(sizeof(MOT *) * nTotalMB);
674 if (video->mot == NULL) goto CLEAN_UP;
675
676 for (idx = 0; idx < nTotalMB; idx++)
677 {
678 video->mot[idx] = (MOT *)M4VENC_MALLOC(sizeof(MOT) * 8);
679 if (video->mot[idx] == NULL)
680 {
681 goto CLEAN_UP;
682 }
683 }
684
685 video->intraArray = (UChar *)M4VENC_MALLOC(sizeof(UChar) * nTotalMB);
686 if (video->intraArray == NULL) goto CLEAN_UP;
687
688 video->sliceNo = (UChar *) M4VENC_MALLOC(nTotalMB); /* Memory for Slice Numbers */
689 if (video->sliceNo == NULL) goto CLEAN_UP;
690 /* Allocating space for predDCAC[][8][16], Not that I intentionally */
691 /* increase the dimension of predDCAC from [][6][15] to [][8][16] */
692 /* so that compilers can generate faster code to indexing the */
693 /* data inside (by using << instead of *). 04/14/2000. */
694 /* 5/29/01, use decoder lib ACDC prediction memory scheme. */
695 if ((size_t)nTotalMB > SIZE_MAX / sizeof(typeDCStore)) {
696 goto CLEAN_UP;
697 }
698 video->predDC = (typeDCStore *) M4VENC_MALLOC(nTotalMB * sizeof(typeDCStore));
699 if (video->predDC == NULL) goto CLEAN_UP;
700
701 if (!video->encParams->H263_Enabled)
702 {
703 if ((size_t)((max_width >> 4) + 1) > SIZE_MAX / sizeof(typeDCACStore)) {
704 goto CLEAN_UP;
705 }
706 video->predDCAC_col = (typeDCACStore *) M4VENC_MALLOC(((max_width >> 4) + 1) * sizeof(typeDCACStore));
707 if (video->predDCAC_col == NULL) goto CLEAN_UP;
708
709 /* element zero will be used for storing vertical (col) AC coefficients */
710 /* the rest will be used for storing horizontal (row) AC coefficients */
711 video->predDCAC_row = video->predDCAC_col + 1; /* ACDC */
712
713 if ((size_t)nTotalMB > SIZE_MAX / sizeof(Int)) {
714 goto CLEAN_UP;
715 }
716 video->acPredFlag = (Int *) M4VENC_MALLOC(nTotalMB * sizeof(Int)); /* Memory for acPredFlag */
717 if (video->acPredFlag == NULL) goto CLEAN_UP;
718 }
719
720 video->outputMB = (MacroBlock *) M4VENC_MALLOC(sizeof(MacroBlock)); /* Allocating macroblock space */
721 if (video->outputMB == NULL) goto CLEAN_UP;
722 M4VENC_MEMSET(video->outputMB->block[0], 0, (sizeof(Short) << 6)*6);
723
724 M4VENC_MEMSET(video->dataBlock, 0, sizeof(Short) << 7);
725 /* Allocate (2*packetsize) working bitstreams */
726
727 video->bitstream1 = BitStreamCreateEnc(2 * 4096); /*allocate working stream 1*/
728 if (video->bitstream1 == NULL) goto CLEAN_UP;
729 video->bitstream2 = BitStreamCreateEnc(2 * 4096); /*allocate working stream 2*/
730 if (video->bitstream2 == NULL) goto CLEAN_UP;
731 video->bitstream3 = BitStreamCreateEnc(2 * 4096); /*allocate working stream 3*/
732 if (video->bitstream3 == NULL) goto CLEAN_UP;
733
734 /* allocate overrun buffer */
735 // this buffer is used when user's buffer is too small to hold one frame.
736 // It is not needed for slice-based encoding.
737 if (nLayers == 1)
738 {
739 video->oBSize = encParams->BufferSize[0] >> 3;
740 }
741 else
742 {
743 video->oBSize = PV_MAX((encParams->BufferSize[0] >> 3), (encParams->BufferSize[1] >> 3));
744 }
745
746 if (video->oBSize > DEFAULT_OVERRUN_BUFFER_SIZE || encParams->RC_Type == CONSTANT_Q) // set limit
747 {
748 video->oBSize = DEFAULT_OVERRUN_BUFFER_SIZE;
749 }
750 video->overrunBuffer = (UChar*) M4VENC_MALLOC(sizeof(UChar) * video->oBSize);
751 if (video->overrunBuffer == NULL) goto CLEAN_UP;
752
753
754 video->currVop = (Vop *) M4VENC_MALLOC(sizeof(Vop)); /* Memory for Current VOP */
755 if (video->currVop == NULL) goto CLEAN_UP;
756
757 /* add padding, 09/19/05 */
758 if (video->encParams->H263_Enabled) /* make it conditional 11/28/05 */
759 {
760 pitch = max_width;
761 offset = 0;
762 }
763 else
764 {
765 pitch = max_width + 32;
766 offset = (pitch << 4) + 16;
767 max_height += 32;
768 }
769 if (((uint64_t)pitch * max_height) > (uint64_t)INT32_MAX) {
770 goto CLEAN_UP;
771 }
772 size = pitch * max_height;
773
774 if (size > INT32_MAX - (size >> 1)
775 || (size_t)(size + (size >> 1)) > SIZE_MAX / sizeof(PIXEL)) {
776 goto CLEAN_UP;
777 }
778 video->currVop->allChan = video->currVop->yChan = (PIXEL *)M4VENC_MALLOC(sizeof(PIXEL) * (size + (size >> 1))); /* Memory for currVop Y */
779 if (video->currVop->yChan == NULL) goto CLEAN_UP;
780 video->currVop->uChan = video->currVop->yChan + size;/* Memory for currVop U */
781 video->currVop->vChan = video->currVop->uChan + (size >> 2);/* Memory for currVop V */
782
783 /* shift for the offset */
784 if (offset)
785 {
786 video->currVop->yChan += offset; /* offset to the origin.*/
787 video->currVop->uChan += (offset >> 2) + 4;
788 video->currVop->vChan += (offset >> 2) + 4;
789 }
790
791 video->forwardRefVop = video->currVop; /* Initialize forwardRefVop */
792 video->backwardRefVop = video->currVop; /* Initialize backwardRefVop */
793
794 video->prevBaseVop = (Vop *) M4VENC_MALLOC(sizeof(Vop)); /* Memory for Previous Base Vop */
795 if (video->prevBaseVop == NULL) goto CLEAN_UP;
796 video->prevBaseVop->allChan = video->prevBaseVop->yChan = (PIXEL *) M4VENC_MALLOC(sizeof(PIXEL) * (size + (size >> 1))); /* Memory for prevBaseVop Y */
797 if (video->prevBaseVop->yChan == NULL) goto CLEAN_UP;
798 video->prevBaseVop->uChan = video->prevBaseVop->yChan + size; /* Memory for prevBaseVop U */
799 video->prevBaseVop->vChan = video->prevBaseVop->uChan + (size >> 2); /* Memory for prevBaseVop V */
800
801 if (offset)
802 {
803 video->prevBaseVop->yChan += offset; /* offset to the origin.*/
804 video->prevBaseVop->uChan += (offset >> 2) + 4;
805 video->prevBaseVop->vChan += (offset >> 2) + 4;
806 }
807
808
809 if (0) /* If B Frames */
810 {
811 video->nextBaseVop = (Vop *) M4VENC_MALLOC(sizeof(Vop)); /* Memory for Next Base Vop */
812 if (video->nextBaseVop == NULL) goto CLEAN_UP;
813 video->nextBaseVop->allChan = video->nextBaseVop->yChan = (PIXEL *) M4VENC_MALLOC(sizeof(PIXEL) * (size + (size >> 1))); /* Memory for nextBaseVop Y */
814 if (video->nextBaseVop->yChan == NULL) goto CLEAN_UP;
815 video->nextBaseVop->uChan = video->nextBaseVop->yChan + size; /* Memory for nextBaseVop U */
816 video->nextBaseVop->vChan = video->nextBaseVop->uChan + (size >> 2); /* Memory for nextBaseVop V */
817
818 if (offset)
819 {
820 video->nextBaseVop->yChan += offset; /* offset to the origin.*/
821 video->nextBaseVop->uChan += (offset >> 2) + 4;
822 video->nextBaseVop->vChan += (offset >> 2) + 4;
823 }
824 }
825
826 if (nLayers > 1) /* If enhancement layers */
827 {
828 video->prevEnhanceVop = (Vop *) M4VENC_MALLOC(sizeof(Vop)); /* Memory for Previous Enhancement Vop */
829 if (video->prevEnhanceVop == NULL) goto CLEAN_UP;
830 video->prevEnhanceVop->allChan = video->prevEnhanceVop->yChan = (PIXEL *) M4VENC_MALLOC(sizeof(PIXEL) * (size + (size >> 1))); /* Memory for Previous Ehancement Y */
831 if (video->prevEnhanceVop->yChan == NULL) goto CLEAN_UP;
832 video->prevEnhanceVop->uChan = video->prevEnhanceVop->yChan + size; /* Memory for Previous Enhancement U */
833 video->prevEnhanceVop->vChan = video->prevEnhanceVop->uChan + (size >> 2); /* Memory for Previous Enhancement V */
834
835 if (offset)
836 {
837 video->prevEnhanceVop->yChan += offset; /* offset to the origin.*/
838 video->prevEnhanceVop->uChan += (offset >> 2) + 4;
839 video->prevEnhanceVop->vChan += (offset >> 2) + 4;
840 }
841 }
842
843 video->numberOfLayers = nLayers; /* Number of Layers */
844 video->sumMAD = 0;
845
846
847 /* 04/09/01, for Vops in the use multipass processing */
848 for (idx = 0; idx < nLayers; idx++)
849 {
850 video->pMP[idx] = (MultiPass *)M4VENC_MALLOC(sizeof(MultiPass));
851 if (video->pMP[idx] == NULL) goto CLEAN_UP;
852 M4VENC_MEMSET(video->pMP[idx], 0, sizeof(MultiPass));
853
854 video->pMP[idx]->encoded_frames = -1; /* forget about the very first I frame */
855
856
857 /* RDInfo **pRDSamples */
858 video->pMP[idx]->pRDSamples = (RDInfo **)M4VENC_MALLOC(30 * sizeof(RDInfo *));
859 if (video->pMP[idx]->pRDSamples == NULL) goto CLEAN_UP;
860 for (i = 0; i < 30; i++)
861 {
862 video->pMP[idx]->pRDSamples[i] = (RDInfo *)M4VENC_MALLOC(32 * sizeof(RDInfo));
863 if (video->pMP[idx]->pRDSamples[i] == NULL) goto CLEAN_UP;
864 for (j = 0; j < 32; j++) M4VENC_MEMSET(&(video->pMP[idx]->pRDSamples[i][j]), 0, sizeof(RDInfo));
865 }
866 video->pMP[idx]->frameRange = (Int)(video->encParams->LayerFrameRate[idx] * 1.0); /* 1.0s time frame*/
867 video->pMP[idx]->frameRange = PV_MAX(video->pMP[idx]->frameRange, 5);
868 video->pMP[idx]->frameRange = PV_MIN(video->pMP[idx]->frameRange, 30);
869
870 video->pMP[idx]->framePos = -1;
871
872 }
873 /* /// End /////////////////////////////////////// */
874
875
876 if ((size_t)nLayers > SIZE_MAX / sizeof(Vol *)) {
877 goto CLEAN_UP;
878 }
879 video->vol = (Vol **)M4VENC_MALLOC(nLayers * sizeof(Vol *)); /* Memory for VOL pointers */
880
881 /* Memory allocation and Initialization of Vols and writing of headers */
882 if (video->vol == NULL) goto CLEAN_UP;
883
884 for (idx = 0; idx < nLayers; idx++)
885 {
886 video->volInitialize[idx] = 1;
887 video->refTick[idx] = 0;
888 video->relLayerCodeTime[idx] = 1000;
889 video->vol[idx] = (Vol *)M4VENC_MALLOC(sizeof(Vol));
890 if (video->vol[idx] == NULL) goto CLEAN_UP;
891
892 pVol = video->vol[idx];
893 pEncParams = video->encParams;
894
895 M4VENC_MEMSET(video->vol[idx], 0, sizeof(Vol));
896 /* Initialize some VOL parameters */
897 pVol->volID = idx; /* Set VOL ID */
898 pVol->shortVideoHeader = pEncParams->H263_Enabled; /*Short Header */
899 pVol->GOVStart = pEncParams->GOV_Enabled; /* GOV Header */
900 pVol->timeIncrementResolution = video->encParams->TimeIncrementRes;
901 pVol->nbitsTimeIncRes = 1;
902 while (pVol->timeIncrementResolution > (1 << pVol->nbitsTimeIncRes))
903 {
904 pVol->nbitsTimeIncRes++;
905 }
906
907 /* timing stuff */
908 pVol->timeIncrement = 0;
909 pVol->moduloTimeBase = 0;
910 pVol->fixedVopRate = 0; /* No fixed VOP rate */
911 pVol->stream = (BitstreamEncVideo *)M4VENC_MALLOC(sizeof(BitstreamEncVideo)); /* allocate BitstreamEncVideo Instance */
912 if (pVol->stream == NULL) goto CLEAN_UP;
913
914 pVol->width = pEncParams->LayerWidth[idx]; /* Layer Width */
915 pVol->height = pEncParams->LayerHeight[idx]; /* Layer Height */
916 // pVol->intra_acdcPredDisable = pEncParams->ACDCPrediction; /* ACDC Prediction */
917 pVol->ResyncMarkerDisable = pEncParams->ResyncMarkerDisable; /* Resync Marker Mode */
918 pVol->dataPartitioning = pEncParams->DataPartitioning; /* Data Partitioning */
919 pVol->useReverseVLC = pEncParams->ReversibleVLC; /* RVLC */
920 if (idx > 0) /* Scalability layers */
921 {
922 pVol->ResyncMarkerDisable = 1;
923 pVol->dataPartitioning = 0;
924 pVol->useReverseVLC = 0; /* No RVLC */
925 }
926 pVol->quantType = pEncParams->QuantType[idx]; /* Quantizer Type */
927
928 /* no need to init Quant Matrices */
929
930 pVol->scalability = 0; /* Vol Scalability */
931 if (idx > 0)
932 pVol->scalability = 1; /* Multiple layers => Scalability */
933
934 /* Initialize Vol to Temporal scalability. It can change during encoding */
935 pVol->scalType = 1;
936 /* Initialize reference Vol ID to the base layer = 0 */
937 pVol->refVolID = 0;
938 /* Initialize layer resolution to same as the reference */
939 pVol->refSampDir = 0;
940 pVol->horSamp_m = 1;
941 pVol->horSamp_n = 1;
942 pVol->verSamp_m = 1;
943 pVol->verSamp_n = 1;
944 pVol->enhancementType = 0; /* We always enhance the entire region */
945
946 pVol->nMBPerRow = (pVol->width + 15) / 16;
947 pVol->nMBPerCol = (pVol->height + 15) / 16;
948 pVol->nTotalMB = pVol->nMBPerRow * pVol->nMBPerCol;
949
950 if (pVol->nTotalMB >= 1)
951 pVol->nBitsForMBID = 1;
952 if (pVol->nTotalMB >= 3)
953 pVol->nBitsForMBID = 2;
954 if (pVol->nTotalMB >= 5)
955 pVol->nBitsForMBID = 3;
956 if (pVol->nTotalMB >= 9)
957 pVol->nBitsForMBID = 4;
958 if (pVol->nTotalMB >= 17)
959 pVol->nBitsForMBID = 5;
960 if (pVol->nTotalMB >= 33)
961 pVol->nBitsForMBID = 6;
962 if (pVol->nTotalMB >= 65)
963 pVol->nBitsForMBID = 7;
964 if (pVol->nTotalMB >= 129)
965 pVol->nBitsForMBID = 8;
966 if (pVol->nTotalMB >= 257)
967 pVol->nBitsForMBID = 9;
968 if (pVol->nTotalMB >= 513)
969 pVol->nBitsForMBID = 10;
970 if (pVol->nTotalMB >= 1025)
971 pVol->nBitsForMBID = 11;
972 if (pVol->nTotalMB >= 2049)
973 pVol->nBitsForMBID = 12;
974 if (pVol->nTotalMB >= 4097)
975 pVol->nBitsForMBID = 13;
976 if (pVol->nTotalMB >= 8193)
977 pVol->nBitsForMBID = 14;
978 if (pVol->nTotalMB >= 16385)
979 pVol->nBitsForMBID = 15;
980 if (pVol->nTotalMB >= 32769)
981 pVol->nBitsForMBID = 16;
982 if (pVol->nTotalMB >= 65537)
983 pVol->nBitsForMBID = 17;
984 if (pVol->nTotalMB >= 131073)
985 pVol->nBitsForMBID = 18;
986
987 if (pVol->shortVideoHeader)
988 {
989 switch (pVol->width)
990 {
991 case 128:
992 if (pVol->height == 96) /* source_format = 1 */
993 {
994 pVol->nGOBinVop = 6;
995 pVol->nMBinGOB = 8;
996 }
997 else
998 status = PV_FALSE;
999 break;
1000
1001 case 176:
1002 if (pVol->height == 144) /* source_format = 2 */
1003 {
1004 pVol->nGOBinVop = 9;
1005 pVol->nMBinGOB = 11;
1006 }
1007 else
1008 status = PV_FALSE;
1009 break;
1010 case 352:
1011 if (pVol->height == 288) /* source_format = 2 */
1012 {
1013 pVol->nGOBinVop = 18;
1014 pVol->nMBinGOB = 22;
1015 }
1016 else
1017 status = PV_FALSE;
1018 break;
1019
1020 case 704:
1021 if (pVol->height == 576) /* source_format = 2 */
1022 {
1023 pVol->nGOBinVop = 18;
1024 pVol->nMBinGOB = 88;
1025 }
1026 else
1027 status = PV_FALSE;
1028 break;
1029 case 1408:
1030 if (pVol->height == 1152) /* source_format = 2 */
1031 {
1032 pVol->nGOBinVop = 18;
1033 pVol->nMBinGOB = 352;
1034 }
1035 else
1036 status = PV_FALSE;
1037 break;
1038
1039 default:
1040 status = PV_FALSE;
1041 break;
1042 }
1043 }
1044 }
1045
1046 /***************************************************/
1047 /* allocate and initialize rate control parameters */
1048 /***************************************************/
1049
1050 /* BEGIN INITIALIZATION OF ANNEX L RATE CONTROL */
1051 if (video->encParams->RC_Type != CONSTANT_Q)
1052 {
1053 for (idx = 0; idx < nLayers; idx++) /* 12/25/00 */
1054 {
1055 video->rc[idx] =
1056 (rateControl *)M4VENC_MALLOC(sizeof(rateControl));
1057
1058 if (video->rc[idx] == NULL) goto CLEAN_UP;
1059
1060 M4VENC_MEMSET(video->rc[idx], 0, sizeof(rateControl));
1061 }
1062 if (PV_SUCCESS != RC_Initialize(video))
1063 {
1064 goto CLEAN_UP;
1065 }
1066 /* initialization for 2-pass rate control */
1067 }
1068 /* END INITIALIZATION OF ANNEX L RATE CONTROL */
1069
1070 /********** assign platform dependent functions ***********************/
1071 /* 1/23/01 */
1072 /* This must be done at run-time not a compile time */
1073 video->functionPointer = (FuncPtr*) M4VENC_MALLOC(sizeof(FuncPtr));
1074 if (video->functionPointer == NULL) goto CLEAN_UP;
1075
1076 video->functionPointer->ComputeMBSum = &ComputeMBSum_C;
1077 video->functionPointer->SAD_MB_HalfPel[0] = NULL;
1078 video->functionPointer->SAD_MB_HalfPel[1] = &SAD_MB_HalfPel_Cxh;
1079 video->functionPointer->SAD_MB_HalfPel[2] = &SAD_MB_HalfPel_Cyh;
1080 video->functionPointer->SAD_MB_HalfPel[3] = &SAD_MB_HalfPel_Cxhyh;
1081
1082 #ifndef NO_INTER4V
1083 video->functionPointer->SAD_Blk_HalfPel = &SAD_Blk_HalfPel_C;
1084 video->functionPointer->SAD_Block = &SAD_Block_C;
1085 #endif
1086 video->functionPointer->SAD_Macroblock = &SAD_Macroblock_C;
1087 video->functionPointer->ChooseMode = &ChooseMode_C;
1088 video->functionPointer->GetHalfPelMBRegion = &GetHalfPelMBRegion_C;
1089 // video->functionPointer->SAD_MB_PADDING = &SAD_MB_PADDING; /* 4/21/01 */
1090
1091
1092 encoderControl->videoEncoderInit = 1; /* init done! */
1093
1094 return PV_TRUE;
1095
1096 CLEAN_UP:
1097 PVCleanUpVideoEncoder(encoderControl);
1098
1099 return PV_FALSE;
1100 }
1101
1102
1103 /* ======================================================================== */
1104 /* Function : PVCleanUpVideoEncoder() */
1105 /* Date : 08/22/2000 */
1106 /* Purpose : Deallocates allocated memory from InitVideoEncoder() */
1107 /* In/out : */
1108 /* Return : PV_TRUE if successed, PV_FALSE if failed. */
1109 /* Modified : 5/21/01, free only yChan in Vop */
1110 /* */
1111 /* ======================================================================== */
1112
PVCleanUpVideoEncoder(VideoEncControls * encoderControl)1113 OSCL_EXPORT_REF Bool PVCleanUpVideoEncoder(VideoEncControls *encoderControl)
1114 {
1115 Int idx, i;
1116 VideoEncData *video = (VideoEncData *)encoderControl->videoEncoderData;
1117 int nTotalMB;
1118 int max_width, offset;
1119
1120 #ifdef PRINT_RC_INFO
1121 if (facct != NULL)
1122 {
1123 fprintf(facct, "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n");
1124 fprintf(facct, "TOTAL NUM BITS GENERATED %d\n", tiTotalNumBitsGenerated);
1125 fprintf(facct, "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n");
1126 fprintf(facct, "TOTAL NUMBER OF FRAMES CODED %d\n",
1127 video->encParams->rc[0]->totalFrameNumber);
1128 fprintf(facct, "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n");
1129 fprintf(facct, "Average BitRate %d\n",
1130 (tiTotalNumBitsGenerated / (90 / 30)));
1131 fprintf(facct, "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n");
1132 fprintf(facct, "TOTAL NUMBER OF STUFF BITS %d\n", (iStuffBits + 10740));
1133 fprintf(facct, "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n");
1134 fprintf(facct, "TOTAL NUMBER OF BITS TO NETWORK %d\n", (35800*90 / 30));;
1135 fprintf(facct, "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n");
1136 fprintf(facct, "SUM OF STUFF BITS AND GENERATED BITS %d\n",
1137 (tiTotalNumBitsGenerated + iStuffBits + 10740));
1138 fprintf(facct, "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n");
1139 fprintf(facct, "UNACCOUNTED DIFFERENCE %d\n",
1140 ((35800*90 / 30) - (tiTotalNumBitsGenerated + iStuffBits + 10740)));
1141 fprintf(facct, "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n");
1142 fclose(facct);
1143 }
1144 #endif
1145
1146 #ifdef PRINT_EC
1147 fclose(fec);
1148 #endif
1149
1150 if (video != NULL)
1151 {
1152
1153 if (video->QPMB) M4VENC_FREE(video->QPMB);
1154 if (video->headerInfo.Mode)M4VENC_FREE(video->headerInfo.Mode);
1155 if (video->headerInfo.CBP)M4VENC_FREE(video->headerInfo.CBP);
1156
1157
1158 if (video->mot)
1159 {
1160 nTotalMB = video->vol[0]->nTotalMB;
1161 for (idx = 1; idx < video->currLayer; idx++)
1162 if (video->vol[idx]->nTotalMB > nTotalMB)
1163 nTotalMB = video->vol[idx]->nTotalMB;
1164 for (idx = 0; idx < nTotalMB; idx++)
1165 {
1166 if (video->mot[idx])
1167 M4VENC_FREE(video->mot[idx]);
1168 }
1169 M4VENC_FREE(video->mot);
1170 }
1171
1172 if (video->intraArray) M4VENC_FREE(video->intraArray);
1173
1174 if (video->sliceNo)M4VENC_FREE(video->sliceNo);
1175 if (video->acPredFlag)M4VENC_FREE(video->acPredFlag);
1176 // if(video->predDCAC)M4VENC_FREE(video->predDCAC);
1177 if (video->predDC) M4VENC_FREE(video->predDC);
1178 video->predDCAC_row = NULL;
1179 if (video->predDCAC_col) M4VENC_FREE(video->predDCAC_col);
1180 if (video->outputMB)M4VENC_FREE(video->outputMB);
1181
1182 if (video->bitstream1)BitstreamCloseEnc(video->bitstream1);
1183 if (video->bitstream2)BitstreamCloseEnc(video->bitstream2);
1184 if (video->bitstream3)BitstreamCloseEnc(video->bitstream3);
1185
1186 if (video->overrunBuffer) M4VENC_FREE(video->overrunBuffer);
1187
1188 max_width = video->encParams->LayerWidth[0];
1189 max_width = (((max_width + 15) >> 4) << 4); /* 09/19/05 */
1190 if (video->encParams->H263_Enabled)
1191 {
1192 offset = 0;
1193 }
1194 else
1195 {
1196 offset = ((max_width + 32) << 4) + 16;
1197 }
1198
1199 if (video->currVop)
1200 {
1201 if (video->currVop->allChan)
1202 {
1203 M4VENC_FREE(video->currVop->allChan);
1204 }
1205 M4VENC_FREE(video->currVop);
1206 }
1207
1208 if (video->nextBaseVop)
1209 {
1210 if (video->nextBaseVop->allChan)
1211 {
1212 M4VENC_FREE(video->nextBaseVop->allChan);
1213 }
1214 M4VENC_FREE(video->nextBaseVop);
1215 }
1216
1217 if (video->prevBaseVop)
1218 {
1219 if (video->prevBaseVop->allChan)
1220 {
1221 M4VENC_FREE(video->prevBaseVop->allChan);
1222 }
1223 M4VENC_FREE(video->prevBaseVop);
1224 }
1225 if (video->prevEnhanceVop)
1226 {
1227 if (video->prevEnhanceVop->allChan)
1228 {
1229 M4VENC_FREE(video->prevEnhanceVop->allChan);
1230 }
1231 M4VENC_FREE(video->prevEnhanceVop);
1232 }
1233
1234 /* 04/09/01, for Vops in the use multipass processing */
1235 for (idx = 0; idx < video->encParams->nLayers; idx++)
1236 {
1237 if (video->pMP[idx])
1238 {
1239 if (video->pMP[idx]->pRDSamples)
1240 {
1241 for (i = 0; i < 30; i++)
1242 {
1243 if (video->pMP[idx]->pRDSamples[i])
1244 M4VENC_FREE(video->pMP[idx]->pRDSamples[i]);
1245 }
1246 M4VENC_FREE(video->pMP[idx]->pRDSamples);
1247 }
1248
1249 M4VENC_MEMSET(video->pMP[idx], 0, sizeof(MultiPass));
1250 M4VENC_FREE(video->pMP[idx]);
1251 }
1252 }
1253 /* // End /////////////////////////////////////// */
1254
1255 if (video->vol)
1256 {
1257 for (idx = 0; idx < video->encParams->nLayers; idx++)
1258 {
1259 if (video->vol[idx])
1260 {
1261 if (video->vol[idx]->stream)
1262 M4VENC_FREE(video->vol[idx]->stream);
1263 M4VENC_FREE(video->vol[idx]);
1264 }
1265 }
1266 M4VENC_FREE(video->vol);
1267 }
1268
1269 /***************************************************/
1270 /* stop rate control parameters */
1271 /***************************************************/
1272
1273 /* ANNEX L RATE CONTROL */
1274 if (video->encParams->RC_Type != CONSTANT_Q)
1275 {
1276 RC_Cleanup(video->rc, video->encParams->nLayers);
1277
1278 for (idx = 0; idx < video->encParams->nLayers; idx++)
1279 {
1280 if (video->rc[idx])
1281 M4VENC_FREE(video->rc[idx]);
1282 }
1283 }
1284
1285 if (video->functionPointer) M4VENC_FREE(video->functionPointer);
1286
1287 /* If application has called PVCleanUpVideoEncoder then we deallocate */
1288 /* If PVInitVideoEncoder class it, then we DO NOT deallocate */
1289 if (video->encParams)
1290 {
1291 M4VENC_FREE(video->encParams);
1292 }
1293
1294 M4VENC_FREE(video);
1295 encoderControl->videoEncoderData = NULL; /* video */
1296 }
1297
1298 encoderControl->videoEncoderInit = 0;
1299
1300 return PV_TRUE;
1301 }
1302
1303 /* ======================================================================== */
1304 /* Function : PVGetVolHeader() */
1305 /* Date : 7/17/2001, */
1306 /* Purpose : */
1307 /* In/out : */
1308 /* Return : PV_TRUE if successed, PV_FALSE if failed. */
1309 /* Modified : */
1310 /* */
1311 /* ======================================================================== */
1312
PVGetVolHeader(VideoEncControls * encCtrl,UChar * volHeader,Int * size,Int layer)1313 OSCL_EXPORT_REF Bool PVGetVolHeader(VideoEncControls *encCtrl, UChar *volHeader, Int *size, Int layer)
1314 {
1315 VideoEncData *encData;
1316 PV_STATUS EncodeVOS_Start(VideoEncControls *encCtrl);
1317 encData = (VideoEncData *)encCtrl->videoEncoderData;
1318
1319
1320 if (encData == NULL)
1321 return PV_FALSE;
1322 if (encData->encParams == NULL)
1323 return PV_FALSE;
1324
1325
1326 encData->currLayer = layer; /* Set Layer */
1327 /*pv_status = */
1328 EncodeVOS_Start(encCtrl); /* Encode VOL Header */
1329
1330 encData->encParams->GetVolHeader[layer] = 1; /* Set usage flag: Needed to support old method*/
1331
1332 /* Copy bitstream to buffer and set the size */
1333
1334 if (*size > encData->bitstream1->byteCount)
1335 {
1336 *size = encData->bitstream1->byteCount;
1337 M4VENC_MEMCPY(volHeader, encData->bitstream1->bitstreamBuffer, *size);
1338 }
1339 else
1340 return PV_FALSE;
1341
1342 /* Reset bitstream1 buffer parameters */
1343 BitstreamEncReset(encData->bitstream1);
1344
1345 return PV_TRUE;
1346 }
1347
1348 /* ======================================================================== */
1349 /* Function : PVGetOverrunBuffer() */
1350 /* Purpose : Get the overrun buffer ` */
1351 /* In/out : */
1352 /* Return : Pointer to overrun buffer. */
1353 /* Modified : */
1354 /* ======================================================================== */
1355
PVGetOverrunBuffer(VideoEncControls * encCtrl)1356 OSCL_EXPORT_REF UChar* PVGetOverrunBuffer(VideoEncControls *encCtrl)
1357 {
1358 VideoEncData *video = (VideoEncData *)encCtrl->videoEncoderData;
1359 Int currLayer = video->currLayer;
1360 Vol *currVol = video->vol[currLayer];
1361
1362 if (currVol->stream->bitstreamBuffer != video->overrunBuffer) // not used
1363 {
1364 return NULL;
1365 }
1366
1367 return video->overrunBuffer;
1368 }
1369
1370
1371
1372
1373 /* ======================================================================== */
1374 /* Function : EncodeVideoFrame() */
1375 /* Date : 08/22/2000 */
1376 /* Purpose : Encode video frame and return bitstream */
1377 /* In/out : */
1378 /* Return : PV_TRUE if successed, PV_FALSE if failed. */
1379 /* Modified : */
1380 /* 02.14.2001 */
1381 /* Finishing new timestamp 32-bit input */
1382 /* Applications need to take care of wrap-around */
1383 /* ======================================================================== */
PVEncodeVideoFrame(VideoEncControls * encCtrl,VideoEncFrameIO * vid_in,VideoEncFrameIO * vid_out,ULong * nextModTime,UChar * bstream,Int * size,Int * nLayer)1384 OSCL_EXPORT_REF Bool PVEncodeVideoFrame(VideoEncControls *encCtrl, VideoEncFrameIO *vid_in, VideoEncFrameIO *vid_out,
1385 ULong *nextModTime, UChar *bstream, Int *size, Int *nLayer)
1386 {
1387 Bool status = PV_TRUE;
1388 PV_STATUS pv_status;
1389 VideoEncData *video = (VideoEncData *)encCtrl->videoEncoderData;
1390 VideoEncParams *encParams = video->encParams;
1391 Vol *currVol;
1392 Vop *tempForwRefVop = NULL;
1393 Int tempRefSelCode = 0;
1394 PV_STATUS EncodeVOS_Start(VideoEncControls *encCtrl);
1395 Int width_16, height_16;
1396 Int width, height;
1397 Vop *temp;
1398 Int encodeVop = 0;
1399 void PaddingEdge(Vop *padVop);
1400 Int currLayer = -1;
1401 //Int nLayers = encParams->nLayers;
1402
1403 ULong modTime = vid_in->timestamp;
1404
1405 #ifdef RANDOM_REFSELCODE /* add random selection of reference Vop */
1406 Int random_val[30] = {0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 0};
1407 static Int rand_idx = 0;
1408 #endif
1409
1410 /*******************************************************/
1411 /* Determine Next Vop to encode, if any, and nLayer */
1412 /*******************************************************/
1413 //i = nLayers-1;
1414
1415 if (video->volInitialize[0]) /* first vol to code */
1416 {
1417 video->nextModTime = video->modTimeRef = ((modTime) - ((modTime) % 1000));
1418 }
1419
1420 encodeVop = DetermineCodingLayer(video, nLayer, modTime);
1421 currLayer = *nLayer;
1422 if ((currLayer < 0) || (currLayer > encParams->nLayers - 1))
1423 return PV_FALSE;
1424
1425 /******************************************/
1426 /* If post-skipping still effective --- return */
1427 /******************************************/
1428
1429 if (!encodeVop) /* skip enh layer, no base layer coded --- return */
1430 {
1431 #ifdef _PRINT_STAT
1432 printf("No frame coded. Continue to next frame.");
1433 #endif
1434 /* expected next code time, convert back to millisec */
1435 *nextModTime = video->nextModTime;
1436
1437 #ifdef ALLOW_VOP_NOT_CODED
1438 if (video->vol[0]->shortVideoHeader) /* Short Video Header = 1 */
1439 {
1440 *size = 0;
1441 *nLayer = -1;
1442 }
1443 else
1444 {
1445 *nLayer = 0;
1446 EncodeVopNotCoded(video, bstream, size, modTime);
1447 *size = video->vol[0]->stream->byteCount;
1448 }
1449 #else
1450 *size = 0;
1451 *nLayer = -1;
1452 #endif
1453 return status;
1454 }
1455
1456
1457 //ENCODE_VOP_AGAIN: /* 12/30/00 */
1458
1459 /**************************************************************/
1460 /* Initialize Vol stream structure with application bitstream */
1461 /**************************************************************/
1462
1463 currVol = video->vol[currLayer];
1464 currVol->stream->bitstreamBuffer = bstream;
1465 currVol->stream->bufferSize = *size;
1466 BitstreamEncReset(currVol->stream);
1467 BitstreamSetOverrunBuffer(currVol->stream, video->overrunBuffer, video->oBSize, video);
1468
1469 /***********************************************************/
1470 /* Encode VOS and VOL Headers on first call for each layer */
1471 /***********************************************************/
1472
1473 if (video->volInitialize[currLayer])
1474 {
1475 video->currVop->timeInc = 0;
1476 video->prevBaseVop->timeInc = 0;
1477 if (!video->encParams->GetVolHeader[currLayer])
1478 pv_status = EncodeVOS_Start(encCtrl);
1479 }
1480
1481 /***************************************************/
1482 /* Copy Input Video Frame to Internal Video Buffer */
1483 /***************************************************/
1484 /* Determine Width and Height of Vop Layer */
1485
1486 width = encParams->LayerWidth[currLayer]; /* Get input width */
1487 height = encParams->LayerHeight[currLayer]; /* Get input height */
1488 /* Round Up to nearest multiple of 16 : MPEG-4 Standard */
1489
1490 width_16 = ((width + 15) / 16) * 16; /* Round up to nearest multiple of 16 */
1491 height_16 = ((height + 15) / 16) * 16; /* Round up to nearest multiple of 16 */
1492
1493 video->input = vid_in; /* point to the frame input */
1494
1495 /*// End ////////////////////////////// */
1496
1497
1498 /**************************************/
1499 /* Determine VOP Type */
1500 /* 6/2/2001, separate function */
1501 /**************************************/
1502 DetermineVopType(video, currLayer);
1503
1504 /****************************/
1505 /* Initialize VOP */
1506 /****************************/
1507 video->currVop->volID = currVol->volID;
1508 video->currVop->width = width_16;
1509 video->currVop->height = height_16;
1510 if (video->encParams->H263_Enabled) /* 11/28/05 */
1511 {
1512 video->currVop->pitch = width_16;
1513 }
1514 else
1515 {
1516 video->currVop->pitch = width_16 + 32;
1517 }
1518 video->currVop->timeInc = currVol->timeIncrement;
1519 video->currVop->vopCoded = 1;
1520 video->currVop->roundingType = 0;
1521 video->currVop->intraDCVlcThr = encParams->IntraDCVlcThr;
1522
1523 if (currLayer == 0
1524 #ifdef RANDOM_REFSELCODE /* add random selection of reference Vop */
1525 || random_val[rand_idx] || video->volInitialize[currLayer]
1526 #endif
1527 )
1528 {
1529 tempForwRefVop = video->forwardRefVop; /* keep initial state */
1530 if (tempForwRefVop != NULL) tempRefSelCode = tempForwRefVop->refSelectCode;
1531
1532 video->forwardRefVop = video->prevBaseVop;
1533 video->forwardRefVop->refSelectCode = 1;
1534 }
1535 #ifdef RANDOM_REFSELCODE
1536 else
1537 {
1538 tempForwRefVop = video->forwardRefVop; /* keep initial state */
1539 if (tempForwRefVop != NULL) tempRefSelCode = tempForwRefVop->refSelectCode;
1540
1541 video->forwardRefVop = video->prevEnhanceVop;
1542 video->forwardRefVop->refSelectCode = 0;
1543 }
1544 rand_idx++;
1545 rand_idx %= 30;
1546 #endif
1547
1548 video->currVop->refSelectCode = video->forwardRefVop->refSelectCode;
1549 video->currVop->gobNumber = 0;
1550 video->currVop->gobFrameID = video->currVop->predictionType;
1551 video->currVop->temporalRef = (modTime * 30 / 1001) % 256;
1552
1553 video->currVop->temporalInterval = 0;
1554
1555 if (video->currVop->predictionType == I_VOP)
1556 video->currVop->quantizer = encParams->InitQuantIvop[currLayer];
1557 else
1558 video->currVop->quantizer = encParams->InitQuantPvop[currLayer];
1559
1560
1561 /****************/
1562 /* Encode Vop */
1563 /****************/
1564 video->slice_coding = 0;
1565
1566 pv_status = EncodeVop(video);
1567 #ifdef _PRINT_STAT
1568 if (video->currVop->predictionType == I_VOP)
1569 printf(" I-VOP ");
1570 else
1571 printf(" P-VOP (ref.%d)", video->forwardRefVop->refSelectCode);
1572 #endif
1573
1574 /************************************/
1575 /* Update Skip Next Frame */
1576 /************************************/
1577 *nLayer = UpdateSkipNextFrame(video, nextModTime, size, pv_status);
1578 if (*nLayer == -1) /* skip current frame */
1579 {
1580 /* make sure that pointers are restored to the previous state */
1581 if (currLayer == 0)
1582 {
1583 video->forwardRefVop = tempForwRefVop; /* For P-Vop base only */
1584 if (video->forwardRefVop != NULL) video->forwardRefVop->refSelectCode = tempRefSelCode;
1585 }
1586
1587 return status;
1588 }
1589
1590 /* If I-VOP was encoded, reset IntraPeriod */
1591 if ((currLayer == 0) && (encParams->IntraPeriod > 0) && (video->currVop->predictionType == I_VOP))
1592 video->nextEncIVop = encParams->IntraPeriod;
1593
1594 /* Set HintTrack Information */
1595 if (currLayer != -1)
1596 {
1597 if (currVol->prevModuloTimeBase)
1598 video->hintTrackInfo.MTB = 1;
1599 else
1600 video->hintTrackInfo.MTB = 0;
1601 video->hintTrackInfo.LayerID = (UChar)currVol->volID;
1602 video->hintTrackInfo.CodeType = (UChar)video->currVop->predictionType;
1603 video->hintTrackInfo.RefSelCode = (UChar)video->currVop->refSelectCode;
1604 }
1605
1606 /************************************************/
1607 /* Determine nLayer and timeInc for next encode */
1608 /* 12/27/00 always go by the highest layer*/
1609 /************************************************/
1610
1611 /**********************************************************/
1612 /* Copy Reconstructed Buffer to Output Video Frame Buffer */
1613 /**********************************************************/
1614 vid_out->yChan = video->currVop->yChan;
1615 vid_out->uChan = video->currVop->uChan;
1616 vid_out->vChan = video->currVop->vChan;
1617 if (video->encParams->H263_Enabled)
1618 {
1619 vid_out->height = video->currVop->height; /* padded height */
1620 vid_out->pitch = video->currVop->width; /* padded width */
1621 }
1622 else
1623 {
1624 vid_out->height = video->currVop->height + 32; /* padded height */
1625 vid_out->pitch = video->currVop->width + 32; /* padded width */
1626 }
1627 //video_out->timestamp = video->modTime;
1628 vid_out->timestamp = (ULong)(((video->prevFrameNum[currLayer] * 1000) / encParams->LayerFrameRate[currLayer]) + video->modTimeRef + 0.5);
1629
1630 /*// End /////////////////////// */
1631
1632 /***********************************/
1633 /* Update Ouput bstream byte count */
1634 /***********************************/
1635
1636 *size = currVol->stream->byteCount;
1637
1638 /****************************************/
1639 /* Swap Vop Pointers for Base Layer */
1640 /****************************************/
1641 if (currLayer == 0)
1642 {
1643 temp = video->prevBaseVop;
1644 video->prevBaseVop = video->currVop;
1645 video->prevBaseVop->padded = 0; /* not padded */
1646 video->currVop = temp;
1647 video->forwardRefVop = video->prevBaseVop; /* For P-Vop base only */
1648 video->forwardRefVop->refSelectCode = 1;
1649 }
1650 else
1651 {
1652 temp = video->prevEnhanceVop;
1653 video->prevEnhanceVop = video->currVop;
1654 video->prevEnhanceVop->padded = 0; /* not padded */
1655 video->currVop = temp;
1656 video->forwardRefVop = video->prevEnhanceVop;
1657 video->forwardRefVop->refSelectCode = 0;
1658 }
1659
1660 /****************************************/
1661 /* Modify the intialize flag at the end.*/
1662 /****************************************/
1663 if (video->volInitialize[currLayer])
1664 video->volInitialize[currLayer] = 0;
1665
1666 return status;
1667 }
1668
1669 #ifndef NO_SLICE_ENCODE
1670 /* ======================================================================== */
1671 /* Function : PVEncodeFrameSet() */
1672 /* Date : 04/18/2000 */
1673 /* Purpose : Enter a video frame and perform front-end time check plus ME */
1674 /* In/out : */
1675 /* Return : PV_TRUE if successed, PV_FALSE if failed. */
1676 /* Modified : */
1677 /* */
1678 /* ======================================================================== */
PVEncodeFrameSet(VideoEncControls * encCtrl,VideoEncFrameIO * vid_in,ULong * nextModTime,Int * nLayer)1679 OSCL_EXPORT_REF Bool PVEncodeFrameSet(VideoEncControls *encCtrl, VideoEncFrameIO *vid_in, ULong *nextModTime, Int *nLayer)
1680 {
1681 Bool status = PV_TRUE;
1682 VideoEncData *video = (VideoEncData *)encCtrl->videoEncoderData;
1683 VideoEncParams *encParams = video->encParams;
1684 Vol *currVol;
1685 PV_STATUS EncodeVOS_Start(VideoEncControls *encCtrl);
1686 Int width_16, height_16;
1687 Int width, height;
1688 Int encodeVop = 0;
1689 void PaddingEdge(Vop *padVop);
1690 Int currLayer = -1;
1691 //Int nLayers = encParams->nLayers;
1692
1693 ULong modTime = vid_in->timestamp;
1694
1695 #ifdef RANDOM_REFSELCODE /* add random selection of reference Vop */
1696 Int random_val[30] = {0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 0};
1697 static Int rand_idx = 0;
1698 #endif
1699 /*******************************************************/
1700 /* Determine Next Vop to encode, if any, and nLayer */
1701 /*******************************************************/
1702
1703 video->modTime = modTime;
1704
1705 //i = nLayers-1;
1706
1707 if (video->volInitialize[0]) /* first vol to code */
1708 {
1709 video->nextModTime = video->modTimeRef = ((modTime) - ((modTime) % 1000));
1710 }
1711
1712
1713 encodeVop = DetermineCodingLayer(video, nLayer, modTime);
1714
1715 currLayer = *nLayer;
1716
1717 /******************************************/
1718 /* If post-skipping still effective --- return */
1719 /******************************************/
1720
1721 if (!encodeVop) /* skip enh layer, no base layer coded --- return */
1722 {
1723 #ifdef _PRINT_STAT
1724 printf("No frame coded. Continue to next frame.");
1725 #endif
1726 *nLayer = -1;
1727
1728 /* expected next code time, convert back to millisec */
1729 *nextModTime = video->nextModTime;;
1730 return status;
1731 }
1732
1733 /**************************************************************/
1734 /* Initialize Vol stream structure with application bitstream */
1735 /**************************************************************/
1736
1737 currVol = video->vol[currLayer];
1738 currVol->stream->bufferSize = 0;
1739 BitstreamEncReset(currVol->stream);
1740
1741 /***********************************************************/
1742 /* Encode VOS and VOL Headers on first call for each layer */
1743 /***********************************************************/
1744
1745 if (video->volInitialize[currLayer])
1746 {
1747 video->currVop->timeInc = 0;
1748 video->prevBaseVop->timeInc = 0;
1749 }
1750
1751 /***************************************************/
1752 /* Copy Input Video Frame to Internal Video Buffer */
1753 /***************************************************/
1754 /* Determine Width and Height of Vop Layer */
1755
1756 width = encParams->LayerWidth[currLayer]; /* Get input width */
1757 height = encParams->LayerHeight[currLayer]; /* Get input height */
1758 /* Round Up to nearest multiple of 16 : MPEG-4 Standard */
1759
1760 width_16 = ((width + 15) / 16) * 16; /* Round up to nearest multiple of 16 */
1761 height_16 = ((height + 15) / 16) * 16; /* Round up to nearest multiple of 16 */
1762
1763 video->input = vid_in; /* point to the frame input */
1764
1765 /*// End ////////////////////////////// */
1766
1767
1768 /**************************************/
1769 /* Determine VOP Type */
1770 /* 6/2/2001, separate function */
1771 /**************************************/
1772 DetermineVopType(video, currLayer);
1773
1774 /****************************/
1775 /* Initialize VOP */
1776 /****************************/
1777 video->currVop->volID = currVol->volID;
1778 video->currVop->width = width_16;
1779 video->currVop->height = height_16;
1780 if (video->encParams->H263_Enabled) /* 11/28/05 */
1781 {
1782 video->currVop->pitch = width_16;
1783 }
1784 else
1785 {
1786 video->currVop->pitch = width_16 + 32;
1787 }
1788 video->currVop->timeInc = currVol->timeIncrement;
1789 video->currVop->vopCoded = 1;
1790 video->currVop->roundingType = 0;
1791 video->currVop->intraDCVlcThr = encParams->IntraDCVlcThr;
1792
1793 if (currLayer == 0
1794 #ifdef RANDOM_REFSELCODE /* add random selection of reference Vop */
1795 || random_val[rand_idx] || video->volInitialize[currLayer]
1796 #endif
1797 )
1798 {
1799 video->tempForwRefVop = video->forwardRefVop; /* keep initial state */
1800 if (video->tempForwRefVop != NULL) video->tempRefSelCode = video->tempForwRefVop->refSelectCode;
1801
1802 video->forwardRefVop = video->prevBaseVop;
1803 video->forwardRefVop->refSelectCode = 1;
1804 }
1805 #ifdef RANDOM_REFSELCODE
1806 else
1807 {
1808 video->tempForwRefVop = video->forwardRefVop; /* keep initial state */
1809 if (video->tempForwRefVop != NULL) video->tempRefSelCode = video->tempForwRefVop->refSelectCode;
1810
1811 video->forwardRefVop = video->prevEnhanceVop;
1812 video->forwardRefVop->refSelectCode = 0;
1813 }
1814 rand_idx++;
1815 rand_idx %= 30;
1816 #endif
1817
1818 video->currVop->refSelectCode = video->forwardRefVop->refSelectCode;
1819 video->currVop->gobNumber = 0;
1820 video->currVop->gobFrameID = video->currVop->predictionType;
1821 video->currVop->temporalRef = ((modTime) * 30 / 1001) % 256;
1822
1823 video->currVop->temporalInterval = 0;
1824
1825 if (video->currVop->predictionType == I_VOP)
1826 video->currVop->quantizer = encParams->InitQuantIvop[currLayer];
1827 else
1828 video->currVop->quantizer = encParams->InitQuantPvop[currLayer];
1829
1830 /****************/
1831 /* Encode Vop */
1832 /****************/
1833 video->slice_coding = 1;
1834
1835 /*pv_status =*/
1836 EncodeVop(video);
1837
1838 #ifdef _PRINT_STAT
1839 if (video->currVop->predictionType == I_VOP)
1840 printf(" I-VOP ");
1841 else
1842 printf(" P-VOP (ref.%d)", video->forwardRefVop->refSelectCode);
1843 #endif
1844
1845 /* Set HintTrack Information */
1846 if (currVol->prevModuloTimeBase)
1847 video->hintTrackInfo.MTB = 1;
1848 else
1849 video->hintTrackInfo.MTB = 0;
1850
1851 video->hintTrackInfo.LayerID = (UChar)currVol->volID;
1852 video->hintTrackInfo.CodeType = (UChar)video->currVop->predictionType;
1853 video->hintTrackInfo.RefSelCode = (UChar)video->currVop->refSelectCode;
1854
1855 return status;
1856 }
1857 #endif /* NO_SLICE_ENCODE */
1858
1859 #ifndef NO_SLICE_ENCODE
1860 /* ======================================================================== */
1861 /* Function : PVEncodePacket() */
1862 /* Date : 04/18/2002 */
1863 /* Purpose : Encode one packet and return bitstream */
1864 /* In/out : */
1865 /* Return : PV_TRUE if successed, PV_FALSE if failed. */
1866 /* Modified : */
1867 /* */
1868 /* ======================================================================== */
PVEncodeSlice(VideoEncControls * encCtrl,UChar * bstream,Int * size,Int * endofFrame,VideoEncFrameIO * vid_out,ULong * nextModTime)1869 OSCL_EXPORT_REF Bool PVEncodeSlice(VideoEncControls *encCtrl, UChar *bstream, Int *size,
1870 Int *endofFrame, VideoEncFrameIO *vid_out, ULong *nextModTime)
1871 {
1872 PV_STATUS pv_status;
1873 VideoEncData *video = (VideoEncData *)encCtrl->videoEncoderData;
1874 VideoEncParams *encParams = video->encParams;
1875 Vol *currVol;
1876 PV_STATUS EncodeVOS_Start(VideoEncControls *encCtrl);
1877 Vop *temp;
1878 void PaddingEdge(Vop *padVop);
1879 Int currLayer = video->currLayer;
1880 Int pre_skip;
1881 Int pre_size;
1882 /**************************************************************/
1883 /* Initialize Vol stream structure with application bitstream */
1884 /**************************************************************/
1885
1886 currVol = video->vol[currLayer];
1887 currVol->stream->bitstreamBuffer = bstream;
1888 pre_size = currVol->stream->byteCount;
1889 currVol->stream->bufferSize = pre_size + (*size);
1890
1891 /***********************************************************/
1892 /* Encode VOS and VOL Headers on first call for each layer */
1893 /***********************************************************/
1894
1895 if (video->volInitialize[currLayer])
1896 {
1897 if (!video->encParams->GetVolHeader[currLayer])
1898 pv_status = EncodeVOS_Start(encCtrl);
1899 }
1900
1901 /****************/
1902 /* Encode Slice */
1903 /****************/
1904 pv_status = EncodeSlice(video);
1905
1906 *endofFrame = 0;
1907
1908 if (video->mbnum >= currVol->nTotalMB && !video->end_of_buf)
1909 {
1910 *endofFrame = 1;
1911
1912 /************************************/
1913 /* Update Skip Next Frame */
1914 /************************************/
1915 pre_skip = UpdateSkipNextFrame(video, nextModTime, size, pv_status); /* modified such that no pre-skipped */
1916
1917 if (pre_skip == -1) /* error */
1918 {
1919 *endofFrame = -1;
1920 /* make sure that pointers are restored to the previous state */
1921 if (currLayer == 0)
1922 {
1923 video->forwardRefVop = video->tempForwRefVop; /* For P-Vop base only */
1924 video->forwardRefVop->refSelectCode = video->tempRefSelCode;
1925 }
1926
1927 return pv_status;
1928 }
1929
1930 /* If I-VOP was encoded, reset IntraPeriod */
1931 if ((currLayer == 0) && (encParams->IntraPeriod > 0) && (video->currVop->predictionType == I_VOP))
1932 video->nextEncIVop = encParams->IntraPeriod;
1933
1934 /**********************************************************/
1935 /* Copy Reconstructed Buffer to Output Video Frame Buffer */
1936 /**********************************************************/
1937 vid_out->yChan = video->currVop->yChan;
1938 vid_out->uChan = video->currVop->uChan;
1939 vid_out->vChan = video->currVop->vChan;
1940 if (video->encParams->H263_Enabled)
1941 {
1942 vid_out->height = video->currVop->height; /* padded height */
1943 vid_out->pitch = video->currVop->width; /* padded width */
1944 }
1945 else
1946 {
1947 vid_out->height = video->currVop->height + 32; /* padded height */
1948 vid_out->pitch = video->currVop->width + 32; /* padded width */
1949 }
1950 //vid_out->timestamp = video->modTime;
1951 vid_out->timestamp = (ULong)(((video->prevFrameNum[currLayer] * 1000) / encParams->LayerFrameRate[currLayer]) + video->modTimeRef + 0.5);
1952
1953 /*// End /////////////////////// */
1954
1955 /****************************************/
1956 /* Swap Vop Pointers for Base Layer */
1957 /****************************************/
1958
1959 if (currLayer == 0)
1960 {
1961 temp = video->prevBaseVop;
1962 video->prevBaseVop = video->currVop;
1963 video->prevBaseVop->padded = 0; /* not padded */
1964 video->currVop = temp;
1965 video->forwardRefVop = video->prevBaseVop; /* For P-Vop base only */
1966 video->forwardRefVop->refSelectCode = 1;
1967 }
1968 else
1969 {
1970 temp = video->prevEnhanceVop;
1971 video->prevEnhanceVop = video->currVop;
1972 video->prevEnhanceVop->padded = 0; /* not padded */
1973 video->currVop = temp;
1974 video->forwardRefVop = video->prevEnhanceVop;
1975 video->forwardRefVop->refSelectCode = 0;
1976 }
1977 }
1978
1979 /***********************************/
1980 /* Update Ouput bstream byte count */
1981 /***********************************/
1982
1983 *size = currVol->stream->byteCount - pre_size;
1984
1985 /****************************************/
1986 /* Modify the intialize flag at the end.*/
1987 /****************************************/
1988 if (video->volInitialize[currLayer])
1989 video->volInitialize[currLayer] = 0;
1990
1991 return pv_status;
1992 }
1993 #endif /* NO_SLICE_ENCODE */
1994
1995
1996 /* ======================================================================== */
1997 /* Function : PVGetH263ProfileLevelID() */
1998 /* Date : 02/05/2003 */
1999 /* Purpose : Get H.263 Profile ID and level ID for profile 0 */
2000 /* In/out : Profile ID=0, levelID is what we want */
2001 /* Return : PV_TRUE if successed, PV_FALSE if failed. */
2002 /* Modified : */
2003 /* Note : h263Level[8], rBR_bound[8], max_h263_framerate[2] */
2004 /* max_h263_width[2], max_h263_height[2] are global */
2005 /* */
2006 /* ======================================================================== */
PVGetH263ProfileLevelID(VideoEncControls * encCtrl,Int * profileID,Int * levelID)2007 OSCL_EXPORT_REF Bool PVGetH263ProfileLevelID(VideoEncControls *encCtrl, Int *profileID, Int *levelID)
2008 {
2009 VideoEncData *encData;
2010 Int width, height;
2011 float bitrate_r, framerate;
2012
2013
2014 /* For this version, we only support H.263 profile 0 */
2015 *profileID = 0;
2016
2017 *levelID = 0;
2018 encData = (VideoEncData *)encCtrl->videoEncoderData;
2019
2020 if (encData == NULL)
2021 return PV_FALSE;
2022 if (encData->encParams == NULL)
2023 return PV_FALSE;
2024
2025 if (!encData->encParams->H263_Enabled) return PV_FALSE;
2026
2027
2028 /* get image width, height, bitrate and framerate */
2029 width = encData->encParams->LayerWidth[0];
2030 height = encData->encParams->LayerHeight[0];
2031 bitrate_r = (float)(encData->encParams->LayerBitRate[0]) / (float)64000.0;
2032 framerate = encData->encParams->LayerFrameRate[0];
2033 if (!width || !height || !(bitrate_r > 0 && framerate > 0)) return PV_FALSE;
2034
2035 /* This is the most frequent case : level 10 */
2036 if (bitrate_r <= rBR_bound[1] && framerate <= max_h263_framerate[0] &&
2037 (width <= max_h263_width[0] && height <= max_h263_height[0]))
2038 {
2039 *levelID = h263Level[1];
2040 return PV_TRUE;
2041 }
2042 else if (bitrate_r > rBR_bound[4] ||
2043 (width > max_h263_width[1] || height > max_h263_height[1]) ||
2044 framerate > max_h263_framerate[1]) /* check the highest level 70 */
2045 {
2046 *levelID = h263Level[7];
2047 return PV_TRUE;
2048 }
2049 else /* search level 20, 30, 40 */
2050 {
2051
2052 /* pick out level 20 */
2053 if (bitrate_r <= rBR_bound[2] &&
2054 ((width <= max_h263_width[0] && height <= max_h263_height[0] && framerate <= max_h263_framerate[1]) ||
2055 (width <= max_h263_width[1] && height <= max_h263_height[1] && framerate <= max_h263_framerate[0])))
2056 {
2057 *levelID = h263Level[2];
2058 return PV_TRUE;
2059 }
2060 else /* width, height and framerate are ok, now choose level 30 or 40 */
2061 {
2062 *levelID = (bitrate_r <= rBR_bound[3] ? h263Level[3] : h263Level[4]);
2063 return PV_TRUE;
2064 }
2065 }
2066 }
2067
2068 /* ======================================================================== */
2069 /* Function : PVGetMPEG4ProfileLevelID() */
2070 /* Date : 26/06/2008 */
2071 /* Purpose : Get MPEG4 Level after initialized */
2072 /* In/out : profile_level according to interface */
2073 /* Return : PV_TRUE if successed, PV_FALSE if failed. */
2074 /* Modified : */
2075 /* */
2076 /* ======================================================================== */
PVGetMPEG4ProfileLevelID(VideoEncControls * encCtrl,Int * profile_level,Int nLayer)2077 OSCL_EXPORT_REF Bool PVGetMPEG4ProfileLevelID(VideoEncControls *encCtrl, Int *profile_level, Int nLayer)
2078 {
2079 VideoEncData* video;
2080 Int i;
2081
2082 video = (VideoEncData *)encCtrl->videoEncoderData;
2083
2084 if (nLayer == 0)
2085 {
2086 for (i = 0; i < 8; i++)
2087 {
2088 if (video->encParams->ProfileLevel[0] == profile_level_code[i])
2089 {
2090 break;
2091 }
2092 }
2093 *profile_level = i;
2094 }
2095 else
2096 {
2097 for (i = 0; i < 8; i++)
2098 {
2099 if (video->encParams->ProfileLevel[0] == scalable_profile_level_code[i])
2100 {
2101 break;
2102 }
2103 }
2104 *profile_level = i + SIMPLE_SCALABLE_PROFILE_LEVEL0;
2105 }
2106
2107 return true;
2108 }
2109
2110 #ifndef LIMITED_API
2111 /* ======================================================================== */
2112 /* Function : PVUpdateEncFrameRate */
2113 /* Date : 04/08/2002 */
2114 /* Purpose : Update target frame rates of the encoded base and enhance */
2115 /* layer(if any) while encoding operation is ongoing */
2116 /* In/out : */
2117 /* Return : PV_TRUE if successed, PV_FALSE if failed. */
2118 /* Modified : */
2119 /* */
2120 /* ======================================================================== */
2121
PVUpdateEncFrameRate(VideoEncControls * encCtrl,float * frameRate)2122 OSCL_EXPORT_REF Bool PVUpdateEncFrameRate(VideoEncControls *encCtrl, float *frameRate)
2123 {
2124 VideoEncData *encData;
2125 Int i;// nTotalMB, mbPerSec;
2126
2127 encData = (VideoEncData *)encCtrl->videoEncoderData;
2128
2129 if (encData == NULL)
2130 return PV_FALSE;
2131 if (encData->encParams == NULL)
2132 return PV_FALSE;
2133
2134 /* Update the framerates for all the layers */
2135 for (i = 0; i < encData->encParams->nLayers; i++)
2136 {
2137
2138 /* New check: encoding framerate should be consistent with the given profile and level */
2139 //nTotalMB = (((encData->encParams->LayerWidth[i]+15)/16)*16)*(((encData->encParams->LayerHeight[i]+15)/16)*16)/(16*16);
2140 //mbPerSec = (Int)(nTotalMB * frameRate[i]);
2141 //if(mbPerSec > encData->encParams->LayerMaxMbsPerSec[i]) return PV_FALSE;
2142 if (frameRate[i] > encData->encParams->LayerMaxFrameRate[i]) return PV_FALSE; /* set by users or profile */
2143
2144 encData->encParams->LayerFrameRate[i] = frameRate[i];
2145 }
2146
2147 return RC_UpdateBXRCParams((void*) encData);
2148
2149 }
2150 #endif
2151 #ifndef LIMITED_API
2152 /* ======================================================================== */
2153 /* Function : PVUpdateBitRate */
2154 /* Date : 04/08/2002 */
2155 /* Purpose : Update target bit rates of the encoded base and enhance */
2156 /* layer(if any) while encoding operation is ongoing */
2157 /* In/out : */
2158 /* Return : PV_TRUE if successed, PV_FALSE if failed. */
2159 /* Modified : */
2160 /* */
2161 /* ======================================================================== */
2162
PVUpdateBitRate(VideoEncControls * encCtrl,Int * bitRate)2163 OSCL_EXPORT_REF Bool PVUpdateBitRate(VideoEncControls *encCtrl, Int *bitRate)
2164 {
2165 VideoEncData *encData;
2166 Int i;
2167
2168 encData = (VideoEncData *)encCtrl->videoEncoderData;
2169
2170 if (encData == NULL)
2171 return PV_FALSE;
2172 if (encData->encParams == NULL)
2173 return PV_FALSE;
2174
2175 /* Update the bitrates for all the layers */
2176 for (i = 0; i < encData->encParams->nLayers; i++)
2177 {
2178 if (bitRate[i] > encData->encParams->LayerMaxBitRate[i]) /* set by users or profile */
2179 {
2180 return PV_FALSE;
2181 }
2182 encData->encParams->LayerBitRate[i] = bitRate[i];
2183 }
2184
2185 return RC_UpdateBXRCParams((void*) encData);
2186
2187 }
2188 #endif
2189 #ifndef LIMITED_API
2190 /* ============================================================================ */
2191 /* Function : PVUpdateVBVDelay() */
2192 /* Date : 4/23/2004 */
2193 /* Purpose : Update VBV buffer size(in delay) */
2194 /* In/out : */
2195 /* Return : PV_TRUE if successed, PV_FALSE if failed. */
2196 /* Modified : */
2197 /* */
2198 /* ============================================================================ */
2199
PVUpdateVBVDelay(VideoEncControls * encCtrl,float delay)2200 Bool PVUpdateVBVDelay(VideoEncControls *encCtrl, float delay)
2201 {
2202
2203 VideoEncData *encData;
2204 Int total_bitrate, max_buffer_size;
2205 int index;
2206
2207 encData = (VideoEncData *)encCtrl->videoEncoderData;
2208
2209 if (encData == NULL)
2210 return PV_FALSE;
2211 if (encData->encParams == NULL)
2212 return PV_FALSE;
2213
2214 /* Check whether the input delay is valid based on the given profile */
2215 total_bitrate = (encData->encParams->nLayers == 1 ? encData->encParams->LayerBitRate[0] :
2216 encData->encParams->LayerBitRate[1]);
2217 index = encData->encParams->profile_table_index;
2218 max_buffer_size = (encData->encParams->nLayers == 1 ? profile_level_max_VBV_size[index] :
2219 scalable_profile_level_max_VBV_size[index]);
2220
2221 if (total_bitrate*delay > (float)max_buffer_size)
2222 return PV_FALSE;
2223
2224 encData->encParams->VBV_delay = delay;
2225 return PV_TRUE;
2226
2227 }
2228 #endif
2229 #ifndef LIMITED_API
2230 /* ======================================================================== */
2231 /* Function : PVUpdateIFrameInterval() */
2232 /* Date : 04/10/2002 */
2233 /* Purpose : updates the INTRA frame refresh interval while encoding */
2234 /* is ongoing */
2235 /* In/out : */
2236 /* Return : PV_TRUE if successed, PV_FALSE if failed. */
2237 /* Modified : */
2238 /* */
2239 /* ======================================================================== */
2240
PVUpdateIFrameInterval(VideoEncControls * encCtrl,Int aIFramePeriod)2241 OSCL_EXPORT_REF Bool PVUpdateIFrameInterval(VideoEncControls *encCtrl, Int aIFramePeriod)
2242 {
2243 VideoEncData *encData;
2244
2245 encData = (VideoEncData *)encCtrl->videoEncoderData;
2246
2247 if (encData == NULL)
2248 return PV_FALSE;
2249 if (encData->encParams == NULL)
2250 return PV_FALSE;
2251
2252 encData->encParams->IntraPeriod = aIFramePeriod;
2253 return PV_TRUE;
2254 }
2255 #endif
2256 #ifndef LIMITED_API
2257 /* ======================================================================== */
2258 /* Function : PVSetNumIntraMBRefresh() */
2259 /* Date : 08/05/2003 */
2260 /* Purpose : */
2261 /* In/out : */
2262 /* Return : PV_TRUE if successed, PV_FALSE if failed. */
2263 /* Modified : */
2264 /* */
2265 /* ======================================================================== */
PVUpdateNumIntraMBRefresh(VideoEncControls * encCtrl,Int numMB)2266 OSCL_EXPORT_REF Bool PVUpdateNumIntraMBRefresh(VideoEncControls *encCtrl, Int numMB)
2267 {
2268 VideoEncData *encData;
2269
2270 encData = (VideoEncData *)encCtrl->videoEncoderData;
2271
2272 if (encData == NULL)
2273 return PV_FALSE;
2274
2275 encData->encParams->Refresh = numMB;
2276
2277 return PV_TRUE;
2278 }
2279 #endif
2280 #ifndef LIMITED_API
2281 /* ======================================================================== */
2282 /* Function : PVIFrameRequest() */
2283 /* Date : 04/10/2002 */
2284 /* Purpose : encodes the next base frame as an I-Vop */
2285 /* In/out : */
2286 /* Return : PV_TRUE if successed, PV_FALSE if failed. */
2287 /* Modified : */
2288 /* */
2289 /* ======================================================================== */
2290
PVIFrameRequest(VideoEncControls * encCtrl)2291 OSCL_EXPORT_REF Bool PVIFrameRequest(VideoEncControls *encCtrl)
2292 {
2293 VideoEncData *encData;
2294
2295 encData = (VideoEncData *)encCtrl->videoEncoderData;
2296
2297 if (encData == NULL)
2298 return PV_FALSE;
2299 if (encData->encParams == NULL)
2300 return PV_FALSE;
2301
2302 encData->nextEncIVop = 1;
2303 return PV_TRUE;
2304 }
2305 #endif
2306 #ifndef LIMITED_API
2307 /* ======================================================================== */
2308 /* Function : PVGetEncMemoryUsage() */
2309 /* Date : 10/17/2000 */
2310 /* Purpose : */
2311 /* In/out : */
2312 /* Return : PV_TRUE if successed, PV_FALSE if failed. */
2313 /* Modified : */
2314 /* */
2315 /* ======================================================================== */
2316
PVGetEncMemoryUsage(VideoEncControls * encCtrl)2317 OSCL_EXPORT_REF Int PVGetEncMemoryUsage(VideoEncControls *encCtrl)
2318 {
2319 VideoEncData *encData;
2320
2321 encData = (VideoEncData *)encCtrl->videoEncoderData;
2322
2323 if (encData == NULL)
2324 return PV_FALSE;
2325 if (encData->encParams == NULL)
2326 return PV_FALSE;
2327 return encData->encParams->MemoryUsage;
2328 }
2329 #endif
2330
2331 /* ======================================================================== */
2332 /* Function : PVGetHintTrack() */
2333 /* Date : 1/17/2001, */
2334 /* Purpose : */
2335 /* In/out : */
2336 /* Return : PV_TRUE if successed, PV_FALSE if failed. */
2337 /* Modified : */
2338 /* */
2339 /* ======================================================================== */
2340
PVGetHintTrack(VideoEncControls * encCtrl,MP4HintTrack * info)2341 OSCL_EXPORT_REF Bool PVGetHintTrack(VideoEncControls *encCtrl, MP4HintTrack *info)
2342 {
2343 VideoEncData *encData;
2344
2345 encData = (VideoEncData *)encCtrl->videoEncoderData;
2346
2347 if (encData == NULL)
2348 return PV_FALSE;
2349 if (encData->encParams == NULL)
2350 return PV_FALSE;
2351 info->MTB = encData->hintTrackInfo.MTB;
2352 info->LayerID = encData->hintTrackInfo.LayerID;
2353 info->CodeType = encData->hintTrackInfo.CodeType;
2354 info->RefSelCode = encData->hintTrackInfo.RefSelCode;
2355
2356 return PV_TRUE;
2357 }
2358
2359 /* ======================================================================== */
2360 /* Function : PVGetMaxVideoFrameSize() */
2361 /* Date : 7/17/2001, */
2362 /* Purpose : Function merely returns the maximum buffer size */
2363 /* In/out : */
2364 /* Return : PV_TRUE if successed, PV_FALSE if failed. */
2365 /* Modified : */
2366 /* */
2367 /* ======================================================================== */
2368
PVGetMaxVideoFrameSize(VideoEncControls * encCtrl,Int * maxVideoFrameSize)2369 OSCL_EXPORT_REF Bool PVGetMaxVideoFrameSize(VideoEncControls *encCtrl, Int *maxVideoFrameSize)
2370 {
2371 VideoEncData *encData;
2372
2373 encData = (VideoEncData *)encCtrl->videoEncoderData;
2374
2375 if (encData == NULL)
2376 return PV_FALSE;
2377 if (encData->encParams == NULL)
2378 return PV_FALSE;
2379
2380
2381
2382 *maxVideoFrameSize = encData->encParams->BufferSize[0];
2383
2384 if (encData->encParams->nLayers == 2)
2385 if (*maxVideoFrameSize < encData->encParams->BufferSize[1])
2386 *maxVideoFrameSize = encData->encParams->BufferSize[1];
2387 *maxVideoFrameSize >>= 3; /* Convert to Bytes */
2388
2389 if (*maxVideoFrameSize <= 4000)
2390 *maxVideoFrameSize = 4000;
2391
2392 return PV_TRUE;
2393 }
2394 #ifndef LIMITED_API
2395 /* ======================================================================== */
2396 /* Function : PVGetVBVSize() */
2397 /* Date : 4/15/2002 */
2398 /* Purpose : Function merely returns the maximum buffer size */
2399 /* In/out : */
2400 /* Return : PV_TRUE if successed, PV_FALSE if failed. */
2401 /* Modified : */
2402 /* */
2403 /* ======================================================================== */
2404
PVGetVBVSize(VideoEncControls * encCtrl,Int * VBVSize)2405 OSCL_EXPORT_REF Bool PVGetVBVSize(VideoEncControls *encCtrl, Int *VBVSize)
2406 {
2407 VideoEncData *encData;
2408
2409 encData = (VideoEncData *)encCtrl->videoEncoderData;
2410
2411 if (encData == NULL)
2412 return PV_FALSE;
2413 if (encData->encParams == NULL)
2414 return PV_FALSE;
2415
2416 *VBVSize = encData->encParams->BufferSize[0];
2417 if (encData->encParams->nLayers == 2)
2418 *VBVSize += encData->encParams->BufferSize[1];
2419
2420 return PV_TRUE;
2421
2422 }
2423 #endif
2424 /* ======================================================================== */
2425 /* Function : EncodeVOS_Start() */
2426 /* Date : 08/22/2000 */
2427 /* Purpose : Encodes the VOS,VO, and VOL or Short Headers */
2428 /* In/out : */
2429 /* Return : PV_TRUE if successed, PV_FALSE if failed. */
2430 /* Modified : */
2431 /* */
2432 /* ======================================================================== */
EncodeVOS_Start(VideoEncControls * encoderControl)2433 PV_STATUS EncodeVOS_Start(VideoEncControls *encoderControl)
2434 {
2435
2436 VideoEncData *video = (VideoEncData *)encoderControl->videoEncoderData;
2437 Vol *currVol = video->vol[video->currLayer];
2438 PV_STATUS status = PV_SUCCESS;
2439 //int profile_level=0x01;
2440 BitstreamEncVideo *stream = video->bitstream1;
2441 int i, j;
2442
2443 /********************************/
2444 /* Check for short_video_header */
2445 /********************************/
2446 if (currVol->shortVideoHeader == 1)
2447 return status;
2448 else
2449 {
2450 /* Short Video Header or M4V */
2451
2452 /**************************/
2453 /* VisualObjectSequence ()*/
2454 /**************************/
2455 status = BitstreamPutGT16Bits(stream, 32, SESSION_START_CODE);
2456 /* Determine profile_level */
2457 status = BitstreamPutBits(stream, 8, video->encParams->ProfileLevel[video->currLayer]);
2458
2459 /******************/
2460 /* VisualObject() */
2461 /******************/
2462
2463 status = BitstreamPutGT16Bits(stream, 32, VISUAL_OBJECT_START_CODE);
2464 status = BitstreamPut1Bits(stream, 0x00); /* visual object identifier */
2465 status = BitstreamPutBits(stream, 4, 0x01); /* visual object Type == "video ID" */
2466 status = BitstreamPut1Bits(stream, 0x00); /* no video signal type */
2467
2468 /*temp = */
2469 BitstreamMpeg4ByteAlignStuffing(stream);
2470
2471
2472 status = BitstreamPutGT16Bits(stream, 27, VO_START_CODE);/* byte align: should be 2 bits */
2473 status = BitstreamPutBits(stream, 5, 0x00);/* Video ID = 0 */
2474
2475
2476
2477 /**********************/
2478 /* VideoObjectLayer() */
2479 /**********************/
2480 if (currVol->shortVideoHeader == 0)
2481 { /* M4V else Short Video Header */
2482 status = BitstreamPutGT16Bits(stream, VOL_START_CODE_LENGTH, VOL_START_CODE);
2483 status = BitstreamPutBits(stream, 4, currVol->volID);/* video_object_layer_id */
2484 status = BitstreamPut1Bits(stream, 0x00);/* Random Access = 0 */
2485
2486 if (video->currLayer == 0)
2487 status = BitstreamPutBits(stream, 8, 0x01);/* Video Object Type Indication = 1 ... Simple Object Type */
2488 else
2489 status = BitstreamPutBits(stream, 8, 0x02);/* Video Object Type Indication = 2 ... Simple Scalable Object Type */
2490
2491 status = BitstreamPut1Bits(stream, 0x00);/* is_object_layer_identifer = 0 */
2492
2493
2494 status = BitstreamPutBits(stream, 4, 0x01); /* aspect_ratio_info = 1 ... 1:1(Square) */
2495 status = BitstreamPut1Bits(stream, 0x00);/* vol_control_parameters = 0 */
2496 status = BitstreamPutBits(stream, 2, 0x00);/* video_object_layer_shape = 00 ... rectangular */
2497 status = BitstreamPut1Bits(stream, 0x01);/* marker bit */
2498 status = BitstreamPutGT8Bits(stream, 16, currVol->timeIncrementResolution);/* vop_time_increment_resolution */
2499 status = BitstreamPut1Bits(stream, 0x01);/* marker bit */
2500 status = BitstreamPut1Bits(stream, currVol->fixedVopRate);/* fixed_vop_rate = 0 */
2501
2502 /* For Rectangular VO layer shape */
2503 status = BitstreamPut1Bits(stream, 0x01);/* marker bit */
2504 status = BitstreamPutGT8Bits(stream, 13, currVol->width);/* video_object_layer_width */
2505 status = BitstreamPut1Bits(stream, 0x01);/* marker bit */
2506 status = BitstreamPutGT8Bits(stream, 13, currVol->height);/* video_object_layer_height */
2507 status = BitstreamPut1Bits(stream, 0x01);/*marker bit */
2508
2509 status = BitstreamPut1Bits(stream, 0x00);/*interlaced = 0 */
2510 status = BitstreamPut1Bits(stream, 0x01);/* obmc_disable = 1 */
2511 status = BitstreamPut1Bits(stream, 0x00);/* sprite_enable = 0 */
2512 status = BitstreamPut1Bits(stream, 0x00);/* not_8_bit = 0 */
2513 status = BitstreamPut1Bits(stream, currVol->quantType);/* quant_type */
2514
2515 if (currVol->quantType)
2516 {
2517 status = BitstreamPut1Bits(stream, currVol->loadIntraQuantMat); /* Intra quant matrix */
2518 if (currVol->loadIntraQuantMat)
2519 {
2520 for (j = 63; j >= 1; j--)
2521 if (currVol->iqmat[*(zigzag_i+j)] != currVol->iqmat[*(zigzag_i+j-1)])
2522 break;
2523 if ((j == 1) && (currVol->iqmat[*(zigzag_i+j)] == currVol->iqmat[*(zigzag_i+j-1)]))
2524 j = 0;
2525 for (i = 0; i < j + 1; i++)
2526 BitstreamPutBits(stream, 8, currVol->iqmat[*(zigzag_i+i)]);
2527 if (j < 63)
2528 BitstreamPutBits(stream, 8, 0);
2529 }
2530 else
2531 {
2532 for (j = 0; j < 64; j++)
2533 currVol->iqmat[j] = mpeg_iqmat_def[j];
2534
2535 }
2536 status = BitstreamPut1Bits(stream, currVol->loadNonIntraQuantMat); /* Non-Intra quant matrix */
2537 if (currVol->loadNonIntraQuantMat)
2538 {
2539 for (j = 63; j >= 1; j--)
2540 if (currVol->niqmat[*(zigzag_i+j)] != currVol->niqmat[*(zigzag_i+j-1)])
2541 break;
2542 if ((j == 1) && (currVol->niqmat[*(zigzag_i+j)] == currVol->niqmat[*(zigzag_i+j-1)]))
2543 j = 0;
2544 for (i = 0; i < j + 1; i++)
2545 BitstreamPutBits(stream, 8, currVol->niqmat[*(zigzag_i+i)]);
2546 if (j < 63)
2547 BitstreamPutBits(stream, 8, 0);
2548 }
2549 else
2550 {
2551 for (j = 0; j < 64; j++)
2552 currVol->niqmat[j] = mpeg_nqmat_def[j];
2553 }
2554 }
2555
2556 status = BitstreamPut1Bits(stream, 0x01); /* complexity_estimation_disable = 1 */
2557 status = BitstreamPut1Bits(stream, currVol->ResyncMarkerDisable);/* Resync_marker_disable */
2558 status = BitstreamPut1Bits(stream, currVol->dataPartitioning);/* Data partitioned */
2559
2560 if (currVol->dataPartitioning)
2561 status = BitstreamPut1Bits(stream, currVol->useReverseVLC); /* Reversible_vlc */
2562
2563
2564 if (currVol->scalability) /* Scalability*/
2565 {
2566
2567 status = BitstreamPut1Bits(stream, currVol->scalability);/* Scalability = 1 */
2568 status = BitstreamPut1Bits(stream, currVol->scalType);/* hierarchy _type ... Spatial= 0 and Temporal = 1 */
2569 status = BitstreamPutBits(stream, 4, currVol->refVolID);/* ref_layer_id */
2570 status = BitstreamPut1Bits(stream, currVol->refSampDir);/* ref_layer_sampling_direc*/
2571 status = BitstreamPutBits(stream, 5, currVol->horSamp_n);/*hor_sampling_factor_n*/
2572 status = BitstreamPutBits(stream, 5, currVol->horSamp_m);/*hor_sampling_factor_m*/
2573 status = BitstreamPutBits(stream, 5, currVol->verSamp_n);/*vert_sampling_factor_n*/
2574 status = BitstreamPutBits(stream, 5, currVol->verSamp_m);/*vert_sampling_factor_m*/
2575 status = BitstreamPut1Bits(stream, currVol->enhancementType);/* enhancement_type*/
2576 }
2577 else /* No Scalability */
2578 status = BitstreamPut1Bits(stream, currVol->scalability);/* Scalability = 0 */
2579
2580 /*temp = */
2581 BitstreamMpeg4ByteAlignStuffing(stream); /* Byte align Headers for VOP */
2582 }
2583 }
2584
2585 return status;
2586 }
2587
2588 /* ======================================================================== */
2589 /* Function : VOS_End() */
2590 /* Date : 08/22/2000 */
2591 /* Purpose : Visual Object Sequence End */
2592 /* In/out : */
2593 /* Return : PV_TRUE if successed, PV_FALSE if failed. */
2594 /* Modified : */
2595 /* */
2596 /* ======================================================================== */
2597
VOS_End(VideoEncControls * encoderControl)2598 PV_STATUS VOS_End(VideoEncControls *encoderControl)
2599 {
2600 PV_STATUS status = PV_SUCCESS;
2601 VideoEncData *video = (VideoEncData *)encoderControl->videoEncoderData;
2602 Vol *currVol = video->vol[video->currLayer];
2603 BitstreamEncVideo *stream = currVol->stream;
2604
2605
2606 status = BitstreamPutBits(stream, SESSION_END_CODE, 32);
2607
2608 return status;
2609 }
2610
2611 /* ======================================================================== */
2612 /* Function : DetermineCodingLayer */
2613 /* Date : 06/02/2001 */
2614 /* Purpose : Find layer to code based on current mod time, assuming that
2615 it's time to encode enhanced layer. */
2616 /* In/out : */
2617 /* Return : Number of layer to code. */
2618 /* Modified : */
2619 /* */
2620 /* ======================================================================== */
2621
DetermineCodingLayer(VideoEncData * video,Int * nLayer,ULong modTime)2622 Int DetermineCodingLayer(VideoEncData *video, Int *nLayer, ULong modTime)
2623 {
2624 Vol **vol = video->vol;
2625 VideoEncParams *encParams = video->encParams;
2626 Int numLayers = encParams->nLayers;
2627 UInt modTimeRef = video->modTimeRef;
2628 float *LayerFrameRate = encParams->LayerFrameRate;
2629 UInt frameNum[4], frameTick;
2630 ULong frameModTime, nextFrmModTime;
2631 #ifdef REDUCE_FRAME_VARIANCE /* To limit how close 2 frames can be */
2632 float frameInterval;
2633 #endif
2634 float srcFrameInterval;
2635 Int frameInc;
2636 Int i, extra_skip;
2637 Int encodeVop = 0;
2638
2639 i = numLayers - 1;
2640
2641 if (modTime - video->nextModTime > ((ULong)(-1)) >> 1) /* next time wrapped around */
2642 return 0; /* not time to code it yet */
2643
2644 video->relLayerCodeTime[i] -= 1000;
2645 video->nextEncIVop--; /* number of Vops in highest layer resolution. */
2646 video->numVopsInGOP++;
2647
2648 /* from this point frameModTime and nextFrmModTime are internal */
2649
2650 frameNum[i] = (UInt)((modTime - modTimeRef) * LayerFrameRate[i] + 500) / 1000;
2651 if (video->volInitialize[i])
2652 {
2653 video->prevFrameNum[i] = frameNum[i] - 1;
2654 }
2655 else if (frameNum[i] <= video->prevFrameNum[i])
2656 {
2657 return 0; /* do not encode this frame */
2658 }
2659
2660 /**** this part computes expected next frame *******/
2661 frameModTime = (ULong)(((frameNum[i] * 1000) / LayerFrameRate[i]) + modTimeRef + 0.5); /* rec. time */
2662 nextFrmModTime = (ULong)((((frameNum[i] + 1) * 1000) / LayerFrameRate[i]) + modTimeRef + 0.5); /* rec. time */
2663
2664 srcFrameInterval = 1000 / video->FrameRate;
2665
2666 video->nextModTime = nextFrmModTime - (ULong)(srcFrameInterval / 2.) - 1; /* between current and next frame */
2667
2668 #ifdef REDUCE_FRAME_VARIANCE /* To limit how close 2 frames can be */
2669 frameInterval = 1000 / LayerFrameRate[i]; /* next rec. time */
2670 delta = (Int)(frameInterval / 4); /* empirical number */
2671 if (video->nextModTime - modTime < (ULong)delta) /* need to move nextModTime further. */
2672 {
2673 video->nextModTime += ((delta - video->nextModTime + modTime)); /* empirical formula */
2674 }
2675 #endif
2676 /****************************************************/
2677
2678 /* map frame no.to tick from modTimeRef */
2679 /*frameTick = (frameNum[i]*vol[i]->timeIncrementResolution) ;
2680 frameTick = (UInt)((frameTick + (encParams->LayerFrameRate[i]/2))/encParams->LayerFrameRate[i]);*/
2681 /* 11/16/01, change frameTick to be the closest tick from the actual modTime */
2682 /* 12/12/02, add (double) to prevent large number wrap-around */
2683 frameTick = (Int)(((double)(modTime - modTimeRef) * vol[i]->timeIncrementResolution + 500) / 1000);
2684
2685 /* find timeIncrement to be put in the bitstream */
2686 /* refTick is second boundary reference. */
2687 vol[i]->timeIncrement = frameTick - video->refTick[i];
2688
2689
2690 vol[i]->moduloTimeBase = 0;
2691 while (vol[i]->timeIncrement >= vol[i]->timeIncrementResolution)
2692 {
2693 vol[i]->timeIncrement -= vol[i]->timeIncrementResolution;
2694 vol[i]->moduloTimeBase++;
2695 /* do not update refTick and modTimeRef yet, do it after encoding!! */
2696 }
2697
2698 if (video->relLayerCodeTime[i] <= 0) /* no skipping */
2699 {
2700 encodeVop = 1;
2701 video->currLayer = *nLayer = i;
2702 video->relLayerCodeTime[i] += 1000;
2703
2704 /* takes care of more dropped frame than expected */
2705 extra_skip = -1;
2706 frameInc = (frameNum[i] - video->prevFrameNum[i]);
2707 extra_skip += frameInc;
2708
2709 if (extra_skip > 0)
2710 { /* update rc->Nr, rc->B, (rc->Rr)*/
2711 video->nextEncIVop -= extra_skip;
2712 video->numVopsInGOP += extra_skip;
2713 if (encParams->RC_Type != CONSTANT_Q)
2714 {
2715 RC_UpdateBuffer(video, i, extra_skip);
2716 }
2717 }
2718
2719 }
2720 /* update frame no. */
2721 video->prevFrameNum[i] = frameNum[i];
2722
2723 /* go through all lower layer */
2724 for (i = (numLayers - 2); i >= 0; i--)
2725 {
2726
2727 video->relLayerCodeTime[i] -= 1000;
2728
2729 /* find timeIncrement to be put in the bitstream */
2730 vol[i]->timeIncrement = frameTick - video->refTick[i];
2731
2732 if (video->relLayerCodeTime[i] <= 0) /* time to encode base */
2733 {
2734 /* 12/27/00 */
2735 encodeVop = 1;
2736 video->currLayer = *nLayer = i;
2737 video->relLayerCodeTime[i] +=
2738 (Int)((1000.0 * encParams->LayerFrameRate[numLayers-1]) / encParams->LayerFrameRate[i]);
2739
2740 vol[i]->moduloTimeBase = 0;
2741 while (vol[i]->timeIncrement >= vol[i]->timeIncrementResolution)
2742 {
2743 vol[i]->timeIncrement -= vol[i]->timeIncrementResolution;
2744 vol[i]->moduloTimeBase++;
2745 /* do not update refTick and modTimeRef yet, do it after encoding!! */
2746 }
2747
2748 /* takes care of more dropped frame than expected */
2749 frameNum[i] = (UInt)((frameModTime - modTimeRef) * encParams->LayerFrameRate[i] + 500) / 1000;
2750 if (video->volInitialize[i])
2751 video->prevFrameNum[i] = frameNum[i] - 1;
2752
2753 extra_skip = -1;
2754 frameInc = (frameNum[i] - video->prevFrameNum[i]);
2755 extra_skip += frameInc;
2756
2757 if (extra_skip > 0)
2758 { /* update rc->Nr, rc->B, (rc->Rr)*/
2759 if (encParams->RC_Type != CONSTANT_Q)
2760 {
2761 RC_UpdateBuffer(video, i, extra_skip);
2762 }
2763 }
2764 /* update frame no. */
2765 video->prevFrameNum[i] = frameNum[i];
2766 }
2767 }
2768
2769 #ifdef _PRINT_STAT
2770 if (encodeVop)
2771 printf(" TI: %d ", vol[*nLayer]->timeIncrement);
2772 #endif
2773
2774 return encodeVop;
2775 }
2776
2777 /* ======================================================================== */
2778 /* Function : DetermineVopType */
2779 /* Date : 06/02/2001 */
2780 /* Purpose : The name says it all. */
2781 /* In/out : */
2782 /* Return : void . */
2783 /* Modified : */
2784 /* */
2785 /* ======================================================================== */
2786
DetermineVopType(VideoEncData * video,Int currLayer)2787 void DetermineVopType(VideoEncData *video, Int currLayer)
2788 {
2789 VideoEncParams *encParams = video->encParams;
2790 // Vol *currVol = video->vol[currLayer];
2791
2792 if (encParams->IntraPeriod == 0) /* I-VOPs only */
2793 {
2794 if (video->currLayer > 0)
2795 video->currVop->predictionType = P_VOP;
2796 else
2797 {
2798 video->currVop->predictionType = I_VOP;
2799 if (video->numVopsInGOP >= 132)
2800 video->numVopsInGOP = 0;
2801 }
2802 }
2803 else if (encParams->IntraPeriod == -1) /* IPPPPP... */
2804 {
2805
2806 /* maintain frame type if previous frame is pre-skipped, 06/02/2001 */
2807 if (encParams->RC_Type == CONSTANT_Q || video->rc[currLayer]->skip_next_frame != -1)
2808 video->currVop->predictionType = P_VOP;
2809
2810 if (video->currLayer == 0)
2811 {
2812 if (/*video->numVopsInGOP>=132 || */video->volInitialize[currLayer])
2813 {
2814 video->currVop->predictionType = I_VOP;
2815 video->numVopsInGOP = 0; /* force INTRA update every 132 base frames*/
2816 video->nextEncIVop = 1;
2817 }
2818 else if (video->nextEncIVop == 0 || video->currVop->predictionType == I_VOP)
2819 {
2820 video->numVopsInGOP = 0;
2821 video->nextEncIVop = 1;
2822 }
2823 }
2824 }
2825 else /* IntraPeriod>0 : IPPPPPIPPPPPI... */
2826 {
2827
2828 /* maintain frame type if previous frame is pre-skipped, 06/02/2001 */
2829 if (encParams->RC_Type == CONSTANT_Q || video->rc[currLayer]->skip_next_frame != -1)
2830 video->currVop->predictionType = P_VOP;
2831
2832 if (currLayer == 0)
2833 {
2834 if (video->nextEncIVop <= 0 || video->currVop->predictionType == I_VOP)
2835 {
2836 video->nextEncIVop = encParams->IntraPeriod;
2837 video->currVop->predictionType = I_VOP;
2838 video->numVopsInGOP = 0;
2839 }
2840 }
2841 }
2842
2843 return ;
2844 }
2845
2846 /* ======================================================================== */
2847 /* Function : UpdateSkipNextFrame */
2848 /* Date : 06/02/2001 */
2849 /* Purpose : From rate control frame skipping decision, update timing
2850 related parameters. */
2851 /* In/out : */
2852 /* Return : Current coded layer. */
2853 /* Modified : */
2854 /* */
2855 /* ======================================================================== */
2856
UpdateSkipNextFrame(VideoEncData * video,ULong * modTime,Int * size,PV_STATUS status)2857 Int UpdateSkipNextFrame(VideoEncData *video, ULong *modTime, Int *size, PV_STATUS status)
2858 {
2859 Int currLayer = video->currLayer;
2860 Int nLayer = currLayer;
2861 VideoEncParams *encParams = video->encParams;
2862 Int numLayers = encParams->nLayers;
2863 Vol *currVol = video->vol[currLayer];
2864 Vol **vol = video->vol;
2865 Int num_skip, extra_skip;
2866 Int i;
2867 UInt newRefTick, deltaModTime;
2868 UInt temp;
2869
2870 if (encParams->RC_Type != CONSTANT_Q)
2871 {
2872 if (video->volInitialize[0] && currLayer == 0) /* always encode the first frame */
2873 {
2874 RC_ResetSkipNextFrame(video, currLayer);
2875 //return currLayer; 09/15/05
2876 }
2877 else
2878 {
2879 if (RC_GetSkipNextFrame(video, currLayer) < 0 || status == PV_END_OF_BUF) /* Skip Current Frame */
2880 {
2881
2882 #ifdef _PRINT_STAT
2883 printf("Skip current frame");
2884 #endif
2885 currVol->moduloTimeBase = currVol->prevModuloTimeBase;
2886
2887 /*********************/
2888 /* prepare to return */
2889 /*********************/
2890 *size = 0; /* Set Bitstream buffer to zero */
2891
2892 /* Determine nLayer and modTime for next encode */
2893
2894 *modTime = video->nextModTime;
2895 nLayer = -1;
2896
2897 return nLayer; /* return immediately without updating RefTick & modTimeRef */
2898 /* If I-VOP was attempted, then ensure next base is I-VOP */
2899 /*if((encParams->IntraPeriod>0) && (video->currVop->predictionType == I_VOP))
2900 video->nextEncIVop = 0; commented out by 06/05/01 */
2901
2902 }
2903 else if ((num_skip = RC_GetSkipNextFrame(video, currLayer)) > 0)
2904 {
2905
2906 #ifdef _PRINT_STAT
2907 printf("Skip next %d frames", num_skip);
2908 #endif
2909 /* to keep the Nr of enh layer the same */
2910 /* adjust relLayerCodeTime only, do not adjust layerCodeTime[numLayers-1] */
2911 extra_skip = 0;
2912 for (i = 0; i < currLayer; i++)
2913 {
2914 if (video->relLayerCodeTime[i] <= 1000)
2915 {
2916 extra_skip = 1;
2917 break;
2918 }
2919 }
2920
2921 for (i = currLayer; i < numLayers; i++)
2922 {
2923 video->relLayerCodeTime[i] += (num_skip + extra_skip) *
2924 ((Int)((1000.0 * encParams->LayerFrameRate[numLayers-1]) / encParams->LayerFrameRate[i]));
2925 }
2926 }
2927 }/* first frame */
2928 }
2929 /***** current frame is encoded, now update refTick ******/
2930
2931 video->refTick[currLayer] += vol[currLayer]->prevModuloTimeBase * vol[currLayer]->timeIncrementResolution;
2932
2933 /* Reset layerCodeTime every I-VOP to prevent overflow */
2934 if (currLayer == 0)
2935 {
2936 /* 12/12/02, fix for weird targer frame rate of 9.99 fps or 3.33 fps */
2937 if (((encParams->IntraPeriod != 0) /*&& (video->currVop->predictionType==I_VOP)*/) ||
2938 ((encParams->IntraPeriod == 0) && (video->numVopsInGOP == 0)))
2939 {
2940 newRefTick = video->refTick[0];
2941
2942 for (i = 1; i < numLayers; i++)
2943 {
2944 if (video->refTick[i] < newRefTick)
2945 newRefTick = video->refTick[i];
2946 }
2947
2948 /* check to make sure that the update is integer multiple of frame number */
2949 /* how many msec elapsed from last modTimeRef */
2950 deltaModTime = (newRefTick / vol[0]->timeIncrementResolution) * 1000;
2951
2952 for (i = numLayers - 1; i >= 0; i--)
2953 {
2954 temp = (UInt)(deltaModTime * encParams->LayerFrameRate[i]); /* 12/12/02 */
2955 if (temp % 1000)
2956 newRefTick = 0;
2957
2958 }
2959 if (newRefTick > 0)
2960 {
2961 video->modTimeRef += deltaModTime;
2962 for (i = numLayers - 1; i >= 0; i--)
2963 {
2964 video->prevFrameNum[i] -= (UInt)(deltaModTime * encParams->LayerFrameRate[i]) / 1000;
2965 video->refTick[i] -= newRefTick;
2966 }
2967 }
2968 }
2969 }
2970
2971 *modTime = video->nextModTime;
2972
2973 return nLayer;
2974 }
2975
2976
2977 #ifndef ORIGINAL_VERSION
2978
2979 /* ======================================================================== */
2980 /* Function : SetProfile_BufferSize */
2981 /* Date : 04/08/2002 */
2982 /* Purpose : Set profile and video buffer size, copied from Jim's code */
2983 /* in PVInitVideoEncoder(.), since we have different places */
2984 /* to reset profile and video buffer size */
2985 /* In/out : */
2986 /* Return : */
2987 /* Modified : */
2988 /* */
2989 /* ======================================================================== */
2990
SetProfile_BufferSize(VideoEncData * video,float delay,Int bInitialized)2991 Bool SetProfile_BufferSize(VideoEncData *video, float delay, Int bInitialized)
2992 {
2993 Int i, j, start, end;
2994 // Int BaseMBsPerSec = 0, EnhMBsPerSec = 0;
2995 Int nTotalMB = 0;
2996 Int idx, temp_w, temp_h, max = 0, max_width, max_height;
2997
2998 Int nLayers = video->encParams->nLayers; /* Number of Layers to be encoded */
2999
3000 Int total_bitrate = 0, base_bitrate;
3001 Int total_packet_size = 0, base_packet_size;
3002 Int total_MBsPerSec = 0, base_MBsPerSec;
3003 Int total_VBV_size = 0, base_VBV_size, enhance_VBV_size = 0;
3004 float total_framerate, base_framerate;
3005 float upper_bound_ratio;
3006 Int bFound = 0;
3007 Int k = 0, width16, height16, index;
3008 Int lowest_level;
3009
3010 #define MIN_BUFF 16000 /* 16k minimum buffer size */
3011 #define BUFF_CONST 2.0 /* 2000ms */
3012 #define UPPER_BOUND_RATIO 8.54 /* upper_bound = 1.4*(1.1+bound/10)*bitrate/framerate */
3013
3014 #define QCIF_WIDTH 176
3015 #define QCIF_HEIGHT 144
3016
3017 index = video->encParams->profile_table_index;
3018
3019 /* Calculate "nTotalMB" */
3020 /* Find the maximum width*height for memory allocation of the VOPs */
3021 for (idx = 0; idx < nLayers; idx++)
3022 {
3023 temp_w = video->encParams->LayerWidth[idx];
3024 temp_h = video->encParams->LayerHeight[idx];
3025
3026 if ((temp_w*temp_h) > max)
3027 {
3028 max = temp_w * temp_h;
3029 max_width = temp_w;
3030 max_height = temp_h;
3031 nTotalMB = ((max_width + 15) >> 4) * ((max_height + 15) >> 4);
3032 }
3033 }
3034 upper_bound_ratio = (video->encParams->RC_Type == CBR_LOWDELAY ? (float)5.0 : (float)UPPER_BOUND_RATIO);
3035
3036
3037 /* Get the basic information: bitrate, packet_size, MBs/s and VBV_size */
3038 base_bitrate = video->encParams->LayerBitRate[0];
3039 if (video->encParams->LayerMaxBitRate[0] != 0) /* video->encParams->LayerMaxBitRate[0] == 0 means it has not been set */
3040 {
3041 base_bitrate = PV_MAX(base_bitrate, video->encParams->LayerMaxBitRate[0]);
3042 }
3043 else /* if the max is not set, set it to the specified profile/level */
3044 {
3045 video->encParams->LayerMaxBitRate[0] = profile_level_max_bitrate[index];
3046 }
3047
3048 base_framerate = video->encParams->LayerFrameRate[0];
3049 if (video->encParams->LayerMaxFrameRate[0] != 0)
3050 {
3051 base_framerate = PV_MAX(base_framerate, video->encParams->LayerMaxFrameRate[0]);
3052 }
3053 else /* if the max is not set, set it to the specified profile/level */
3054 {
3055 video->encParams->LayerMaxFrameRate[0] = (float)profile_level_max_mbsPerSec[index] / nTotalMB;
3056 }
3057
3058 base_packet_size = video->encParams->ResyncPacketsize;
3059 base_MBsPerSec = (Int)(base_framerate * nTotalMB);
3060 base_VBV_size = PV_MAX((Int)(base_bitrate * delay),
3061 (Int)(upper_bound_ratio * base_bitrate / base_framerate));
3062 base_VBV_size = PV_MAX(base_VBV_size, MIN_BUFF);
3063
3064 /* if the buffer is larger than maximum buffer size, we'll clip it */
3065 if (base_VBV_size > profile_level_max_VBV_size[5])
3066 base_VBV_size = profile_level_max_VBV_size[5];
3067
3068
3069 /* Check if the buffer exceeds the maximum buffer size given the maximum profile and level */
3070 if (nLayers == 1 && base_VBV_size > profile_level_max_VBV_size[index])
3071 return FALSE;
3072
3073
3074 if (nLayers == 2)
3075 {
3076 total_bitrate = video->encParams->LayerBitRate[1];
3077 if (video->encParams->LayerMaxBitRate[1] != 0)
3078 {
3079 total_bitrate = PV_MIN(total_bitrate, video->encParams->LayerMaxBitRate[1]);
3080 }
3081 else /* if the max is not set, set it to the specified profile/level */
3082 {
3083 video->encParams->LayerMaxBitRate[1] = scalable_profile_level_max_bitrate[index];
3084 }
3085
3086 total_framerate = video->encParams->LayerFrameRate[1];
3087 if (video->encParams->LayerMaxFrameRate[1] != 0)
3088 {
3089 total_framerate = PV_MIN(total_framerate, video->encParams->LayerMaxFrameRate[1]);
3090 }
3091 else /* if the max is not set, set it to the specified profile/level */
3092 {
3093 video->encParams->LayerMaxFrameRate[1] = (float)scalable_profile_level_max_mbsPerSec[index] / nTotalMB;
3094 }
3095
3096 total_packet_size = video->encParams->ResyncPacketsize;
3097 total_MBsPerSec = (Int)(total_framerate * nTotalMB);
3098
3099 enhance_VBV_size = PV_MAX((Int)((total_bitrate - base_bitrate) * delay),
3100 (Int)(upper_bound_ratio * (total_bitrate - base_bitrate) / (total_framerate - base_framerate)));
3101 enhance_VBV_size = PV_MAX(enhance_VBV_size, MIN_BUFF);
3102
3103 total_VBV_size = base_VBV_size + enhance_VBV_size;
3104
3105 /* if the buffer is larger than maximum buffer size, we'll clip it */
3106 if (total_VBV_size > scalable_profile_level_max_VBV_size[6])
3107 {
3108 total_VBV_size = scalable_profile_level_max_VBV_size[6];
3109 enhance_VBV_size = total_VBV_size - base_VBV_size;
3110 }
3111
3112 /* Check if the buffer exceeds the maximum buffer size given the maximum profile and level */
3113 if (total_VBV_size > scalable_profile_level_max_VBV_size[index])
3114 return FALSE;
3115 }
3116
3117
3118 if (!bInitialized) /* Has been initialized --> profile @ level has been figured out! */
3119 {
3120 video->encParams->BufferSize[0] = base_VBV_size;
3121 if (nLayers > 1)
3122 video->encParams->BufferSize[1] = enhance_VBV_size;
3123
3124 return PV_TRUE;
3125 }
3126
3127
3128 /* Profile @ level determination */
3129 if (nLayers == 1)
3130 {
3131 /* BASE ONLY : Simple Profile(SP) Or Core Profile(CP) */
3132 if (base_bitrate > profile_level_max_bitrate[index] ||
3133 base_packet_size > profile_level_max_packet_size[index] ||
3134 base_MBsPerSec > profile_level_max_mbsPerSec[index] ||
3135 base_VBV_size > profile_level_max_VBV_size[index])
3136
3137 return PV_FALSE; /* Beyond the bound of Core Profile @ Level2 */
3138
3139 /* For H263/Short header, determine k*16384 */
3140 width16 = ((video->encParams->LayerWidth[0] + 15) >> 4) << 4;
3141 height16 = ((video->encParams->LayerHeight[0] + 15) >> 4) << 4;
3142 if (video->encParams->H263_Enabled)
3143 {
3144 k = 4;
3145 if (width16 == 2*QCIF_WIDTH && height16 == 2*QCIF_HEIGHT) /* CIF */
3146 k = 16;
3147
3148 else if (width16 == 4*QCIF_WIDTH && height16 == 4*QCIF_HEIGHT) /* 4CIF */
3149 k = 32;
3150
3151 else if (width16 == 8*QCIF_WIDTH && height16 == 8*QCIF_HEIGHT) /* 16CIF */
3152 k = 64;
3153
3154 video->encParams->maxFrameSize = k * 16384;
3155
3156 /* Make sure the buffer size is limited to the top profile and level: the Core profile and level 2 */
3157 if (base_VBV_size > (Int)(k*16384 + 4*(float)profile_level_max_bitrate[5]*1001.0 / 30000.0))
3158 base_VBV_size = (Int)(k * 16384 + 4 * (float)profile_level_max_bitrate[5] * 1001.0 / 30000.0);
3159
3160 if (base_VBV_size > (Int)(k*16384 + 4*(float)profile_level_max_bitrate[index]*1001.0 / 30000.0))
3161 return PV_FALSE;
3162 }
3163
3164 /* Search the appropriate profile@level index */
3165 if (!video->encParams->H263_Enabled &&
3166 (video->encParams->IntraDCVlcThr != 0 || video->encParams->SearchRange > 16))
3167 {
3168 lowest_level = 1; /* cannot allow SPL0 */
3169 }
3170 else
3171 {
3172 lowest_level = 0; /* SPL0 */
3173 }
3174
3175 for (i = lowest_level; i <= index; i++)
3176 {
3177 if (i != 4 && /* skip Core Profile@Level1 because the parameters in it are smaller than those in Simple Profile@Level3 */
3178 base_bitrate <= profile_level_max_bitrate[i] &&
3179 base_packet_size <= profile_level_max_packet_size[i] &&
3180 base_MBsPerSec <= profile_level_max_mbsPerSec[i] &&
3181 base_VBV_size <= (video->encParams->H263_Enabled ? (Int)(k*16384 + 4*(float)profile_level_max_bitrate[i]*1001.0 / 30000.0) :
3182 profile_level_max_VBV_size[i]))
3183 break;
3184 }
3185 if (i > index) return PV_FALSE; /* Nothing found!! */
3186
3187 /* Found out the actual profile @ level : index "i" */
3188 if (i == 0)
3189 {
3190 /* For Simple Profile @ Level 0, we need to do one more check: image size <= QCIF */
3191 if (width16 > QCIF_WIDTH || height16 > QCIF_HEIGHT)
3192 i = 1; /* image size > QCIF, then set SP level1 */
3193 }
3194
3195 video->encParams->ProfileLevel[0] = profile_level_code[i];
3196 video->encParams->BufferSize[0] = base_VBV_size;
3197
3198 if (video->encParams->LayerMaxBitRate[0] == 0)
3199 video->encParams->LayerMaxBitRate[0] = profile_level_max_bitrate[i];
3200
3201 if (video->encParams->LayerMaxFrameRate[0] == 0)
3202 video->encParams->LayerMaxFrameRate[0] = PV_MIN(30, (float)profile_level_max_mbsPerSec[i] / nTotalMB);
3203
3204 /* For H263/Short header, one special constraint for VBV buffer size */
3205 if (video->encParams->H263_Enabled)
3206 video->encParams->BufferSize[0] = (Int)(k * 16384 + 4 * (float)profile_level_max_bitrate[i] * 1001.0 / 30000.0);
3207
3208 }
3209 else
3210 {
3211 /* SCALABALE MODE: Simple Scalable Profile(SSP) Or Core Scalable Profile(CSP) */
3212
3213 if (total_bitrate > scalable_profile_level_max_bitrate[index] ||
3214 total_packet_size > scalable_profile_level_max_packet_size[index] ||
3215 total_MBsPerSec > scalable_profile_level_max_mbsPerSec[index] ||
3216 total_VBV_size > scalable_profile_level_max_VBV_size[index])
3217
3218 return PV_FALSE; /* Beyond given profile and level */
3219
3220 /* One-time check: Simple Scalable Profile or Core Scalable Profile */
3221 if (total_bitrate <= scalable_profile_level_max_bitrate[2] &&
3222 total_packet_size <= scalable_profile_level_max_packet_size[2] &&
3223 total_MBsPerSec <= scalable_profile_level_max_mbsPerSec[2] &&
3224 total_VBV_size <= scalable_profile_level_max_VBV_size[2])
3225
3226 {
3227 start = 0;
3228 end = index;
3229 }
3230
3231 else
3232 {
3233 start = 4;
3234 end = index;
3235 }
3236
3237
3238 /* Search the scalable profile */
3239 for (i = start; i <= end; i++)
3240 {
3241 if (total_bitrate <= scalable_profile_level_max_bitrate[i] &&
3242 total_packet_size <= scalable_profile_level_max_packet_size[i] &&
3243 total_MBsPerSec <= scalable_profile_level_max_mbsPerSec[i] &&
3244 total_VBV_size <= scalable_profile_level_max_VBV_size[i])
3245
3246 break;
3247 }
3248 if (i > end) return PV_FALSE;
3249
3250 /* Search the base profile */
3251 if (i == 0)
3252 {
3253 j = 0;
3254 bFound = 1;
3255 }
3256 else bFound = 0;
3257
3258 for (j = start; !bFound && j <= i; j++)
3259 {
3260 if (base_bitrate <= profile_level_max_bitrate[j] &&
3261 base_packet_size <= profile_level_max_packet_size[j] &&
3262 base_MBsPerSec <= profile_level_max_mbsPerSec[j] &&
3263 base_VBV_size <= profile_level_max_VBV_size[j])
3264
3265 {
3266 bFound = 1;
3267 break;
3268 }
3269 }
3270
3271 if (!bFound) // && start == 4)
3272 return PV_FALSE; /* mis-match in the profiles between base layer and enhancement layer */
3273
3274 /* j for base layer, i for enhancement layer */
3275 video->encParams->ProfileLevel[0] = profile_level_code[j];
3276 video->encParams->ProfileLevel[1] = scalable_profile_level_code[i];
3277 video->encParams->BufferSize[0] = base_VBV_size;
3278 video->encParams->BufferSize[1] = enhance_VBV_size;
3279
3280 if (video->encParams->LayerMaxBitRate[0] == 0)
3281 video->encParams->LayerMaxBitRate[0] = profile_level_max_bitrate[j];
3282
3283 if (video->encParams->LayerMaxBitRate[1] == 0)
3284 video->encParams->LayerMaxBitRate[1] = scalable_profile_level_max_bitrate[i];
3285
3286 if (video->encParams->LayerMaxFrameRate[0] == 0)
3287 video->encParams->LayerMaxFrameRate[0] = PV_MIN(30, (float)profile_level_max_mbsPerSec[j] / nTotalMB);
3288
3289 if (video->encParams->LayerMaxFrameRate[1] == 0)
3290 video->encParams->LayerMaxFrameRate[1] = PV_MIN(30, (float)scalable_profile_level_max_mbsPerSec[i] / nTotalMB);
3291
3292
3293 } /* end of: if(nLayers == 1) */
3294
3295
3296 if (!video->encParams->H263_Enabled && (video->encParams->ProfileLevel[0] == 0x08)) /* SPL0 restriction*/
3297 {
3298 /* PV only allow frame-based rate control, no QP change from one MB to another
3299 if(video->encParams->ACDCPrediction == TRUE && MB-based rate control)
3300 return PV_FALSE */
3301 }
3302
3303 return PV_TRUE;
3304 }
3305
3306 #endif /* #ifndef ORIGINAL_VERSION */
3307