1 /********************************************************************
3 * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE. *
4 * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
5 * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
6 * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
8 * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2007 *
9 * by the Xiph.Org Foundation http://www.xiph.org/ *
11 ********************************************************************
16 ********************************************************************/
24 #include "toplevel_lookup.h"
25 #include "../internal.h"
27 #include "codec_internal.h"
29 #define A_TABLE_SIZE 29
30 #define DF_CANDIDATE_WINDOW 5
33 * th_quant_info for VP3
36 /*The default quantization parameters used by VP3.1.*/
37 static const int OC_VP31_RANGE_SIZES
[1]={63};
38 static const th_quant_base OC_VP31_BASES_INTRA_Y
[2]={
40 16, 11, 10, 16, 24, 40, 51, 61,
41 12, 12, 14, 19, 26, 58, 60, 55,
42 14, 13, 16, 24, 40, 57, 69, 56,
43 14, 17, 22, 29, 51, 87, 80, 62,
44 18, 22, 37, 58, 68, 109,103, 77,
45 24, 35, 55, 64, 81, 104,113, 92,
46 49, 64, 78, 87,103, 121,120,101,
47 72, 92, 95, 98,112, 100,103, 99
50 16, 11, 10, 16, 24, 40, 51, 61,
51 12, 12, 14, 19, 26, 58, 60, 55,
52 14, 13, 16, 24, 40, 57, 69, 56,
53 14, 17, 22, 29, 51, 87, 80, 62,
54 18, 22, 37, 58, 68, 109,103, 77,
55 24, 35, 55, 64, 81, 104,113, 92,
56 49, 64, 78, 87,103, 121,120,101,
57 72, 92, 95, 98,112, 100,103, 99
60 static const th_quant_base OC_VP31_BASES_INTRA_C
[2]={
62 17, 18, 24, 47, 99, 99, 99, 99,
63 18, 21, 26, 66, 99, 99, 99, 99,
64 24, 26, 56, 99, 99, 99, 99, 99,
65 47, 66, 99, 99, 99, 99, 99, 99,
66 99, 99, 99, 99, 99, 99, 99, 99,
67 99, 99, 99, 99, 99, 99, 99, 99,
68 99, 99, 99, 99, 99, 99, 99, 99,
69 99, 99, 99, 99, 99, 99, 99, 99
72 17, 18, 24, 47, 99, 99, 99, 99,
73 18, 21, 26, 66, 99, 99, 99, 99,
74 24, 26, 56, 99, 99, 99, 99, 99,
75 47, 66, 99, 99, 99, 99, 99, 99,
76 99, 99, 99, 99, 99, 99, 99, 99,
77 99, 99, 99, 99, 99, 99, 99, 99,
78 99, 99, 99, 99, 99, 99, 99, 99,
79 99, 99, 99, 99, 99, 99, 99, 99
82 static const th_quant_base OC_VP31_BASES_INTER
[2]={
84 16, 16, 16, 20, 24, 28, 32, 40,
85 16, 16, 20, 24, 28, 32, 40, 48,
86 16, 20, 24, 28, 32, 40, 48, 64,
87 20, 24, 28, 32, 40, 48, 64, 64,
88 24, 28, 32, 40, 48, 64, 64, 64,
89 28, 32, 40, 48, 64, 64, 64, 96,
90 32, 40, 48, 64, 64, 64, 96,128,
91 40, 48, 64, 64, 64, 96,128,128
94 16, 16, 16, 20, 24, 28, 32, 40,
95 16, 16, 20, 24, 28, 32, 40, 48,
96 16, 20, 24, 28, 32, 40, 48, 64,
97 20, 24, 28, 32, 40, 48, 64, 64,
98 24, 28, 32, 40, 48, 64, 64, 64,
99 28, 32, 40, 48, 64, 64, 64, 96,
100 32, 40, 48, 64, 64, 64, 96,128,
101 40, 48, 64, 64, 64, 96,128,128
105 const th_quant_info TH_VP31_QUANT_INFO
={
107 220,200,190,180,170,170,160,160,
108 150,150,140,140,130,130,120,120,
109 110,110,100,100, 90, 90, 90, 80,
110 80, 80, 70, 70, 70, 60, 60, 60,
111 60, 50, 50, 50, 50, 40, 40, 40,
112 40, 40, 30, 30, 30, 30, 30, 30,
113 30, 20, 20, 20, 20, 20, 20, 20,
114 20, 10, 10, 10, 10, 10, 10, 10
117 500,450,400,370,340,310,285,265,
118 245,225,210,195,185,180,170,160,
119 150,145,135,130,125,115,110,107,
120 100, 96, 93, 89, 85, 82, 75, 74,
121 70, 68, 64, 60, 57, 56, 52, 50,
122 49, 45, 44, 43, 40, 38, 37, 35,
123 33, 32, 30, 29, 28, 25, 24, 22,
124 21, 19, 18, 17, 15, 13, 12, 10
127 30,25,20,20,15,15,14,14,
128 13,13,12,12,11,11,10,10,
129 9, 9, 8, 8, 7, 7, 7, 7,
130 6, 6, 6, 6, 5, 5, 5, 5,
131 4, 4, 4, 4, 3, 3, 3, 3,
132 2, 2, 2, 2, 2, 2, 2, 2,
133 0, 0, 0, 0, 0, 0, 0, 0,
134 0, 0, 0, 0, 0, 0, 0, 0
138 {1,OC_VP31_RANGE_SIZES
,OC_VP31_BASES_INTRA_Y
},
139 {1,OC_VP31_RANGE_SIZES
,OC_VP31_BASES_INTRA_C
},
140 {1,OC_VP31_RANGE_SIZES
,OC_VP31_BASES_INTRA_C
}
143 {1,OC_VP31_RANGE_SIZES
,OC_VP31_BASES_INTER
},
144 {1,OC_VP31_RANGE_SIZES
,OC_VP31_BASES_INTER
},
145 {1,OC_VP31_RANGE_SIZES
,OC_VP31_BASES_INTER
}
151 static void EClearFragmentInfo(CP_INSTANCE
* cpi
){
152 if(cpi
->extra_fragments
)
153 _ogg_free(cpi
->extra_fragments
);
154 if(cpi
->FragmentLastQ
)
155 _ogg_free(cpi
->FragmentLastQ
);
157 _ogg_free(cpi
->FragTokens
);
158 if(cpi
->FragTokenCounts
)
159 _ogg_free(cpi
->FragTokenCounts
);
160 if(cpi
->RunHuffIndices
)
161 _ogg_free(cpi
->RunHuffIndices
);
162 if(cpi
->LastCodedErrorScore
)
163 _ogg_free(cpi
->LastCodedErrorScore
);
165 _ogg_free(cpi
->ModeList
);
167 _ogg_free(cpi
->MVList
);
169 _ogg_free( cpi
->DCT_codes
);
170 if(cpi
->DCTDataBuffer
)
171 _ogg_free( cpi
->DCTDataBuffer
);
172 if(cpi
->quantized_list
)
173 _ogg_free( cpi
->quantized_list
);
175 _ogg_free( cpi
->OriginalDC
);
176 if(cpi
->PartiallyCodedFlags
)
177 _ogg_free(cpi
->PartiallyCodedFlags
);
178 if(cpi
->PartiallyCodedMbPatterns
)
179 _ogg_free(cpi
->PartiallyCodedMbPatterns
);
180 if(cpi
->UncodedMbFlags
)
181 _ogg_free(cpi
->UncodedMbFlags
);
183 if(cpi
->BlockCodedFlags
)
184 _ogg_free(cpi
->BlockCodedFlags
);
186 cpi
->extra_fragments
= 0;
187 cpi
->FragmentLastQ
= 0;
189 cpi
->FragTokenCounts
= 0;
190 cpi
->RunHuffIndices
= 0;
191 cpi
->LastCodedErrorScore
= 0;
195 cpi
->DCTDataBuffer
= 0;
196 cpi
->quantized_list
= 0;
198 cpi
->BlockCodedFlags
= 0;
201 static void EInitFragmentInfo(CP_INSTANCE
* cpi
){
203 /* clear any existing info */
204 EClearFragmentInfo(cpi
);
206 /* Perform Fragment Allocations */
207 cpi
->extra_fragments
=
208 _ogg_malloc(cpi
->pb
.UnitFragments
*sizeof(unsigned char));
210 /* A note to people reading and wondering why malloc returns aren't
213 lines like the following that implement a general strategy of
214 'check the return of malloc; a zero pointer means we're out of
217 if(!cpi->extra_fragments) { EDeleteFragmentInfo(cpi); return FALSE; }
219 ...are not useful. It's true that many platforms follow this
220 malloc behavior, but many do not. The more modern malloc
221 strategy is only to allocate virtual pages, which are not mapped
222 until the memory on that page is touched. At *that* point, if
223 the machine is out of heap, the page fails to be mapped and a
226 That means that if we want to deal with out of memory conditions,
227 we *must* be prepared to process a SEGV. If we implement the
228 SEGV handler, there's no reason to to check malloc return; it is
232 _ogg_malloc(cpi
->pb
.UnitFragments
*
233 sizeof(*cpi
->FragmentLastQ
));
235 _ogg_malloc(cpi
->pb
.UnitFragments
*
236 sizeof(*cpi
->FragTokens
));
238 _ogg_malloc(cpi
->pb
.UnitFragments
*
239 sizeof(*cpi
->OriginalDC
));
240 cpi
->FragTokenCounts
=
241 _ogg_malloc(cpi
->pb
.UnitFragments
*
242 sizeof(*cpi
->FragTokenCounts
));
243 cpi
->RunHuffIndices
=
244 _ogg_malloc(cpi
->pb
.UnitFragments
*
245 sizeof(*cpi
->RunHuffIndices
));
246 cpi
->LastCodedErrorScore
=
247 _ogg_malloc(cpi
->pb
.UnitFragments
*
248 sizeof(*cpi
->LastCodedErrorScore
));
249 cpi
->BlockCodedFlags
=
250 _ogg_malloc(cpi
->pb
.UnitFragments
*
251 sizeof(*cpi
->BlockCodedFlags
));
253 _ogg_malloc(cpi
->pb
.UnitFragments
*
254 sizeof(*cpi
->ModeList
));
256 _ogg_malloc(cpi
->pb
.UnitFragments
*
257 sizeof(*cpi
->MVList
));
260 sizeof(*cpi
->DCT_codes
));
263 sizeof(*cpi
->DCTDataBuffer
));
264 cpi
->quantized_list
=
266 sizeof(*cpi
->quantized_list
));
267 cpi
->PartiallyCodedFlags
=
268 _ogg_malloc(cpi
->pb
.MacroBlocks
*
269 sizeof(*cpi
->PartiallyCodedFlags
));
270 cpi
->PartiallyCodedMbPatterns
=
271 _ogg_malloc(cpi
->pb
.MacroBlocks
*
272 sizeof(*cpi
->PartiallyCodedMbPatterns
));
273 cpi
->UncodedMbFlags
=
274 _ogg_malloc(cpi
->pb
.MacroBlocks
*
275 sizeof(*cpi
->UncodedMbFlags
));
279 static void EClearFrameInfo(CP_INSTANCE
* cpi
) {
280 if(cpi
->ConvDestBuffer
)
281 _ogg_free(cpi
->ConvDestBuffer
);
282 cpi
->ConvDestBuffer
= 0;
285 _ogg_free(cpi
->yuv0ptr
);
289 _ogg_free(cpi
->yuv1ptr
);
292 if(cpi
->OptimisedTokenListEb
)
293 _ogg_free(cpi
->OptimisedTokenListEb
);
294 cpi
->OptimisedTokenListEb
= 0;
296 if(cpi
->OptimisedTokenList
)
297 _ogg_free(cpi
->OptimisedTokenList
);
298 cpi
->OptimisedTokenList
= 0;
300 if(cpi
->OptimisedTokenListHi
)
301 _ogg_free(cpi
->OptimisedTokenListHi
);
302 cpi
->OptimisedTokenListHi
= 0;
304 if(cpi
->OptimisedTokenListPl
)
305 _ogg_free(cpi
->OptimisedTokenListPl
);
306 cpi
->OptimisedTokenListPl
= 0;
310 static void EInitFrameInfo(CP_INSTANCE
* cpi
){
311 int FrameSize
= cpi
->pb
.ReconYPlaneSize
+ 2 * cpi
->pb
.ReconUVPlaneSize
;
313 /* clear any existing info */
314 EClearFrameInfo(cpi
);
316 /* allocate frames */
317 cpi
->ConvDestBuffer
=
318 _ogg_malloc(FrameSize
*
319 sizeof(*cpi
->ConvDestBuffer
));
321 _ogg_malloc(FrameSize
*
322 sizeof(*cpi
->yuv0ptr
));
324 _ogg_malloc(FrameSize
*
325 sizeof(*cpi
->yuv1ptr
));
326 cpi
->OptimisedTokenListEb
=
327 _ogg_malloc(FrameSize
*
328 sizeof(*cpi
->OptimisedTokenListEb
));
329 cpi
->OptimisedTokenList
=
330 _ogg_malloc(FrameSize
*
331 sizeof(*cpi
->OptimisedTokenList
));
332 cpi
->OptimisedTokenListHi
=
333 _ogg_malloc(FrameSize
*
334 sizeof(*cpi
->OptimisedTokenListHi
));
335 cpi
->OptimisedTokenListPl
=
336 _ogg_malloc(FrameSize
*
337 sizeof(*cpi
->OptimisedTokenListPl
));
340 static void SetupKeyFrame(CP_INSTANCE
*cpi
) {
341 /* Make sure the "last frame" buffer contains the first frame data
343 memcpy ( cpi
->yuv0ptr
, cpi
->yuv1ptr
,
344 cpi
->pb
.ReconYPlaneSize
+ 2 * cpi
->pb
.ReconUVPlaneSize
);
346 /* Initialise the cpi->pb.display_fragments and other fragment
347 structures for the first frame. */
348 memset( cpi
->pb
.display_fragments
, 1, cpi
->pb
.UnitFragments
);
349 memset( cpi
->extra_fragments
, 1, cpi
->pb
.UnitFragments
);
351 /* Set up for a KEY FRAME */
352 cpi
->pb
.FrameType
= KEY_FRAME
;
355 static void AdjustKeyFrameContext(CP_INSTANCE
*cpi
) {
357 ogg_uint32_t AvKeyFrameFrequency
=
358 (ogg_uint32_t
) (cpi
->CurrentFrame
/ cpi
->KeyFrameCount
);
359 ogg_uint32_t AvKeyFrameBytes
=
360 (ogg_uint32_t
) (cpi
->TotKeyFrameBytes
/ cpi
->KeyFrameCount
);
361 ogg_uint32_t TotalWeight
=0;
362 ogg_int32_t AvKeyFramesPerSecond
;
363 ogg_int32_t MinFrameTargetRate
;
365 /* Update the frame carry over. */
366 cpi
->TotKeyFrameBytes
+= oggpackB_bytes(cpi
->oggbuffer
);
368 /* reset keyframe context and calculate weighted average of last
369 KEY_FRAME_CONTEXT keyframes */
370 for( i
= 0 ; i
< KEY_FRAME_CONTEXT
; i
++ ) {
371 if ( i
< KEY_FRAME_CONTEXT
-1) {
372 cpi
->PriorKeyFrameSize
[i
] = cpi
->PriorKeyFrameSize
[i
+1];
373 cpi
->PriorKeyFrameDistance
[i
] = cpi
->PriorKeyFrameDistance
[i
+1];
375 cpi
->PriorKeyFrameSize
[KEY_FRAME_CONTEXT
- 1] =
376 oggpackB_bytes(cpi
->oggbuffer
);
377 cpi
->PriorKeyFrameDistance
[KEY_FRAME_CONTEXT
- 1] =
381 AvKeyFrameBytes
+= PriorKeyFrameWeight
[i
] *
382 cpi
->PriorKeyFrameSize
[i
];
383 AvKeyFrameFrequency
+= PriorKeyFrameWeight
[i
] *
384 cpi
->PriorKeyFrameDistance
[i
];
385 TotalWeight
+= PriorKeyFrameWeight
[i
];
387 AvKeyFrameBytes
/= TotalWeight
;
388 AvKeyFrameFrequency
/= TotalWeight
;
389 AvKeyFramesPerSecond
= 100 * cpi
->Configuration
.OutputFrameRate
/
390 AvKeyFrameFrequency
;
392 /* Calculate a new target rate per frame allowing for average key
393 frame frequency over newest frames . */
394 if ( 100 * cpi
->Configuration
.TargetBandwidth
>
395 AvKeyFrameBytes
* AvKeyFramesPerSecond
&&
396 (100 * cpi
->Configuration
.OutputFrameRate
- AvKeyFramesPerSecond
)){
397 cpi
->frame_target_rate
=
398 (ogg_int32_t
)(100* cpi
->Configuration
.TargetBandwidth
-
399 AvKeyFrameBytes
* AvKeyFramesPerSecond
) /
400 ( (100 * cpi
->Configuration
.OutputFrameRate
- AvKeyFramesPerSecond
) );
402 /* don't let this number get too small!!! */
403 cpi
->frame_target_rate
= 1;
406 /* minimum allowable frame_target_rate */
407 MinFrameTargetRate
= (cpi
->Configuration
.TargetBandwidth
/
408 cpi
->Configuration
.OutputFrameRate
) / 3;
410 if(cpi
->frame_target_rate
< MinFrameTargetRate
) {
411 cpi
->frame_target_rate
= MinFrameTargetRate
;
414 cpi
->LastKeyFrame
= 1;
415 cpi
->LastKeyFrameSize
=oggpackB_bytes(cpi
->oggbuffer
);
419 static void UpdateFrame(CP_INSTANCE
*cpi
){
421 double CorrectionFactor
;
423 /* Reset the DC predictors. */
424 cpi
->pb
.LastIntraDC
= 0;
425 cpi
->pb
.InvLastIntraDC
= 0;
426 cpi
->pb
.LastInterDC
= 0;
427 cpi
->pb
.InvLastInterDC
= 0;
429 /* Initialise bit packing mechanism. */
430 oggpackB_reset(cpi
->oggbuffer
);
432 /* mark as video frame */
433 oggpackB_write(cpi
->oggbuffer
,0,1);
435 /* Write out the frame header information including size. */
436 WriteFrameHeader(cpi
);
438 /* Copy back any extra frags that are to be updated by the codec
439 as part of the background cleanup task */
440 CopyBackExtraFrags(cpi
);
442 /* Encode the data. */
445 /* Adjust drop frame trigger. */
446 if ( cpi
->pb
.FrameType
!= KEY_FRAME
) {
447 /* Apply decay factor then add in the last frame size. */
448 cpi
->DropFrameTriggerBytes
=
449 ((cpi
->DropFrameTriggerBytes
* (DF_CANDIDATE_WINDOW
-1)) /
450 DF_CANDIDATE_WINDOW
) + oggpackB_bytes(cpi
->oggbuffer
);
452 /* Increase cpi->DropFrameTriggerBytes a little. Just after a key
453 frame may actually be a good time to drop a frame. */
454 cpi
->DropFrameTriggerBytes
=
455 (cpi
->DropFrameTriggerBytes
* DF_CANDIDATE_WINDOW
) /
456 (DF_CANDIDATE_WINDOW
-1);
459 /* Test for overshoot which may require a dropped frame next time
460 around. If we are already in a drop frame condition but the
461 previous frame was not dropped then the threshold for continuing
462 to allow dropped frames is reduced. */
463 if ( cpi
->DropFrameCandidate
) {
464 if ( cpi
->DropFrameTriggerBytes
>
465 (cpi
->frame_target_rate
* (DF_CANDIDATE_WINDOW
+1)) )
466 cpi
->DropFrameCandidate
= 1;
468 cpi
->DropFrameCandidate
= 0;
470 if ( cpi
->DropFrameTriggerBytes
>
471 (cpi
->frame_target_rate
* ((DF_CANDIDATE_WINDOW
*2)-2)) )
472 cpi
->DropFrameCandidate
= 1;
474 cpi
->DropFrameCandidate
= 0;
477 /* Update the BpbCorrectionFactor variable according to whether or
478 not we were close enough with our selection of DCT quantiser. */
479 if ( cpi
->pb
.FrameType
!= KEY_FRAME
) {
480 /* Work out a size correction factor. */
481 CorrectionFactor
= (double)oggpackB_bytes(cpi
->oggbuffer
) /
482 (double)cpi
->ThisFrameTargetBytes
;
484 if ( (CorrectionFactor
> 1.05) &&
485 (cpi
->pb
.ThisFrameQualityValue
<
486 cpi
->pb
.QThreshTable
[cpi
->Configuration
.ActiveMaxQ
]) ) {
487 CorrectionFactor
= 1.0 + ((CorrectionFactor
- 1.0)/2);
488 if ( CorrectionFactor
> 1.5 )
489 cpi
->BpbCorrectionFactor
*= 1.5;
491 cpi
->BpbCorrectionFactor
*= CorrectionFactor
;
493 /* Keep BpbCorrectionFactor within limits */
494 if ( cpi
->BpbCorrectionFactor
> MAX_BPB_FACTOR
)
495 cpi
->BpbCorrectionFactor
= MAX_BPB_FACTOR
;
496 } else if ( (CorrectionFactor
< 0.95) &&
497 (cpi
->pb
.ThisFrameQualityValue
> VERY_BEST_Q
) ){
498 CorrectionFactor
= 1.0 - ((1.0 - CorrectionFactor
)/2);
499 if ( CorrectionFactor
< 0.75 )
500 cpi
->BpbCorrectionFactor
*= 0.75;
502 cpi
->BpbCorrectionFactor
*= CorrectionFactor
;
504 /* Keep BpbCorrectionFactor within limits */
505 if ( cpi
->BpbCorrectionFactor
< MIN_BPB_FACTOR
)
506 cpi
->BpbCorrectionFactor
= MIN_BPB_FACTOR
;
510 /* Adjust carry over and or key frame context. */
511 if ( cpi
->pb
.FrameType
== KEY_FRAME
) {
512 /* Adjust the key frame context unless the key frame was very small */
513 AdjustKeyFrameContext(cpi
);
515 /* Update the frame carry over */
516 cpi
->CarryOver
+= ((ogg_int32_t
)cpi
->frame_target_rate
-
517 (ogg_int32_t
)oggpackB_bytes(cpi
->oggbuffer
));
519 cpi
->TotalByteCount
+= oggpackB_bytes(cpi
->oggbuffer
);
522 static void CompressFirstFrame(CP_INSTANCE
*cpi
) {
525 /* set up context of key frame sizes and distances for more local
527 for( i
= 0 ; i
< KEY_FRAME_CONTEXT
; i
++ ) {
528 cpi
->PriorKeyFrameSize
[i
] = cpi
->Configuration
.KeyFrameDataTarget
;
529 cpi
->PriorKeyFrameDistance
[i
] = cpi
->pb
.info
.keyframe_frequency_force
;
532 /* Keep track of the total number of Key Frames Coded. */
533 cpi
->KeyFrameCount
= 1;
534 cpi
->LastKeyFrame
= 1;
535 cpi
->TotKeyFrameBytes
= 0;
537 /* A key frame is not a dropped frame there for reset the count of
538 consequative dropped frames. */
543 /* Calculate a new target rate per frame allowing for average key
544 frame frequency and size thus far. */
545 if ( cpi
->Configuration
.TargetBandwidth
>
546 ((cpi
->Configuration
.KeyFrameDataTarget
*
547 cpi
->Configuration
.OutputFrameRate
)/
548 cpi
->pb
.info
.keyframe_frequency
) ) {
550 cpi
->frame_target_rate
=
551 (ogg_int32_t
)((cpi
->Configuration
.TargetBandwidth
-
552 ((cpi
->Configuration
.KeyFrameDataTarget
*
553 cpi
->Configuration
.OutputFrameRate
)/
554 cpi
->pb
.info
.keyframe_frequency
)) /
555 cpi
->Configuration
.OutputFrameRate
);
557 cpi
->frame_target_rate
= 1;
559 /* Set baseline frame target rate. */
560 cpi
->BaseLineFrameTargetRate
= cpi
->frame_target_rate
;
562 /* A key frame is not a dropped frame there for reset the count of
563 consequative dropped frames. */
566 /* Initialise drop frame trigger to 5 frames worth of data. */
567 cpi
->DropFrameTriggerBytes
= cpi
->frame_target_rate
* DF_CANDIDATE_WINDOW
;
569 /* Set a target size for this key frame based upon the baseline
570 target and frequency */
571 cpi
->ThisFrameTargetBytes
= cpi
->Configuration
.KeyFrameDataTarget
;
573 /* Get a DCT quantizer level for the key frame. */
574 cpi
->MotionScore
= cpi
->pb
.UnitFragments
;
576 RegulateQ(cpi
, cpi
->pb
.UnitFragments
);
578 cpi
->pb
.LastFrameQualityValue
= cpi
->pb
.ThisFrameQualityValue
;
580 /* Initialise quantizer. */
581 UpdateQC(cpi
, cpi
->pb
.ThisFrameQualityValue
);
583 /* Initialise the cpi->pb.display_fragments and other fragment
584 structures for the first frame. */
585 for ( i
= 0; i
< cpi
->pb
.UnitFragments
; i
++ )
586 cpi
->FragmentLastQ
[i
] = cpi
->pb
.ThisFrameQualityValue
;
588 /* Compress and output the frist frame. */
590 cpi
->pb
.YSBRows
, cpi
->pb
.YSBCols
);
593 /* Initialise the carry over rate targeting variables. */
598 static void CompressKeyFrame(CP_INSTANCE
*cpi
){
601 /* Before we compress reset the carry over to the actual frame carry over */
602 cpi
->CarryOver
= cpi
->Configuration
.TargetBandwidth
* cpi
->CurrentFrame
/
603 cpi
->Configuration
.OutputFrameRate
- cpi
->TotalByteCount
;
605 /* Keep track of the total number of Key Frames Coded */
606 cpi
->KeyFrameCount
+= 1;
608 /* A key frame is not a dropped frame there for reset the count of
609 consequative dropped frames. */
614 /* set a target size for this frame */
615 cpi
->ThisFrameTargetBytes
= (ogg_int32_t
) cpi
->frame_target_rate
+
616 ( (cpi
->Configuration
.KeyFrameDataTarget
- cpi
->frame_target_rate
) *
617 cpi
->LastKeyFrame
/ cpi
->pb
.info
.keyframe_frequency_force
);
619 if ( cpi
->ThisFrameTargetBytes
> cpi
->Configuration
.KeyFrameDataTarget
)
620 cpi
->ThisFrameTargetBytes
= cpi
->Configuration
.KeyFrameDataTarget
;
622 /* Get a DCT quantizer level for the key frame. */
623 cpi
->MotionScore
= cpi
->pb
.UnitFragments
;
625 RegulateQ(cpi
, cpi
->pb
.UnitFragments
);
627 cpi
->pb
.LastFrameQualityValue
= cpi
->pb
.ThisFrameQualityValue
;
629 /* Initialise DCT tables. */
630 UpdateQC(cpi
, cpi
->pb
.ThisFrameQualityValue
);
632 /* Initialise the cpi->pb.display_fragments and other fragment
633 structures for the first frame. */
634 for ( i
= 0; i
< cpi
->pb
.UnitFragments
; i
++ )
635 cpi
->FragmentLastQ
[i
] = cpi
->pb
.ThisFrameQualityValue
;
638 /* Compress and output the frist frame. */
640 cpi
->pb
.YSBRows
, cpi
->pb
.YSBCols
);
645 static void CompressFrame( CP_INSTANCE
*cpi
) {
646 ogg_int32_t min_blocks_per_frame
;
649 ogg_uint32_t ResidueBlocksAdded
=0;
650 ogg_uint32_t KFIndicator
= 0;
653 double QModifier
= 1.0;
655 /* Clear down the macro block level mode and MV arrays. */
656 for ( i
= 0; i
< cpi
->pb
.UnitFragments
; i
++ ) {
657 cpi
->pb
.FragCodingMethod
[i
] = CODE_INTER_NO_MV
; /* Default coding mode */
658 cpi
->pb
.FragMVect
[i
].x
= 0;
659 cpi
->pb
.FragMVect
[i
].y
= 0;
662 /* Default to delta frames. */
663 cpi
->pb
.FrameType
= DELTA_FRAME
;
665 /* Clear down the difference arrays for the current frame. */
666 memset( cpi
->pb
.display_fragments
, 0, cpi
->pb
.UnitFragments
);
667 memset( cpi
->extra_fragments
, 0, cpi
->pb
.UnitFragments
);
669 /* Calculate the target bytes for this frame. */
670 cpi
->ThisFrameTargetBytes
= cpi
->frame_target_rate
;
672 /* Correct target to try and compensate for any overall rate error
673 that is developing */
675 /* Set the max allowed Q for this frame based upon carry over
676 history. First set baseline worst Q for this frame */
677 cpi
->Configuration
.ActiveMaxQ
= cpi
->Configuration
.MaxQ
+ 10;
678 if ( cpi
->Configuration
.ActiveMaxQ
>= Q_TABLE_SIZE
)
679 cpi
->Configuration
.ActiveMaxQ
= Q_TABLE_SIZE
- 1;
681 /* Make a further adjustment based upon the carry over and recent
682 history.. cpi->Configuration.ActiveMaxQ reduced by 1 for each 1/2
683 seconds worth of -ve carry over up to a limit of 6. Also
684 cpi->Configuration.ActiveMaxQ reduced if frame is a
685 "DropFrameCandidate". Remember that if we are behind the bit
686 target carry over is -ve. */
687 if ( cpi
->CarryOver
< 0 ) {
688 if ( cpi
->DropFrameCandidate
) {
689 cpi
->Configuration
.ActiveMaxQ
-= 4;
692 if ( cpi
->CarryOver
<
693 -((ogg_int32_t
)cpi
->Configuration
.TargetBandwidth
*3) )
694 cpi
->Configuration
.ActiveMaxQ
-= 6;
696 cpi
->Configuration
.ActiveMaxQ
+=
697 (ogg_int32_t
) ((cpi
->CarryOver
*2) /
698 (ogg_int32_t
)cpi
->Configuration
.TargetBandwidth
);
700 /* Check that we have not dropped quality too far */
701 if ( cpi
->Configuration
.ActiveMaxQ
< cpi
->Configuration
.MaxQ
)
702 cpi
->Configuration
.ActiveMaxQ
= cpi
->Configuration
.MaxQ
;
705 /* Calculate the Q Modifier step size required to cause a step down
706 from full target bandwidth to 40% of target between max Q and
708 QModStep
= 0.5 / (double)((Q_TABLE_SIZE
- 1) -
709 cpi
->Configuration
.ActiveMaxQ
);
711 /* Set up the cpi->QTargetModifier[] table. */
712 for ( i
= 0; i
< cpi
->Configuration
.ActiveMaxQ
; i
++ ) {
713 cpi
->QTargetModifier
[i
] = QModifier
;
715 for ( i
= cpi
->Configuration
.ActiveMaxQ
; i
< Q_TABLE_SIZE
; i
++ ) {
716 cpi
->QTargetModifier
[i
] = QModifier
;
717 QModifier
-= QModStep
;
720 /* if we are allowed to drop frames and are falling behind (eg more
721 than x frames worth of bandwidth) */
722 if ( cpi
->pb
.info
.dropframes_p
&&
723 ( cpi
->DropCount
< cpi
->MaxConsDroppedFrames
) &&
725 -((ogg_int32_t
)cpi
->Configuration
.TargetBandwidth
)) &&
726 ( cpi
->DropFrameCandidate
) ) {
727 /* (we didn't do this frame so we should have some left over for
729 cpi
->CarryOver
+= cpi
->frame_target_rate
;
733 /* Adjust DropFrameTriggerBytes to account for the saving achieved. */
734 cpi
->DropFrameTriggerBytes
=
735 (cpi
->DropFrameTriggerBytes
*
736 (DF_CANDIDATE_WINDOW
-1))/DF_CANDIDATE_WINDOW
;
738 /* Even if we drop a frame we should account for it when
739 considering key frame seperation. */
741 } else if ( cpi
->CarryOver
<
742 -((ogg_int32_t
)cpi
->Configuration
.TargetBandwidth
* 2) ) {
743 /* Reduce frame bit target by 1.75% for each 1/10th of a seconds
744 worth of -ve carry over down to a minimum of 65% of its
745 un-modified value. */
747 cpi
->ThisFrameTargetBytes
=
748 (ogg_uint32_t
)(cpi
->ThisFrameTargetBytes
* 0.65);
749 } else if ( cpi
->CarryOver
< 0 ) {
750 /* Note that cpi->CarryOver is a -ve here hence 1.0 "+" ... */
751 cpi
->ThisFrameTargetBytes
=
752 (ogg_uint32_t
)(cpi
->ThisFrameTargetBytes
*
753 (1.0 + ( ((cpi
->CarryOver
* 10)/
755 Configuration
.TargetBandwidth
)) * 0.0175) ));
759 /* pick all the macroblock modes and motion vectors */
760 ogg_uint32_t InterError
;
761 ogg_uint32_t IntraError
;
764 /* Set Baseline filter level. */
765 ConfigurePP( &cpi
->pp
, cpi
->pb
.info
.noise_sensitivity
);
767 /* Score / analyses the fragments. */
768 cpi
->MotionScore
= YUVAnalyseFrame(&cpi
->pp
, &KFIndicator
);
770 /* Get the baseline Q value */
771 RegulateQ( cpi
, cpi
->MotionScore
);
773 /* Recode blocks if the error score in last frame was high. */
774 ResidueBlocksAdded
= 0;
775 for ( i
= 0; i
< cpi
->pb
.UnitFragments
; i
++ ){
776 if ( !cpi
->pb
.display_fragments
[i
] ){
777 if ( cpi
->LastCodedErrorScore
[i
] >=
778 ResidueErrorThresh
[cpi
->pb
.FrameQIndex
] ) {
779 cpi
->pb
.display_fragments
[i
] = 1; /* Force block update */
780 cpi
->extra_fragments
[i
] = 1; /* Insures up to date
781 pixel data is used. */
782 ResidueBlocksAdded
++;
787 /* Adjust the motion score to allow for residue blocks
788 added. These are assumed to have below average impact on
789 bitrate (Hence ResidueBlockFactor). */
790 cpi
->MotionScore
= cpi
->MotionScore
+
791 (ResidueBlocksAdded
/ ResidueBlockFactor
[cpi
->pb
.FrameQIndex
]);
793 /* Estimate the min number of blocks at best Q */
794 min_blocks_per_frame
=
795 (ogg_int32_t
)(cpi
->ThisFrameTargetBytes
/
796 GetEstimatedBpb( cpi
, VERY_BEST_Q
));
797 if ( min_blocks_per_frame
== 0 )
798 min_blocks_per_frame
= 1;
800 /* If we have less than this number then consider adding in some
802 if ( cpi
->MotionScore
< min_blocks_per_frame
) {
803 min_blocks_per_frame
=
805 (ogg_int32_t
)(((min_blocks_per_frame
- cpi
->MotionScore
) * 4) / 3 );
806 UpRegulateDataStream( cpi
, VERY_BEST_Q
, min_blocks_per_frame
);
808 /* Reset control variable for best quality final pass. */
809 cpi
->FinalPassLastPos
= 0;
812 /* Get the modified Q prediction taking into account extra blocks added. */
813 RegulateQ( cpi
, cpi
->MotionScore
);
815 /* Unless we are already well ahead (4 seconds of data) of the
817 if ( cpi
->CarryOver
<
818 (ogg_int32_t
)(cpi
->Configuration
.TargetBandwidth
* 4) ){
819 /* Look at the predicted Q (pbi->FrameQIndex). Adjust the
820 target bits for this frame based upon projected Q and
821 re-calculate. The idea is that if the Q is better than a
822 given (good enough) level then we will try and save some bits
823 for use in more difficult segments. */
824 cpi
->ThisFrameTargetBytes
=
825 (ogg_int32_t
) (cpi
->ThisFrameTargetBytes
*
826 cpi
->QTargetModifier
[cpi
->pb
.FrameQIndex
]);
828 /* Recalculate Q again */
829 RegulateQ( cpi
, cpi
->MotionScore
);
833 /* Select modes and motion vectors for each of the blocks : return
834 an error score for inter and intra */
835 PickModes( cpi
, cpi
->pb
.YSBRows
, cpi
->pb
.YSBCols
,
837 &InterError
, &IntraError
);
839 /* decide whether we really should have made this frame a key frame */
840 /* forcing out a keyframe if the max interval is up is done at a higher level */
841 if( cpi
->pb
.info
.keyframe_auto_p
){
842 if( ( 2* IntraError
< 5 * InterError
)
843 && ( KFIndicator
>= (ogg_uint32_t
)
844 cpi
->pb
.info
.keyframe_auto_threshold
)
845 && ( cpi
->LastKeyFrame
> cpi
->pb
.info
.keyframe_mindistance
)
847 CompressKeyFrame(cpi
); /* Code a key frame */
853 /* Increment the frames since last key frame count */
856 /* Proceed with the frame update. */
860 if ( cpi
->MotionScore
> 0 ){
861 /* Note the Quantizer used for each block coded. */
862 for ( i
= 0; i
< cpi
->pb
.UnitFragments
; i
++ ){
863 if ( cpi
->pb
.display_fragments
[i
] ){
864 cpi
->FragmentLastQ
[i
] = cpi
->pb
.ThisFrameQualityValue
;
870 /* even if we 'drop' a frame, a placeholder must be written as we
871 currently assume fixed frame rate timebase as Ogg mapping
877 /********************** The toplevel: encode ***********************/
879 static int _ilog(unsigned int v
){
888 static void theora_encode_dispatch_init(CP_INSTANCE
*cpi
);
890 int theora_encode_init(theora_state
*th
, theora_info
*c
){
895 memset(th
, 0, sizeof(*th
));
896 /*Currently only the 4:2:0 format is supported.*/
897 if(c
->pixelformat
!=OC_PF_420
)return OC_IMPL
;
898 th
->internal_encode
=cpi
=_ogg_calloc(1,sizeof(*cpi
));
899 theora_encode_dispatch_init(cpi
);
901 dsp_static_init (&cpi
->dsp
);
902 memcpy (&cpi
->pb
.dsp
, &cpi
->dsp
, sizeof(DspFunctions
));
904 c
->version_major
=TH_VERSION_MAJOR
;
905 c
->version_minor
=TH_VERSION_MINOR
;
906 c
->version_subminor
=TH_VERSION_SUB
;
908 InitTmpBuffers(&cpi
->pb
);
909 InitPPInstance(&cpi
->pp
, &cpi
->dsp
);
911 /* Initialise Configuration structure to legal values */
912 if(c
->quality
>63)c
->quality
=63;
913 if(c
->quality
<0)c
->quality
=32;
914 if(c
->target_bitrate
<0)c
->target_bitrate
=0;
915 /* we clamp target_bitrate to 24 bits after setting up the encoder */
917 cpi
->Configuration
.BaseQ
= c
->quality
;
918 cpi
->Configuration
.FirstFrameQ
= c
->quality
;
919 cpi
->Configuration
.MaxQ
= c
->quality
;
920 cpi
->Configuration
.ActiveMaxQ
= c
->quality
;
922 cpi
->MVChangeFactor
= 14;
923 cpi
->FourMvChangeFactor
= 8;
924 cpi
->MinImprovementForNewMV
= 25;
925 cpi
->ExhaustiveSearchThresh
= 2500;
926 cpi
->MinImprovementForFourMV
= 100;
927 cpi
->FourMVThreshold
= 10000;
928 cpi
->BitRateCapFactor
= 1.5;
929 cpi
->InterTripOutThresh
= 5000;
931 cpi
->InterCodeCount
= 127;
932 cpi
->BpbCorrectionFactor
= 1.0;
933 cpi
->GoldenFrameEnabled
= 1;
934 cpi
->InterPrediction
= 1;
935 cpi
->MotionCompensation
= 1;
936 cpi
->ThreshMapThreshold
= 5;
937 cpi
->MaxConsDroppedFrames
= 1;
939 /* Set encoder flags. */
940 /* if not AutoKeyframing cpi->ForceKeyFrameEvery = is frequency */
941 if(!c
->keyframe_auto_p
)
942 c
->keyframe_frequency_force
= c
->keyframe_frequency
;
944 /* Set the frame rate variables. */
945 if ( c
->fps_numerator
< 1 )
946 c
->fps_numerator
= 1;
947 if ( c
->fps_denominator
< 1 )
948 c
->fps_denominator
= 1;
950 /* don't go too nuts on keyframe spacing; impose a high limit to
951 make certain the granulepos encoding strategy works */
952 if(c
->keyframe_frequency_force
>32768)c
->keyframe_frequency_force
=32768;
953 if(c
->keyframe_mindistance
>32768)c
->keyframe_mindistance
=32768;
954 if(c
->keyframe_mindistance
>c
->keyframe_frequency_force
)
955 c
->keyframe_mindistance
=c
->keyframe_frequency_force
;
956 cpi
->pb
.keyframe_granule_shift
=_ilog(c
->keyframe_frequency_force
-1);
958 /* clamp the target_bitrate to a maximum of 24 bits so we get a
959 more meaningful value when we write this out in the header. */
960 if(c
->target_bitrate
>(1<<24)-1)c
->target_bitrate
=(1<<24)-1;
963 memcpy(&cpi
->pb
.info
,c
,sizeof(*c
));
967 /* Set up default values for QTargetModifier[Q_TABLE_SIZE] table */
968 for ( i
= 0; i
< Q_TABLE_SIZE
; i
++ )
969 cpi
->QTargetModifier
[i
] = 1.0;
971 /* Set up an encode buffer */
972 cpi
->oggbuffer
= _ogg_malloc(sizeof(oggpack_buffer
));
973 oggpackB_writeinit(cpi
->oggbuffer
);
975 /* Set data rate related variables. */
976 cpi
->Configuration
.TargetBandwidth
= (c
->target_bitrate
) / 8;
978 cpi
->Configuration
.OutputFrameRate
=
979 (double)( c
->fps_numerator
/
980 c
->fps_denominator
);
982 cpi
->frame_target_rate
= cpi
->Configuration
.TargetBandwidth
/
983 cpi
->Configuration
.OutputFrameRate
;
985 /* Set key frame data rate target; this is nominal keyframe size */
986 cpi
->Configuration
.KeyFrameDataTarget
= (c
->keyframe_data_target_bitrate
*
988 c
->fps_numerator
) / 8;
990 /* Note the height and width in the pre-processor control structure. */
991 cpi
->ScanConfig
.VideoFrameHeight
= cpi
->pb
.info
.height
;
992 cpi
->ScanConfig
.VideoFrameWidth
= cpi
->pb
.info
.width
;
994 InitFrameDetails(&cpi
->pb
);
995 EInitFragmentInfo(cpi
);
998 /* Set up pre-processor config pointers. */
999 cpi
->ScanConfig
.Yuv0ptr
= cpi
->yuv0ptr
;
1000 cpi
->ScanConfig
.Yuv1ptr
= cpi
->yuv1ptr
;
1001 cpi
->ScanConfig
.SrfWorkSpcPtr
= cpi
->ConvDestBuffer
;
1002 cpi
->ScanConfig
.disp_fragments
= cpi
->pb
.display_fragments
;
1003 cpi
->ScanConfig
.RegionIndex
= cpi
->pb
.pixel_index_table
;
1005 /* Initialise the pre-processor module. */
1006 ScanYUVInit(&cpi
->pp
, &(cpi
->ScanConfig
));
1008 /* Initialise Motion compensation */
1009 InitMotionCompensation(cpi
);
1011 /* Initialise the compression process. */
1012 /* We always start at frame 1 */
1013 cpi
->CurrentFrame
= 1;
1015 /* Reset the rate targeting correction factor. */
1016 cpi
->BpbCorrectionFactor
= 1.0;
1018 cpi
->TotalByteCount
= 0;
1019 cpi
->TotalMotionScore
= 0;
1021 /* Up regulation variables. */
1022 cpi
->FinalPassLastPos
= 0; /* Used to regulate a final unrestricted pass. */
1023 cpi
->LastEndSB
= 0; /* Where we were in the loop last time. */
1024 cpi
->ResidueLastEndSB
= 0; /* Where we were in the residue update
1027 InitHuffmanSet(&cpi
->pb
);
1029 /* This makes sure encoder version specific tables are initialised */
1030 memcpy(&cpi
->pb
.quant_info
, &TH_VP31_QUANT_INFO
, sizeof(th_quant_info
));
1031 InitQTables(&cpi
->pb
);
1033 /* Indicate that the next frame to be compressed is the first in the
1035 cpi
->ThisIsFirstFrame
= 1;
1038 cpi
->pb
.HeadersWritten
= 0;
1039 /*We overload this flag to track header output.*/
1045 int theora_encode_YUVin(theora_state
*t
,
1048 unsigned char *LocalDataPtr
;
1049 unsigned char *InputDataPtr
;
1050 CP_INSTANCE
*cpi
=(CP_INSTANCE
*)(t
->internal_encode
);
1052 if(!cpi
->readyflag
)return OC_EINVAL
;
1053 if(cpi
->doneflag
>0)return OC_EINVAL
;
1055 /* If frame size has changed, abort out for now */
1056 if (yuv
->y_height
!= (int)cpi
->pb
.info
.height
||
1057 yuv
->y_width
!= (int)cpi
->pb
.info
.width
)
1061 /* Copy over input YUV to internal YUV buffers. */
1062 /* we invert the image for backward compatibility with VP3 */
1063 /* First copy over the Y data */
1064 LocalDataPtr
= cpi
->yuv1ptr
+ yuv
->y_width
*(yuv
->y_height
- 1);
1065 InputDataPtr
= yuv
->y
;
1066 for ( i
= 0; i
< yuv
->y_height
; i
++ ){
1067 memcpy( LocalDataPtr
, InputDataPtr
, yuv
->y_width
);
1068 LocalDataPtr
-= yuv
->y_width
;
1069 InputDataPtr
+= yuv
->y_stride
;
1072 /* Now copy over the U data */
1073 LocalDataPtr
= &cpi
->yuv1ptr
[(yuv
->y_height
* yuv
->y_width
)];
1074 LocalDataPtr
+= yuv
->uv_width
*(yuv
->uv_height
- 1);
1075 InputDataPtr
= yuv
->u
;
1076 for ( i
= 0; i
< yuv
->uv_height
; i
++ ){
1077 memcpy( LocalDataPtr
, InputDataPtr
, yuv
->uv_width
);
1078 LocalDataPtr
-= yuv
->uv_width
;
1079 InputDataPtr
+= yuv
->uv_stride
;
1082 /* Now copy over the V data */
1084 &cpi
->yuv1ptr
[((yuv
->y_height
*yuv
->y_width
)*5)/4];
1085 LocalDataPtr
+= yuv
->uv_width
*(yuv
->uv_height
- 1);
1086 InputDataPtr
= yuv
->v
;
1087 for ( i
= 0; i
< yuv
->uv_height
; i
++ ){
1088 memcpy( LocalDataPtr
, InputDataPtr
, yuv
->uv_width
);
1089 LocalDataPtr
-= yuv
->uv_width
;
1090 InputDataPtr
+= yuv
->uv_stride
;
1093 /* Special case for first frame */
1094 if ( cpi
->ThisIsFirstFrame
){
1095 CompressFirstFrame(cpi
);
1096 cpi
->ThisIsFirstFrame
= 0;
1097 cpi
->ThisIsKeyFrame
= 0;
1100 /* don't allow generating invalid files that overflow the p-frame
1101 shift, even if keyframe_auto_p is turned off */
1102 if(cpi
->LastKeyFrame
>= (ogg_uint32_t
)
1103 cpi
->pb
.info
.keyframe_frequency_force
)
1104 cpi
->ThisIsKeyFrame
= 1;
1106 if ( cpi
->ThisIsKeyFrame
) {
1107 CompressKeyFrame(cpi
);
1108 cpi
->ThisIsKeyFrame
= 0;
1110 /* Compress the frame. */
1111 CompressFrame( cpi
);
1116 /* Update stats variables. */
1117 cpi
->LastFrameSize
= oggpackB_bytes(cpi
->oggbuffer
);
1118 cpi
->CurrentFrame
++;
1122 ((cpi
->CurrentFrame
- cpi
->LastKeyFrame
)<<cpi
->pb
.keyframe_granule_shift
)+
1123 cpi
->LastKeyFrame
- 1;
1128 int theora_encode_packetout( theora_state
*t
, int last_p
, ogg_packet
*op
){
1129 CP_INSTANCE
*cpi
=(CP_INSTANCE
*)(t
->internal_encode
);
1130 long bytes
=oggpackB_bytes(cpi
->oggbuffer
);
1132 if(!bytes
)return(0);
1133 if(!cpi
->packetflag
)return(0);
1134 if(cpi
->doneflag
>0)return(-1);
1136 op
->packet
=oggpackB_get_buffer(cpi
->oggbuffer
);
1141 op
->packetno
=cpi
->CurrentFrame
;
1142 op
->granulepos
=t
->granulepos
;
1145 if(last_p
)cpi
->doneflag
=1;
1150 static void _tp_writebuffer(oggpack_buffer
*opb
, const char *buf
, const long len
)
1154 for (i
= 0; i
< len
; i
++)
1155 oggpackB_write(opb
, *buf
++, 8);
1158 static void _tp_writelsbint(oggpack_buffer
*opb
, long value
)
1160 oggpackB_write(opb
, value
&0xFF, 8);
1161 oggpackB_write(opb
, value
>>8&0xFF, 8);
1162 oggpackB_write(opb
, value
>>16&0xFF, 8);
1163 oggpackB_write(opb
, value
>>24&0xFF, 8);
1166 /* build the initial short header for stream recognition and format */
1167 int theora_encode_header(theora_state
*t
, ogg_packet
*op
){
1168 CP_INSTANCE
*cpi
=(CP_INSTANCE
*)(t
->internal_encode
);
1171 oggpackB_reset(cpi
->oggbuffer
);
1172 oggpackB_write(cpi
->oggbuffer
,0x80,8);
1173 _tp_writebuffer(cpi
->oggbuffer
, "theora", 6);
1175 oggpackB_write(cpi
->oggbuffer
,TH_VERSION_MAJOR
,8);
1176 oggpackB_write(cpi
->oggbuffer
,TH_VERSION_MINOR
,8);
1177 oggpackB_write(cpi
->oggbuffer
,TH_VERSION_SUB
,8);
1179 oggpackB_write(cpi
->oggbuffer
,cpi
->pb
.info
.width
>>4,16);
1180 oggpackB_write(cpi
->oggbuffer
,cpi
->pb
.info
.height
>>4,16);
1181 oggpackB_write(cpi
->oggbuffer
,cpi
->pb
.info
.frame_width
,24);
1182 oggpackB_write(cpi
->oggbuffer
,cpi
->pb
.info
.frame_height
,24);
1183 oggpackB_write(cpi
->oggbuffer
,cpi
->pb
.info
.offset_x
,8);
1184 /* Applications use offset_y to mean offset from the top of the image; the
1185 * meaning in the bitstream is the opposite (from the bottom). Transform.
1187 offset_y
= cpi
->pb
.info
.height
- cpi
->pb
.info
.frame_height
-
1188 cpi
->pb
.info
.offset_y
;
1189 oggpackB_write(cpi
->oggbuffer
,offset_y
,8);
1191 oggpackB_write(cpi
->oggbuffer
,cpi
->pb
.info
.fps_numerator
,32);
1192 oggpackB_write(cpi
->oggbuffer
,cpi
->pb
.info
.fps_denominator
,32);
1193 oggpackB_write(cpi
->oggbuffer
,cpi
->pb
.info
.aspect_numerator
,24);
1194 oggpackB_write(cpi
->oggbuffer
,cpi
->pb
.info
.aspect_denominator
,24);
1196 oggpackB_write(cpi
->oggbuffer
,cpi
->pb
.info
.colorspace
,8);
1197 oggpackB_write(cpi
->oggbuffer
,cpi
->pb
.info
.target_bitrate
,24);
1198 oggpackB_write(cpi
->oggbuffer
,cpi
->pb
.info
.quality
,6);
1200 oggpackB_write(cpi
->oggbuffer
,cpi
->pb
.keyframe_granule_shift
,5);
1202 oggpackB_write(cpi
->oggbuffer
,cpi
->pb
.info
.pixelformat
,2);
1204 oggpackB_write(cpi
->oggbuffer
,0,3); /* spare config bits */
1206 op
->packet
=oggpackB_get_buffer(cpi
->oggbuffer
);
1207 op
->bytes
=oggpackB_bytes(cpi
->oggbuffer
);
1220 /* build the comment header packet from the passed metadata */
1221 int theora_encode_comment(theora_comment
*tc
, ogg_packet
*op
)
1223 const char *vendor
= theora_version_string();
1224 const int vendor_length
= strlen(vendor
);
1225 oggpack_buffer
*opb
;
1227 opb
= _ogg_malloc(sizeof(oggpack_buffer
));
1228 oggpackB_writeinit(opb
);
1229 oggpackB_write(opb
, 0x81, 8);
1230 _tp_writebuffer(opb
, "theora", 6);
1232 _tp_writelsbint(opb
, vendor_length
);
1233 _tp_writebuffer(opb
, vendor
, vendor_length
);
1235 _tp_writelsbint(opb
, tc
->comments
);
1238 for(i
=0;i
<tc
->comments
;i
++){
1239 if(tc
->user_comments
[i
]){
1240 _tp_writelsbint(opb
,tc
->comment_lengths
[i
]);
1241 _tp_writebuffer(opb
,tc
->user_comments
[i
],tc
->comment_lengths
[i
]);
1243 oggpackB_write(opb
,0,32);
1247 op
->bytes
=oggpack_bytes(opb
);
1249 /* So we're expecting the application will free this? */
1250 op
->packet
=_ogg_malloc(oggpack_bytes(opb
));
1251 memcpy(op
->packet
, oggpack_get_buffer(opb
), oggpack_bytes(opb
));
1252 oggpack_writeclear(opb
);
1265 /* build the final header packet with the tables required
1267 int theora_encode_tables(theora_state
*t
, ogg_packet
*op
){
1268 CP_INSTANCE
*cpi
=(CP_INSTANCE
*)(t
->internal_encode
);
1270 oggpackB_reset(cpi
->oggbuffer
);
1271 oggpackB_write(cpi
->oggbuffer
,0x82,8);
1272 _tp_writebuffer(cpi
->oggbuffer
,"theora",6);
1274 WriteQTables(&cpi
->pb
,cpi
->oggbuffer
);
1275 WriteHuffmanTrees(cpi
->pb
.HuffRoot_VP3x
,cpi
->oggbuffer
);
1277 op
->packet
=oggpackB_get_buffer(cpi
->oggbuffer
);
1278 op
->bytes
=oggpackB_bytes(cpi
->oggbuffer
);
1288 cpi
->pb
.HeadersWritten
= 1;
1293 static void theora_encode_clear (theora_state
*th
){
1295 cpi
=(CP_INSTANCE
*)th
->internal_encode
;
1298 ClearHuffmanSet(&cpi
->pb
);
1299 ClearFragmentInfo(&cpi
->pb
);
1300 ClearFrameInfo(&cpi
->pb
);
1301 EClearFragmentInfo(cpi
);
1302 EClearFrameInfo(cpi
);
1303 ClearTmpBuffers(&cpi
->pb
);
1304 ClearPPInstance(&cpi
->pp
);
1306 oggpackB_writeclear(cpi
->oggbuffer
);
1307 _ogg_free(cpi
->oggbuffer
);
1311 memset(th
,0,sizeof(*th
));
1315 /* returns, in seconds, absolute time of current packet in given
1317 static double theora_encode_granule_time(theora_state
*th
,
1318 ogg_int64_t granulepos
){
1319 #ifndef THEORA_DISABLE_FLOAT
1320 CP_INSTANCE
*cpi
=(CP_INSTANCE
*)(th
->internal_encode
);
1321 PB_INSTANCE
*pbi
=(PB_INSTANCE
*)(th
->internal_decode
);
1323 if(cpi
)pbi
=&cpi
->pb
;
1326 ogg_int64_t iframe
=granulepos
>>pbi
->keyframe_granule_shift
;
1327 ogg_int64_t pframe
=granulepos
-(iframe
<<pbi
->keyframe_granule_shift
);
1329 return (iframe
+pframe
)*
1330 ((double)pbi
->info
.fps_denominator
/pbi
->info
.fps_numerator
);
1335 return(-1); /* negative granulepos or float calculations disabled */
1338 /* returns frame number of current packet in given logical stream */
1339 static ogg_int64_t
theora_encode_granule_frame(theora_state
*th
,
1340 ogg_int64_t granulepos
){
1341 CP_INSTANCE
*cpi
=(CP_INSTANCE
*)(th
->internal_encode
);
1342 PB_INSTANCE
*pbi
=(PB_INSTANCE
*)(th
->internal_decode
);
1344 if(cpi
)pbi
=&cpi
->pb
;
1347 ogg_int64_t iframe
=granulepos
>>pbi
->keyframe_granule_shift
;
1348 ogg_int64_t pframe
=granulepos
-(iframe
<<pbi
->keyframe_granule_shift
);
1350 return (iframe
+pframe
-1);
1357 static int theora_encode_control(theora_state
*th
,int req
,
1358 void *buf
,size_t buf_sz
) {
1366 cpi
= th
->internal_encode
;
1370 case TH_ENCCTL_SET_QUANT_PARAMS
:
1371 if( ( buf
==NULL
&&buf_sz
!=0 )
1372 || ( buf
!=NULL
&&buf_sz
!=sizeof(th_quant_info
) )
1373 || cpi
->pb
.HeadersWritten
){
1377 if(buf
==NULL
)buf
=&TH_VP31_QUANT_INFO
;
1378 memcpy(&pbi
->quant_info
, buf
, sizeof(th_quant_info
));
1382 case TH_ENCCTL_SET_VP3_COMPATIBLE
:
1383 if(cpi
->pb
.HeadersWritten
)
1386 memcpy(&pbi
->quant_info
, &TH_VP31_QUANT_INFO
, sizeof(th_quant_info
));
1390 case TH_ENCCTL_SET_SPLEVEL
:
1391 if(buf
== NULL
|| buf_sz
!= sizeof(int))
1394 memcpy(&value
, buf
, sizeof(int));
1398 cpi
->MotionCompensation
= 1;
1399 pbi
->info
.quick_p
= 0;
1403 cpi
->MotionCompensation
= 1;
1404 pbi
->info
.quick_p
= 1;
1408 cpi
->MotionCompensation
= 0;
1409 pbi
->info
.quick_p
= 1;
1417 case TH_ENCCTL_GET_SPLEVEL_MAX
:
1419 memcpy(buf
, &value
, sizeof(int));
1426 static void theora_encode_dispatch_init(CP_INSTANCE
*cpi
){
1427 cpi
->dispatch_vtbl
.clear
=theora_encode_clear
;
1428 cpi
->dispatch_vtbl
.control
=theora_encode_control
;
1429 cpi
->dispatch_vtbl
.granule_frame
=theora_encode_granule_frame
;
1430 cpi
->dispatch_vtbl
.granule_time
=theora_encode_granule_time
;