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