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