Set quantization parameters to default values when an empty buffer is passed
[xiph.git] / theora / lib / enc / encoder_toplevel.c
blobd4777b26ce79b6e446950f63359b53486580951d
1 /********************************************************************
2 * *
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. *
7 * *
8 * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2007 *
9 * by the Xiph.Org Foundation http://www.xiph.org/ *
10 * *
11 ********************************************************************
13 function:
14 last mod: $Id$
16 ********************************************************************/
18 #ifdef HAVE_CONFIG_H
19 # include "config.h"
20 #endif
22 #include <stdlib.h>
23 #include <string.h>
24 #include "toplevel_lookup.h"
25 #include "../internal.h"
26 #include "dsp.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);
156 if(cpi->FragTokens)
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);
164 if(cpi->ModeList)
165 _ogg_free(cpi->ModeList);
166 if(cpi->MVList)
167 _ogg_free(cpi->MVList);
168 if(cpi->DCT_codes )
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);
174 if(cpi->OriginalDC)
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;
188 cpi->FragTokens = 0;
189 cpi->FragTokenCounts = 0;
190 cpi->RunHuffIndices = 0;
191 cpi->LastCodedErrorScore = 0;
192 cpi->ModeList = 0;
193 cpi->MVList = 0;
194 cpi->DCT_codes = 0;
195 cpi->DCTDataBuffer = 0;
196 cpi->quantized_list = 0;
197 cpi->OriginalDC = 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
211 checked:
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
215 memory!'...:
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
224 SEGV is generated.
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
229 a waste of code. */
231 cpi->FragmentLastQ =
232 _ogg_malloc(cpi->pb.UnitFragments*
233 sizeof(*cpi->FragmentLastQ));
234 cpi->FragTokens =
235 _ogg_malloc(cpi->pb.UnitFragments*
236 sizeof(*cpi->FragTokens));
237 cpi->OriginalDC =
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));
252 cpi->ModeList =
253 _ogg_malloc(cpi->pb.UnitFragments*
254 sizeof(*cpi->ModeList));
255 cpi->MVList =
256 _ogg_malloc(cpi->pb.UnitFragments*
257 sizeof(*cpi->MVList));
258 cpi->DCT_codes =
259 _ogg_malloc(64*
260 sizeof(*cpi->DCT_codes));
261 cpi->DCTDataBuffer =
262 _ogg_malloc(64*
263 sizeof(*cpi->DCTDataBuffer));
264 cpi->quantized_list =
265 _ogg_malloc(64*
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;
284 if(cpi->yuv0ptr)
285 _ogg_free(cpi->yuv0ptr);
286 cpi->yuv0ptr = 0;
288 if(cpi->yuv1ptr)
289 _ogg_free(cpi->yuv1ptr);
290 cpi->yuv1ptr = 0;
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));
320 cpi->yuv0ptr =
321 _ogg_malloc(FrameSize*
322 sizeof(*cpi->yuv0ptr));
323 cpi->yuv1ptr =
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
342 as well. */
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) {
356 ogg_uint32_t i;
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];
374 } else {
375 cpi->PriorKeyFrameSize[KEY_FRAME_CONTEXT - 1] =
376 oggpackB_bytes(cpi->oggbuffer);
377 cpi->PriorKeyFrameDistance[KEY_FRAME_CONTEXT - 1] =
378 cpi->LastKeyFrame;
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 ) );
401 } else {
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. */
443 EncodeData(cpi);
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);
451 }else{
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;
467 else
468 cpi->DropFrameCandidate = 0;
469 } else {
470 if ( cpi->DropFrameTriggerBytes >
471 (cpi->frame_target_rate * ((DF_CANDIDATE_WINDOW*2)-2)) )
472 cpi->DropFrameCandidate = 1;
473 else
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;
490 else
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;
501 else
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);
514 } else {
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) {
523 ogg_uint32_t i;
525 /* set up context of key frame sizes and distances for more local
526 datarate control */
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. */
539 cpi->DropCount = 0;
541 SetupKeyFrame(cpi);
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);
556 }else
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. */
564 cpi->DropCount = 0;
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. */
589 PickIntra( cpi,
590 cpi->pb.YSBRows, cpi->pb.YSBCols);
591 UpdateFrame(cpi);
593 /* Initialise the carry over rate targeting variables. */
594 cpi->CarryOver = 0;
598 static void CompressKeyFrame(CP_INSTANCE *cpi){
599 ogg_uint32_t i;
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. */
610 cpi->DropCount = 0;
612 SetupKeyFrame(cpi);
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. */
639 PickIntra( cpi,
640 cpi->pb.YSBRows, cpi->pb.YSBCols);
641 UpdateFrame(cpi);
645 static void CompressFrame( CP_INSTANCE *cpi) {
646 ogg_int32_t min_blocks_per_frame;
647 ogg_uint32_t i;
648 int DropFrame = 0;
649 ogg_uint32_t ResidueBlocksAdded=0;
650 ogg_uint32_t KFIndicator = 0;
652 double QModStep;
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;
695 else
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
707 best Q */
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) &&
724 ( cpi->CarryOver <
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
728 the next frame) */
729 cpi->CarryOver += cpi->frame_target_rate;
730 DropFrame = 1;
731 cpi->DropCount ++;
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. */
740 cpi->LastKeyFrame++;
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)/
754 ((ogg_int32_t)cpi->
755 Configuration.TargetBandwidth)) * 0.0175) ));
758 if ( !DropFrame ) {
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
801 extra blocks */
802 if ( cpi->MotionScore < min_blocks_per_frame ) {
803 min_blocks_per_frame =
804 cpi->MotionScore +
805 (ogg_int32_t)(((min_blocks_per_frame - cpi->MotionScore) * 4) / 3 );
806 UpRegulateDataStream( cpi, VERY_BEST_Q, min_blocks_per_frame );
807 }else{
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
816 projected bitrate */
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,
836 cpi->pb.info.width,
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 */
848 return;
853 /* Increment the frames since last key frame count */
854 cpi->LastKeyFrame++;
856 /* Proceed with the frame update. */
857 UpdateFrame(cpi);
858 cpi->DropCount = 0;
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;
869 }else{
870 /* even if we 'drop' a frame, a placeholder must be written as we
871 currently assume fixed frame rate timebase as Ogg mapping
872 invariant */
873 UpdateFrame(cpi);
877 /********************** The toplevel: encode ***********************/
879 static int _ilog(unsigned int v){
880 int ret=0;
881 while(v){
882 ret++;
883 v>>=1;
885 return(ret);
888 static void theora_encode_dispatch_init(CP_INSTANCE *cpi);
890 int theora_encode_init(theora_state *th, theora_info *c){
891 int i;
893 CP_INSTANCE *cpi;
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;
930 cpi->MVEnabled = 1;
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;
962 /* copy in config */
963 memcpy(&cpi->pb.info,c,sizeof(*c));
964 th->i=&cpi->pb.info;
965 th->granulepos=-1;
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 *
987 c->fps_denominator /
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);
996 EInitFrameInfo(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
1025 loop last time. */
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
1034 current clip. */
1035 cpi->ThisIsFirstFrame = 1;
1036 cpi->readyflag = 1;
1038 cpi->pb.HeadersWritten = 0;
1039 /*We overload this flag to track header output.*/
1040 cpi->doneflag=-3;
1042 return 0;
1045 int theora_encode_YUVin(theora_state *t,
1046 yuv_buffer *yuv){
1047 ogg_int32_t i;
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 )
1058 return(-1);
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 */
1083 LocalDataPtr =
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;
1098 } else {
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;
1109 } else {
1110 /* Compress the frame. */
1111 CompressFrame( cpi );
1116 /* Update stats variables. */
1117 cpi->LastFrameSize = oggpackB_bytes(cpi->oggbuffer);
1118 cpi->CurrentFrame++;
1119 cpi->packetflag=1;
1121 t->granulepos=
1122 ((cpi->CurrentFrame - cpi->LastKeyFrame)<<cpi->pb.keyframe_granule_shift)+
1123 cpi->LastKeyFrame - 1;
1125 return 0;
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);
1137 op->bytes=bytes;
1138 op->b_o_s=0;
1139 op->e_o_s=last_p;
1141 op->packetno=cpi->CurrentFrame;
1142 op->granulepos=t->granulepos;
1144 cpi->packetflag=0;
1145 if(last_p)cpi->doneflag=1;
1147 return 1;
1150 static void _tp_writebuffer(oggpack_buffer *opb, const char *buf, const long len)
1152 long i;
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);
1169 int offset_y;
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);
1209 op->b_o_s=1;
1210 op->e_o_s=0;
1212 op->packetno=0;
1214 op->granulepos=0;
1215 cpi->packetflag=0;
1217 return(0);
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);
1236 if(tc->comments){
1237 int i;
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]);
1242 }else{
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);
1254 _ogg_free(opb);
1256 op->b_o_s=0;
1257 op->e_o_s=0;
1259 op->packetno=0;
1260 op->granulepos=0;
1262 return (0);
1265 /* build the final header packet with the tables required
1266 for decode */
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);
1280 op->b_o_s=0;
1281 op->e_o_s=0;
1283 op->packetno=0;
1285 op->granulepos=0;
1286 cpi->packetflag=0;
1288 cpi->pb.HeadersWritten = 1;
1290 return(0);
1293 static void theora_encode_clear (theora_state *th){
1294 CP_INSTANCE *cpi;
1295 cpi=(CP_INSTANCE *)th->internal_encode;
1296 if(cpi){
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);
1308 _ogg_free(cpi);
1311 memset(th,0,sizeof(*th));
1315 /* returns, in seconds, absolute time of current packet in given
1316 logical stream */
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;
1325 if(granulepos>=0){
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);
1333 #endif
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;
1346 if(granulepos>=0){
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);
1353 return(-1);
1357 static int theora_encode_control(theora_state *th,int req,
1358 void *buf,size_t buf_sz) {
1359 CP_INSTANCE *cpi;
1360 PB_INSTANCE *pbi;
1361 int value;
1363 if(th == NULL)
1364 return TH_EFAULT;
1366 cpi = th->internal_encode;
1367 pbi = &cpi->pb;
1369 switch(req) {
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 ){
1374 return TH_EINVAL;
1377 if(buf==NULL)buf=&TH_VP31_QUANT_INFO;
1378 memcpy(&pbi->quant_info, buf, sizeof(th_quant_info));
1379 InitQTables(pbi);
1381 return 0;
1382 case TH_ENCCTL_SET_VP3_COMPATIBLE:
1383 if(cpi->pb.HeadersWritten)
1384 return TH_EINVAL;
1386 memcpy(&pbi->quant_info, &TH_VP31_QUANT_INFO, sizeof(th_quant_info));
1387 InitQTables(pbi);
1389 return 0;
1390 case TH_ENCCTL_SET_SPLEVEL:
1391 if(buf == NULL || buf_sz != sizeof(int))
1392 return TH_EINVAL;
1394 memcpy(&value, buf, sizeof(int));
1396 switch(value) {
1397 case 0:
1398 cpi->MotionCompensation = 1;
1399 pbi->info.quick_p = 0;
1400 break;
1402 case 1:
1403 cpi->MotionCompensation = 1;
1404 pbi->info.quick_p = 1;
1405 break;
1407 case 2:
1408 cpi->MotionCompensation = 0;
1409 pbi->info.quick_p = 1;
1410 break;
1412 default:
1413 return TH_EINVAL;
1416 return 0;
1417 case TH_ENCCTL_GET_SPLEVEL_MAX:
1418 value = 2;
1419 memcpy(buf, &value, sizeof(int));
1420 return 0;
1421 default:
1422 return TH_EIMPL;
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;