Add an API wrapper to the encoder to export the new theora-exp API.
[xiph/unicode.git] / theora / lib / enc / encoder_toplevel.c
blobbf223fb459babf1b847c828b79783faf255a51df
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 #ifdef _TH_DEBUG_
30 FILE *debugout=NULL;
31 long dframe=0;
32 #endif
34 #define A_TABLE_SIZE 29
35 #define DF_CANDIDATE_WINDOW 5
38 * th_quant_info for VP3
41 /*The default quantization parameters used by VP3.1.*/
42 static const int OC_VP31_RANGE_SIZES[1]={63};
43 static const th_quant_base OC_VP31_BASES_INTRA_Y[2]={
45 16, 11, 10, 16, 24, 40, 51, 61,
46 12, 12, 14, 19, 26, 58, 60, 55,
47 14, 13, 16, 24, 40, 57, 69, 56,
48 14, 17, 22, 29, 51, 87, 80, 62,
49 18, 22, 37, 58, 68, 109,103, 77,
50 24, 35, 55, 64, 81, 104,113, 92,
51 49, 64, 78, 87,103, 121,120,101,
52 72, 92, 95, 98,112, 100,103, 99
55 16, 11, 10, 16, 24, 40, 51, 61,
56 12, 12, 14, 19, 26, 58, 60, 55,
57 14, 13, 16, 24, 40, 57, 69, 56,
58 14, 17, 22, 29, 51, 87, 80, 62,
59 18, 22, 37, 58, 68, 109,103, 77,
60 24, 35, 55, 64, 81, 104,113, 92,
61 49, 64, 78, 87,103, 121,120,101,
62 72, 92, 95, 98,112, 100,103, 99
65 static const th_quant_base OC_VP31_BASES_INTRA_C[2]={
67 17, 18, 24, 47, 99, 99, 99, 99,
68 18, 21, 26, 66, 99, 99, 99, 99,
69 24, 26, 56, 99, 99, 99, 99, 99,
70 47, 66, 99, 99, 99, 99, 99, 99,
71 99, 99, 99, 99, 99, 99, 99, 99,
72 99, 99, 99, 99, 99, 99, 99, 99,
73 99, 99, 99, 99, 99, 99, 99, 99,
74 99, 99, 99, 99, 99, 99, 99, 99
77 17, 18, 24, 47, 99, 99, 99, 99,
78 18, 21, 26, 66, 99, 99, 99, 99,
79 24, 26, 56, 99, 99, 99, 99, 99,
80 47, 66, 99, 99, 99, 99, 99, 99,
81 99, 99, 99, 99, 99, 99, 99, 99,
82 99, 99, 99, 99, 99, 99, 99, 99,
83 99, 99, 99, 99, 99, 99, 99, 99,
84 99, 99, 99, 99, 99, 99, 99, 99
87 static const th_quant_base OC_VP31_BASES_INTER[2]={
89 16, 16, 16, 20, 24, 28, 32, 40,
90 16, 16, 20, 24, 28, 32, 40, 48,
91 16, 20, 24, 28, 32, 40, 48, 64,
92 20, 24, 28, 32, 40, 48, 64, 64,
93 24, 28, 32, 40, 48, 64, 64, 64,
94 28, 32, 40, 48, 64, 64, 64, 96,
95 32, 40, 48, 64, 64, 64, 96,128,
96 40, 48, 64, 64, 64, 96,128,128
99 16, 16, 16, 20, 24, 28, 32, 40,
100 16, 16, 20, 24, 28, 32, 40, 48,
101 16, 20, 24, 28, 32, 40, 48, 64,
102 20, 24, 28, 32, 40, 48, 64, 64,
103 24, 28, 32, 40, 48, 64, 64, 64,
104 28, 32, 40, 48, 64, 64, 64, 96,
105 32, 40, 48, 64, 64, 64, 96,128,
106 40, 48, 64, 64, 64, 96,128,128
110 const th_quant_info TH_VP31_QUANT_INFO={
112 220,200,190,180,170,170,160,160,
113 150,150,140,140,130,130,120,120,
114 110,110,100,100, 90, 90, 90, 80,
115 80, 80, 70, 70, 70, 60, 60, 60,
116 60, 50, 50, 50, 50, 40, 40, 40,
117 40, 40, 30, 30, 30, 30, 30, 30,
118 30, 20, 20, 20, 20, 20, 20, 20,
119 20, 10, 10, 10, 10, 10, 10, 10
122 500,450,400,370,340,310,285,265,
123 245,225,210,195,185,180,170,160,
124 150,145,135,130,125,115,110,107,
125 100, 96, 93, 89, 85, 82, 75, 74,
126 70, 68, 64, 60, 57, 56, 52, 50,
127 49, 45, 44, 43, 40, 38, 37, 35,
128 33, 32, 30, 29, 28, 25, 24, 22,
129 21, 19, 18, 17, 15, 13, 12, 10
132 30,25,20,20,15,15,14,14,
133 13,13,12,12,11,11,10,10,
134 9, 9, 8, 8, 7, 7, 7, 7,
135 6, 6, 6, 6, 5, 5, 5, 5,
136 4, 4, 4, 4, 3, 3, 3, 3,
137 2, 2, 2, 2, 2, 2, 2, 2,
138 0, 0, 0, 0, 0, 0, 0, 0,
139 0, 0, 0, 0, 0, 0, 0, 0
143 {1,OC_VP31_RANGE_SIZES,OC_VP31_BASES_INTRA_Y},
144 {1,OC_VP31_RANGE_SIZES,OC_VP31_BASES_INTRA_C},
145 {1,OC_VP31_RANGE_SIZES,OC_VP31_BASES_INTRA_C}
148 {1,OC_VP31_RANGE_SIZES,OC_VP31_BASES_INTER},
149 {1,OC_VP31_RANGE_SIZES,OC_VP31_BASES_INTER},
150 {1,OC_VP31_RANGE_SIZES,OC_VP31_BASES_INTER}
156 static void EClearFragmentInfo(CP_INSTANCE * cpi){
157 if(cpi->extra_fragments)
158 _ogg_free(cpi->extra_fragments);
159 if(cpi->FragmentLastQ)
160 _ogg_free(cpi->FragmentLastQ);
161 if(cpi->FragTokens)
162 _ogg_free(cpi->FragTokens);
163 if(cpi->FragTokenCounts)
164 _ogg_free(cpi->FragTokenCounts);
165 if(cpi->RunHuffIndices)
166 _ogg_free(cpi->RunHuffIndices);
167 if(cpi->LastCodedErrorScore)
168 _ogg_free(cpi->LastCodedErrorScore);
169 if(cpi->ModeList)
170 _ogg_free(cpi->ModeList);
171 if(cpi->MVList)
172 _ogg_free(cpi->MVList);
173 if(cpi->DCT_codes )
174 _ogg_free( cpi->DCT_codes );
175 if(cpi->DCTDataBuffer )
176 _ogg_free( cpi->DCTDataBuffer);
177 if(cpi->quantized_list)
178 _ogg_free( cpi->quantized_list);
179 if(cpi->OriginalDC)
180 _ogg_free( cpi->OriginalDC);
181 if(cpi->PartiallyCodedFlags)
182 _ogg_free(cpi->PartiallyCodedFlags);
183 if(cpi->PartiallyCodedMbPatterns)
184 _ogg_free(cpi->PartiallyCodedMbPatterns);
185 if(cpi->UncodedMbFlags)
186 _ogg_free(cpi->UncodedMbFlags);
188 if(cpi->BlockCodedFlags)
189 _ogg_free(cpi->BlockCodedFlags);
191 cpi->extra_fragments = 0;
192 cpi->FragmentLastQ = 0;
193 cpi->FragTokens = 0;
194 cpi->FragTokenCounts = 0;
195 cpi->RunHuffIndices = 0;
196 cpi->LastCodedErrorScore = 0;
197 cpi->ModeList = 0;
198 cpi->MVList = 0;
199 cpi->DCT_codes = 0;
200 cpi->DCTDataBuffer = 0;
201 cpi->quantized_list = 0;
202 cpi->OriginalDC = 0;
203 cpi->BlockCodedFlags = 0;
206 static void EInitFragmentInfo(CP_INSTANCE * cpi){
208 /* clear any existing info */
209 EClearFragmentInfo(cpi);
211 /* Perform Fragment Allocations */
212 cpi->extra_fragments =
213 _ogg_malloc(cpi->pb.UnitFragments*sizeof(unsigned char));
215 /* A note to people reading and wondering why malloc returns aren't
216 checked:
218 lines like the following that implement a general strategy of
219 'check the return of malloc; a zero pointer means we're out of
220 memory!'...:
222 if(!cpi->extra_fragments) { EDeleteFragmentInfo(cpi); return FALSE; }
224 ...are not useful. It's true that many platforms follow this
225 malloc behavior, but many do not. The more modern malloc
226 strategy is only to allocate virtual pages, which are not mapped
227 until the memory on that page is touched. At *that* point, if
228 the machine is out of heap, the page fails to be mapped and a
229 SEGV is generated.
231 That means that if we want to deal with out of memory conditions,
232 we *must* be prepared to process a SEGV. If we implement the
233 SEGV handler, there's no reason to to check malloc return; it is
234 a waste of code. */
236 cpi->FragmentLastQ =
237 _ogg_malloc(cpi->pb.UnitFragments*
238 sizeof(*cpi->FragmentLastQ));
239 cpi->FragTokens =
240 _ogg_malloc(cpi->pb.UnitFragments*
241 sizeof(*cpi->FragTokens));
242 cpi->OriginalDC =
243 _ogg_malloc(cpi->pb.UnitFragments*
244 sizeof(*cpi->OriginalDC));
245 cpi->FragTokenCounts =
246 _ogg_malloc(cpi->pb.UnitFragments*
247 sizeof(*cpi->FragTokenCounts));
248 cpi->RunHuffIndices =
249 _ogg_malloc(cpi->pb.UnitFragments*
250 sizeof(*cpi->RunHuffIndices));
251 cpi->LastCodedErrorScore =
252 _ogg_malloc(cpi->pb.UnitFragments*
253 sizeof(*cpi->LastCodedErrorScore));
254 cpi->BlockCodedFlags =
255 _ogg_malloc(cpi->pb.UnitFragments*
256 sizeof(*cpi->BlockCodedFlags));
257 cpi->ModeList =
258 _ogg_malloc(cpi->pb.UnitFragments*
259 sizeof(*cpi->ModeList));
260 cpi->MVList =
261 _ogg_malloc(cpi->pb.UnitFragments*
262 sizeof(*cpi->MVList));
263 cpi->DCT_codes =
264 _ogg_malloc(64*
265 sizeof(*cpi->DCT_codes));
266 cpi->DCTDataBuffer =
267 _ogg_malloc(64*
268 sizeof(*cpi->DCTDataBuffer));
269 cpi->quantized_list =
270 _ogg_malloc(64*
271 sizeof(*cpi->quantized_list));
272 cpi->PartiallyCodedFlags =
273 _ogg_malloc(cpi->pb.MacroBlocks*
274 sizeof(*cpi->PartiallyCodedFlags));
275 cpi->PartiallyCodedMbPatterns =
276 _ogg_malloc(cpi->pb.MacroBlocks*
277 sizeof(*cpi->PartiallyCodedMbPatterns));
278 cpi->UncodedMbFlags =
279 _ogg_malloc(cpi->pb.MacroBlocks*
280 sizeof(*cpi->UncodedMbFlags));
284 static void EClearFrameInfo(CP_INSTANCE * cpi) {
285 if(cpi->ConvDestBuffer )
286 _ogg_free(cpi->ConvDestBuffer );
287 cpi->ConvDestBuffer = 0;
289 if(cpi->yuv0ptr)
290 _ogg_free(cpi->yuv0ptr);
291 cpi->yuv0ptr = 0;
293 if(cpi->yuv1ptr)
294 _ogg_free(cpi->yuv1ptr);
295 cpi->yuv1ptr = 0;
297 if(cpi->OptimisedTokenListEb )
298 _ogg_free(cpi->OptimisedTokenListEb);
299 cpi->OptimisedTokenListEb = 0;
301 if(cpi->OptimisedTokenList )
302 _ogg_free(cpi->OptimisedTokenList);
303 cpi->OptimisedTokenList = 0;
305 if(cpi->OptimisedTokenListHi )
306 _ogg_free(cpi->OptimisedTokenListHi);
307 cpi->OptimisedTokenListHi = 0;
309 if(cpi->OptimisedTokenListPl )
310 _ogg_free(cpi->OptimisedTokenListPl);
311 cpi->OptimisedTokenListPl = 0;
315 static void EInitFrameInfo(CP_INSTANCE * cpi){
316 int FrameSize = cpi->pb.ReconYPlaneSize + 2 * cpi->pb.ReconUVPlaneSize;
318 /* clear any existing info */
319 EClearFrameInfo(cpi);
321 /* allocate frames */
322 cpi->ConvDestBuffer =
323 _ogg_malloc(FrameSize*
324 sizeof(*cpi->ConvDestBuffer));
325 cpi->yuv0ptr =
326 _ogg_malloc(FrameSize*
327 sizeof(*cpi->yuv0ptr));
328 cpi->yuv1ptr =
329 _ogg_malloc(FrameSize*
330 sizeof(*cpi->yuv1ptr));
331 cpi->OptimisedTokenListEb =
332 _ogg_malloc(FrameSize*
333 sizeof(*cpi->OptimisedTokenListEb));
334 cpi->OptimisedTokenList =
335 _ogg_malloc(FrameSize*
336 sizeof(*cpi->OptimisedTokenList));
337 cpi->OptimisedTokenListHi =
338 _ogg_malloc(FrameSize*
339 sizeof(*cpi->OptimisedTokenListHi));
340 cpi->OptimisedTokenListPl =
341 _ogg_malloc(FrameSize*
342 sizeof(*cpi->OptimisedTokenListPl));
345 static void SetupKeyFrame(CP_INSTANCE *cpi) {
346 /* Make sure the "last frame" buffer contains the first frame data
347 as well. */
348 memcpy ( cpi->yuv0ptr, cpi->yuv1ptr,
349 cpi->pb.ReconYPlaneSize + 2 * cpi->pb.ReconUVPlaneSize );
351 /* Initialise the cpi->pb.display_fragments and other fragment
352 structures for the first frame. */
353 memset( cpi->pb.display_fragments, 1, cpi->pb.UnitFragments );
354 memset( cpi->extra_fragments, 1, cpi->pb.UnitFragments );
356 /* Set up for a KEY FRAME */
357 cpi->pb.FrameType = KEY_FRAME;
360 static void AdjustKeyFrameContext(CP_INSTANCE *cpi) {
361 ogg_uint32_t i;
362 ogg_uint32_t AvKeyFrameFrequency =
363 (ogg_uint32_t) (cpi->CurrentFrame / cpi->KeyFrameCount);
364 ogg_uint32_t AvKeyFrameBytes =
365 (ogg_uint32_t) (cpi->TotKeyFrameBytes / cpi->KeyFrameCount);
366 ogg_uint32_t TotalWeight=0;
367 ogg_int32_t AvKeyFramesPerSecond;
368 ogg_int32_t MinFrameTargetRate;
370 /* Update the frame carry over. */
371 cpi->TotKeyFrameBytes += oggpackB_bytes(cpi->oggbuffer);
373 /* reset keyframe context and calculate weighted average of last
374 KEY_FRAME_CONTEXT keyframes */
375 for( i = 0 ; i < KEY_FRAME_CONTEXT ; i ++ ) {
376 if ( i < KEY_FRAME_CONTEXT -1) {
377 cpi->PriorKeyFrameSize[i] = cpi->PriorKeyFrameSize[i+1];
378 cpi->PriorKeyFrameDistance[i] = cpi->PriorKeyFrameDistance[i+1];
379 } else {
380 cpi->PriorKeyFrameSize[KEY_FRAME_CONTEXT - 1] =
381 oggpackB_bytes(cpi->oggbuffer);
382 cpi->PriorKeyFrameDistance[KEY_FRAME_CONTEXT - 1] =
383 cpi->LastKeyFrame;
386 AvKeyFrameBytes += PriorKeyFrameWeight[i] *
387 cpi->PriorKeyFrameSize[i];
388 AvKeyFrameFrequency += PriorKeyFrameWeight[i] *
389 cpi->PriorKeyFrameDistance[i];
390 TotalWeight += PriorKeyFrameWeight[i];
392 AvKeyFrameBytes /= TotalWeight;
393 AvKeyFrameFrequency /= TotalWeight;
394 AvKeyFramesPerSecond = 100 * cpi->Configuration.OutputFrameRate /
395 AvKeyFrameFrequency ;
397 /* Calculate a new target rate per frame allowing for average key
398 frame frequency over newest frames . */
399 if ( 100 * cpi->Configuration.TargetBandwidth >
400 AvKeyFrameBytes * AvKeyFramesPerSecond &&
401 (100 * cpi->Configuration.OutputFrameRate - AvKeyFramesPerSecond )){
402 cpi->frame_target_rate =
403 (ogg_int32_t)(100* cpi->Configuration.TargetBandwidth -
404 AvKeyFrameBytes * AvKeyFramesPerSecond ) /
405 ( (100 * cpi->Configuration.OutputFrameRate - AvKeyFramesPerSecond ) );
406 } else {
407 /* don't let this number get too small!!! */
408 cpi->frame_target_rate = 1;
411 /* minimum allowable frame_target_rate */
412 MinFrameTargetRate = (cpi->Configuration.TargetBandwidth /
413 cpi->Configuration.OutputFrameRate) / 3;
415 if(cpi->frame_target_rate < MinFrameTargetRate ) {
416 cpi->frame_target_rate = MinFrameTargetRate;
419 cpi->LastKeyFrame = 1;
420 cpi->LastKeyFrameSize=oggpackB_bytes(cpi->oggbuffer);
424 static void UpdateFrame(CP_INSTANCE *cpi){
426 double CorrectionFactor;
428 /* Reset the DC predictors. */
429 cpi->pb.LastIntraDC = 0;
430 cpi->pb.InvLastIntraDC = 0;
431 cpi->pb.LastInterDC = 0;
432 cpi->pb.InvLastInterDC = 0;
434 /* Initialise bit packing mechanism. */
435 #ifndef LIBOGG2
436 oggpackB_reset(cpi->oggbuffer);
437 #else
438 oggpackB_writeinit(cpi->oggbuffer, cpi->oggbufferstate);
439 #endif
440 /* mark as video frame */
441 oggpackB_write(cpi->oggbuffer,0,1);
443 /* Write out the frame header information including size. */
444 WriteFrameHeader(cpi);
446 /* Copy back any extra frags that are to be updated by the codec
447 as part of the background cleanup task */
448 CopyBackExtraFrags(cpi);
450 /* Encode the data. */
451 EncodeData(cpi);
453 /* Adjust drop frame trigger. */
454 if ( cpi->pb.FrameType != KEY_FRAME ) {
455 /* Apply decay factor then add in the last frame size. */
456 cpi->DropFrameTriggerBytes =
457 ((cpi->DropFrameTriggerBytes * (DF_CANDIDATE_WINDOW-1)) /
458 DF_CANDIDATE_WINDOW) + oggpackB_bytes(cpi->oggbuffer);
459 }else{
460 /* Increase cpi->DropFrameTriggerBytes a little. Just after a key
461 frame may actually be a good time to drop a frame. */
462 cpi->DropFrameTriggerBytes =
463 (cpi->DropFrameTriggerBytes * DF_CANDIDATE_WINDOW) /
464 (DF_CANDIDATE_WINDOW-1);
467 /* Test for overshoot which may require a dropped frame next time
468 around. If we are already in a drop frame condition but the
469 previous frame was not dropped then the threshold for continuing
470 to allow dropped frames is reduced. */
471 if ( cpi->DropFrameCandidate ) {
472 if ( cpi->DropFrameTriggerBytes >
473 (cpi->frame_target_rate * (DF_CANDIDATE_WINDOW+1)) )
474 cpi->DropFrameCandidate = 1;
475 else
476 cpi->DropFrameCandidate = 0;
477 } else {
478 if ( cpi->DropFrameTriggerBytes >
479 (cpi->frame_target_rate * ((DF_CANDIDATE_WINDOW*2)-2)) )
480 cpi->DropFrameCandidate = 1;
481 else
482 cpi->DropFrameCandidate = 0;
485 /* Update the BpbCorrectionFactor variable according to whether or
486 not we were close enough with our selection of DCT quantiser. */
487 if ( cpi->pb.FrameType != KEY_FRAME ) {
488 /* Work out a size correction factor. */
489 CorrectionFactor = (double)oggpackB_bytes(cpi->oggbuffer) /
490 (double)cpi->ThisFrameTargetBytes;
492 if ( (CorrectionFactor > 1.05) &&
493 (cpi->pb.ThisFrameQualityValue <
494 cpi->pb.QThreshTable[cpi->Configuration.ActiveMaxQ]) ) {
495 CorrectionFactor = 1.0 + ((CorrectionFactor - 1.0)/2);
496 if ( CorrectionFactor > 1.5 )
497 cpi->BpbCorrectionFactor *= 1.5;
498 else
499 cpi->BpbCorrectionFactor *= CorrectionFactor;
501 /* Keep BpbCorrectionFactor within limits */
502 if ( cpi->BpbCorrectionFactor > MAX_BPB_FACTOR )
503 cpi->BpbCorrectionFactor = MAX_BPB_FACTOR;
504 } else if ( (CorrectionFactor < 0.95) &&
505 (cpi->pb.ThisFrameQualityValue > VERY_BEST_Q) ){
506 CorrectionFactor = 1.0 - ((1.0 - CorrectionFactor)/2);
507 if ( CorrectionFactor < 0.75 )
508 cpi->BpbCorrectionFactor *= 0.75;
509 else
510 cpi->BpbCorrectionFactor *= CorrectionFactor;
512 /* Keep BpbCorrectionFactor within limits */
513 if ( cpi->BpbCorrectionFactor < MIN_BPB_FACTOR )
514 cpi->BpbCorrectionFactor = MIN_BPB_FACTOR;
518 /* Adjust carry over and or key frame context. */
519 if ( cpi->pb.FrameType == KEY_FRAME ) {
520 /* Adjust the key frame context unless the key frame was very small */
521 AdjustKeyFrameContext(cpi);
522 } else {
523 /* Update the frame carry over */
524 cpi->CarryOver += ((ogg_int32_t)cpi->frame_target_rate -
525 (ogg_int32_t)oggpackB_bytes(cpi->oggbuffer));
527 cpi->TotalByteCount += oggpackB_bytes(cpi->oggbuffer);
530 static void CompressFirstFrame(CP_INSTANCE *cpi) {
531 ogg_uint32_t i;
533 /* set up context of key frame sizes and distances for more local
534 datarate control */
535 for( i = 0 ; i < KEY_FRAME_CONTEXT ; i ++ ) {
536 cpi->PriorKeyFrameSize[i] = cpi->Configuration.KeyFrameDataTarget;
537 cpi->PriorKeyFrameDistance[i] = cpi->pb.info.keyframe_frequency_force;
540 /* Keep track of the total number of Key Frames Coded. */
541 cpi->KeyFrameCount = 1;
542 cpi->LastKeyFrame = 1;
543 cpi->TotKeyFrameBytes = 0;
545 /* A key frame is not a dropped frame there for reset the count of
546 consequative dropped frames. */
547 cpi->DropCount = 0;
549 SetupKeyFrame(cpi);
551 /* Calculate a new target rate per frame allowing for average key
552 frame frequency and size thus far. */
553 if ( cpi->Configuration.TargetBandwidth >
554 ((cpi->Configuration.KeyFrameDataTarget *
555 cpi->Configuration.OutputFrameRate)/
556 cpi->pb.info.keyframe_frequency) ) {
558 cpi->frame_target_rate =
559 (ogg_int32_t)((cpi->Configuration.TargetBandwidth -
560 ((cpi->Configuration.KeyFrameDataTarget *
561 cpi->Configuration.OutputFrameRate)/
562 cpi->pb.info.keyframe_frequency)) /
563 cpi->Configuration.OutputFrameRate);
564 }else
565 cpi->frame_target_rate = 1;
567 /* Set baseline frame target rate. */
568 cpi->BaseLineFrameTargetRate = cpi->frame_target_rate;
570 /* A key frame is not a dropped frame there for reset the count of
571 consequative dropped frames. */
572 cpi->DropCount = 0;
574 /* Initialise drop frame trigger to 5 frames worth of data. */
575 cpi->DropFrameTriggerBytes = cpi->frame_target_rate * DF_CANDIDATE_WINDOW;
577 /* Set a target size for this key frame based upon the baseline
578 target and frequency */
579 cpi->ThisFrameTargetBytes = cpi->Configuration.KeyFrameDataTarget;
581 /* Get a DCT quantizer level for the key frame. */
582 cpi->MotionScore = cpi->pb.UnitFragments;
584 RegulateQ(cpi, cpi->pb.UnitFragments);
586 cpi->pb.LastFrameQualityValue = cpi->pb.ThisFrameQualityValue;
588 /* Initialise quantizer. */
589 UpdateQC(cpi, cpi->pb.ThisFrameQualityValue );
591 /* Initialise the cpi->pb.display_fragments and other fragment
592 structures for the first frame. */
593 for ( i = 0; i < cpi->pb.UnitFragments; i ++ )
594 cpi->FragmentLastQ[i] = cpi->pb.ThisFrameQualityValue;
596 /* Compress and output the frist frame. */
597 PickIntra( cpi,
598 cpi->pb.YSBRows, cpi->pb.YSBCols);
599 UpdateFrame(cpi);
601 /* Initialise the carry over rate targeting variables. */
602 cpi->CarryOver = 0;
606 static void CompressKeyFrame(CP_INSTANCE *cpi){
607 ogg_uint32_t i;
609 /* Before we compress reset the carry over to the actual frame carry over */
610 cpi->CarryOver = cpi->Configuration.TargetBandwidth * cpi->CurrentFrame /
611 cpi->Configuration.OutputFrameRate - cpi->TotalByteCount;
613 /* Keep track of the total number of Key Frames Coded */
614 cpi->KeyFrameCount += 1;
616 /* A key frame is not a dropped frame there for reset the count of
617 consequative dropped frames. */
618 cpi->DropCount = 0;
620 SetupKeyFrame(cpi);
622 /* set a target size for this frame */
623 cpi->ThisFrameTargetBytes = (ogg_int32_t) cpi->frame_target_rate +
624 ( (cpi->Configuration.KeyFrameDataTarget - cpi->frame_target_rate) *
625 cpi->LastKeyFrame / cpi->pb.info.keyframe_frequency_force );
627 if ( cpi->ThisFrameTargetBytes > cpi->Configuration.KeyFrameDataTarget )
628 cpi->ThisFrameTargetBytes = cpi->Configuration.KeyFrameDataTarget;
630 /* Get a DCT quantizer level for the key frame. */
631 cpi->MotionScore = cpi->pb.UnitFragments;
633 RegulateQ(cpi, cpi->pb.UnitFragments);
635 cpi->pb.LastFrameQualityValue = cpi->pb.ThisFrameQualityValue;
637 /* Initialise DCT tables. */
638 UpdateQC(cpi, cpi->pb.ThisFrameQualityValue );
640 /* Initialise the cpi->pb.display_fragments and other fragment
641 structures for the first frame. */
642 for ( i = 0; i < cpi->pb.UnitFragments; i ++ )
643 cpi->FragmentLastQ[i] = cpi->pb.ThisFrameQualityValue;
646 /* Compress and output the frist frame. */
647 PickIntra( cpi,
648 cpi->pb.YSBRows, cpi->pb.YSBCols);
649 UpdateFrame(cpi);
653 static void CompressFrame( CP_INSTANCE *cpi) {
654 ogg_int32_t min_blocks_per_frame;
655 ogg_uint32_t i;
656 int DropFrame = 0;
657 ogg_uint32_t ResidueBlocksAdded=0;
658 ogg_uint32_t KFIndicator = 0;
660 double QModStep;
661 double QModifier = 1.0;
663 /* Clear down the macro block level mode and MV arrays. */
664 for ( i = 0; i < cpi->pb.UnitFragments; i++ ) {
665 cpi->pb.FragCodingMethod[i] = CODE_INTER_NO_MV; /* Default coding mode */
666 cpi->pb.FragMVect[i].x = 0;
667 cpi->pb.FragMVect[i].y = 0;
670 /* Default to delta frames. */
671 cpi->pb.FrameType = DELTA_FRAME;
673 /* Clear down the difference arrays for the current frame. */
674 memset( cpi->pb.display_fragments, 0, cpi->pb.UnitFragments );
675 memset( cpi->extra_fragments, 0, cpi->pb.UnitFragments );
677 /* Calculate the target bytes for this frame. */
678 cpi->ThisFrameTargetBytes = cpi->frame_target_rate;
680 /* Correct target to try and compensate for any overall rate error
681 that is developing */
683 /* Set the max allowed Q for this frame based upon carry over
684 history. First set baseline worst Q for this frame */
685 cpi->Configuration.ActiveMaxQ = cpi->Configuration.MaxQ + 10;
686 if ( cpi->Configuration.ActiveMaxQ >= Q_TABLE_SIZE )
687 cpi->Configuration.ActiveMaxQ = Q_TABLE_SIZE - 1;
689 /* Make a further adjustment based upon the carry over and recent
690 history.. cpi->Configuration.ActiveMaxQ reduced by 1 for each 1/2
691 seconds worth of -ve carry over up to a limit of 6. Also
692 cpi->Configuration.ActiveMaxQ reduced if frame is a
693 "DropFrameCandidate". Remember that if we are behind the bit
694 target carry over is -ve. */
695 if ( cpi->CarryOver < 0 ) {
696 if ( cpi->DropFrameCandidate ) {
697 cpi->Configuration.ActiveMaxQ -= 4;
700 if ( cpi->CarryOver <
701 -((ogg_int32_t)cpi->Configuration.TargetBandwidth*3) )
702 cpi->Configuration.ActiveMaxQ -= 6;
703 else
704 cpi->Configuration.ActiveMaxQ +=
705 (ogg_int32_t) ((cpi->CarryOver*2) /
706 (ogg_int32_t)cpi->Configuration.TargetBandwidth);
708 /* Check that we have not dropped quality too far */
709 if ( cpi->Configuration.ActiveMaxQ < cpi->Configuration.MaxQ )
710 cpi->Configuration.ActiveMaxQ = cpi->Configuration.MaxQ;
713 /* Calculate the Q Modifier step size required to cause a step down
714 from full target bandwidth to 40% of target between max Q and
715 best Q */
716 QModStep = 0.5 / (double)((Q_TABLE_SIZE - 1) -
717 cpi->Configuration.ActiveMaxQ);
719 /* Set up the cpi->QTargetModifier[] table. */
720 for ( i = 0; i < cpi->Configuration.ActiveMaxQ; i++ ) {
721 cpi->QTargetModifier[i] = QModifier;
723 for ( i = cpi->Configuration.ActiveMaxQ; i < Q_TABLE_SIZE; i++ ) {
724 cpi->QTargetModifier[i] = QModifier;
725 QModifier -= QModStep;
728 /* if we are allowed to drop frames and are falling behind (eg more
729 than x frames worth of bandwidth) */
730 if ( cpi->pb.info.dropframes_p &&
731 ( cpi->DropCount < cpi->MaxConsDroppedFrames) &&
732 ( cpi->CarryOver <
733 -((ogg_int32_t)cpi->Configuration.TargetBandwidth)) &&
734 ( cpi->DropFrameCandidate) ) {
735 /* (we didn't do this frame so we should have some left over for
736 the next frame) */
737 cpi->CarryOver += cpi->frame_target_rate;
738 DropFrame = 1;
739 cpi->DropCount ++;
741 /* Adjust DropFrameTriggerBytes to account for the saving achieved. */
742 cpi->DropFrameTriggerBytes =
743 (cpi->DropFrameTriggerBytes *
744 (DF_CANDIDATE_WINDOW-1))/DF_CANDIDATE_WINDOW;
746 /* Even if we drop a frame we should account for it when
747 considering key frame seperation. */
748 cpi->LastKeyFrame++;
749 } else if ( cpi->CarryOver <
750 -((ogg_int32_t)cpi->Configuration.TargetBandwidth * 2) ) {
751 /* Reduce frame bit target by 1.75% for each 1/10th of a seconds
752 worth of -ve carry over down to a minimum of 65% of its
753 un-modified value. */
755 cpi->ThisFrameTargetBytes =
756 (ogg_uint32_t)(cpi->ThisFrameTargetBytes * 0.65);
757 } else if ( cpi->CarryOver < 0 ) {
758 /* Note that cpi->CarryOver is a -ve here hence 1.0 "+" ... */
759 cpi->ThisFrameTargetBytes =
760 (ogg_uint32_t)(cpi->ThisFrameTargetBytes *
761 (1.0 + ( ((cpi->CarryOver * 10)/
762 ((ogg_int32_t)cpi->
763 Configuration.TargetBandwidth)) * 0.0175) ));
766 if ( !DropFrame ) {
767 /* pick all the macroblock modes and motion vectors */
768 ogg_uint32_t InterError;
769 ogg_uint32_t IntraError;
772 /* Set Baseline filter level. */
773 ConfigurePP( &cpi->pp, cpi->pb.info.noise_sensitivity);
775 /* Score / analyses the fragments. */
776 cpi->MotionScore = YUVAnalyseFrame(&cpi->pp, &KFIndicator );
778 /* Get the baseline Q value */
779 RegulateQ( cpi, cpi->MotionScore );
781 /* Recode blocks if the error score in last frame was high. */
782 ResidueBlocksAdded = 0;
783 for ( i = 0; i < cpi->pb.UnitFragments; i++ ){
784 if ( !cpi->pb.display_fragments[i] ){
785 if ( cpi->LastCodedErrorScore[i] >=
786 ResidueErrorThresh[cpi->pb.FrameQIndex] ) {
787 cpi->pb.display_fragments[i] = 1; /* Force block update */
788 cpi->extra_fragments[i] = 1; /* Insures up to date
789 pixel data is used. */
790 ResidueBlocksAdded ++;
795 /* Adjust the motion score to allow for residue blocks
796 added. These are assumed to have below average impact on
797 bitrate (Hence ResidueBlockFactor). */
798 cpi->MotionScore = cpi->MotionScore +
799 (ResidueBlocksAdded / ResidueBlockFactor[cpi->pb.FrameQIndex]);
801 /* Estimate the min number of blocks at best Q */
802 min_blocks_per_frame =
803 (ogg_int32_t)(cpi->ThisFrameTargetBytes /
804 GetEstimatedBpb( cpi, VERY_BEST_Q ));
805 if ( min_blocks_per_frame == 0 )
806 min_blocks_per_frame = 1;
808 /* If we have less than this number then consider adding in some
809 extra blocks */
810 if ( cpi->MotionScore < min_blocks_per_frame ) {
811 min_blocks_per_frame =
812 cpi->MotionScore +
813 (ogg_int32_t)(((min_blocks_per_frame - cpi->MotionScore) * 4) / 3 );
814 UpRegulateDataStream( cpi, VERY_BEST_Q, min_blocks_per_frame );
815 }else{
816 /* Reset control variable for best quality final pass. */
817 cpi->FinalPassLastPos = 0;
820 /* Get the modified Q prediction taking into account extra blocks added. */
821 RegulateQ( cpi, cpi->MotionScore );
823 /* Unless we are already well ahead (4 seconds of data) of the
824 projected bitrate */
825 if ( cpi->CarryOver <
826 (ogg_int32_t)(cpi->Configuration.TargetBandwidth * 4) ){
827 /* Look at the predicted Q (pbi->FrameQIndex). Adjust the
828 target bits for this frame based upon projected Q and
829 re-calculate. The idea is that if the Q is better than a
830 given (good enough) level then we will try and save some bits
831 for use in more difficult segments. */
832 cpi->ThisFrameTargetBytes =
833 (ogg_int32_t) (cpi->ThisFrameTargetBytes *
834 cpi->QTargetModifier[cpi->pb.FrameQIndex]);
836 /* Recalculate Q again */
837 RegulateQ( cpi, cpi->MotionScore );
841 /* Select modes and motion vectors for each of the blocks : return
842 an error score for inter and intra */
843 PickModes( cpi, cpi->pb.YSBRows, cpi->pb.YSBCols,
844 cpi->pb.info.width,
845 &InterError, &IntraError );
847 /* decide whether we really should have made this frame a key frame */
848 /* forcing out a keyframe if the max interval is up is done at a higher level */
849 if( cpi->pb.info.keyframe_auto_p){
850 if( ( 2* IntraError < 5 * InterError )
851 && ( KFIndicator >= (ogg_uint32_t)
852 cpi->pb.info.keyframe_auto_threshold)
853 && ( cpi->LastKeyFrame > cpi->pb.info.keyframe_mindistance)
855 CompressKeyFrame(cpi); /* Code a key frame */
856 return;
861 /* Increment the frames since last key frame count */
862 cpi->LastKeyFrame++;
864 /* Proceed with the frame update. */
865 UpdateFrame(cpi);
866 cpi->DropCount = 0;
868 if ( cpi->MotionScore > 0 ){
869 /* Note the Quantizer used for each block coded. */
870 for ( i = 0; i < cpi->pb.UnitFragments; i++ ){
871 if ( cpi->pb.display_fragments[i] ){
872 cpi->FragmentLastQ[i] = cpi->pb.ThisFrameQualityValue;
877 }else{
878 /* even if we 'drop' a frame, a placeholder must be written as we
879 currently assume fixed frame rate timebase as Ogg mapping
880 invariant */
881 UpdateFrame(cpi);
885 /********************** The toplevel: encode ***********************/
887 static int _ilog(unsigned int v){
888 int ret=0;
889 while(v){
890 ret++;
891 v>>=1;
893 return(ret);
896 static void theora_encode_dispatch_init(CP_INSTANCE *cpi);
898 int theora_encode_init(theora_state *th, theora_info *c){
899 int i;
901 CP_INSTANCE *cpi;
903 #ifdef _TH_DEBUG_
904 debugout=fopen("theoraenc-debugout.txt","w");
905 #endif
907 memset(th, 0, sizeof(*th));
908 /*Currently only the 4:2:0 format is supported.*/
909 if(c->pixelformat!=OC_PF_420)return OC_IMPL;
910 th->internal_encode=cpi=_ogg_calloc(1,sizeof(*cpi));
911 theora_encode_dispatch_init(cpi);
913 dsp_static_init (&cpi->dsp);
914 memcpy (&cpi->pb.dsp, &cpi->dsp, sizeof(DspFunctions));
916 c->version_major=TH_VERSION_MAJOR;
917 c->version_minor=TH_VERSION_MINOR;
918 c->version_subminor=TH_VERSION_SUB;
920 InitTmpBuffers(&cpi->pb);
921 InitPPInstance(&cpi->pp, &cpi->dsp);
923 /* Initialise Configuration structure to legal values */
924 if(c->quality>63)c->quality=63;
925 if(c->quality<0)c->quality=32;
926 if(c->target_bitrate<0)c->target_bitrate=0;
927 /* we clamp target_bitrate to 24 bits after setting up the encoder */
929 cpi->Configuration.BaseQ = c->quality;
930 cpi->Configuration.FirstFrameQ = c->quality;
931 cpi->Configuration.MaxQ = c->quality;
932 cpi->Configuration.ActiveMaxQ = c->quality;
934 cpi->MVChangeFactor = 14;
935 cpi->FourMvChangeFactor = 8;
936 cpi->MinImprovementForNewMV = 25;
937 cpi->ExhaustiveSearchThresh = 2500;
938 cpi->MinImprovementForFourMV = 100;
939 cpi->FourMVThreshold = 10000;
940 cpi->BitRateCapFactor = 1.5;
941 cpi->InterTripOutThresh = 5000;
942 cpi->MVEnabled = 1;
943 cpi->InterCodeCount = 127;
944 cpi->BpbCorrectionFactor = 1.0;
945 cpi->GoldenFrameEnabled = 1;
946 cpi->InterPrediction = 1;
947 cpi->MotionCompensation = 1;
948 cpi->ThreshMapThreshold = 5;
949 cpi->MaxConsDroppedFrames = 1;
951 /* Set encoder flags. */
952 /* if not AutoKeyframing cpi->ForceKeyFrameEvery = is frequency */
953 if(!c->keyframe_auto_p)
954 c->keyframe_frequency_force = c->keyframe_frequency;
956 /* Set the frame rate variables. */
957 if ( c->fps_numerator < 1 )
958 c->fps_numerator = 1;
959 if ( c->fps_denominator < 1 )
960 c->fps_denominator = 1;
962 /* don't go too nuts on keyframe spacing; impose a high limit to
963 make certain the granulepos encoding strategy works */
964 if(c->keyframe_frequency_force>32768)c->keyframe_frequency_force=32768;
965 if(c->keyframe_mindistance>32768)c->keyframe_mindistance=32768;
966 if(c->keyframe_mindistance>c->keyframe_frequency_force)
967 c->keyframe_mindistance=c->keyframe_frequency_force;
968 cpi->pb.keyframe_granule_shift=_ilog(c->keyframe_frequency_force-1);
970 /* clamp the target_bitrate to a maximum of 24 bits so we get a
971 more meaningful value when we write this out in the header. */
972 if(c->target_bitrate>(1<<24)-1)c->target_bitrate=(1<<24)-1;
974 /* copy in config */
975 memcpy(&cpi->pb.info,c,sizeof(*c));
976 th->i=&cpi->pb.info;
977 th->granulepos=-1;
979 /* Set up default values for QTargetModifier[Q_TABLE_SIZE] table */
980 for ( i = 0; i < Q_TABLE_SIZE; i++ )
981 cpi->QTargetModifier[i] = 1.0;
983 /* Set up an encode buffer */
984 #ifndef LIBOGG2
985 cpi->oggbuffer = _ogg_malloc(sizeof(oggpack_buffer));
986 oggpackB_writeinit(cpi->oggbuffer);
987 #else
988 cpi->oggbuffer = _ogg_malloc(oggpack_buffersize());
989 cpi->oggbufferstate = ogg_buffer_create();
990 oggpackB_writeinit(cpi->oggbuffer, cpi->oggbufferstate);
991 #endif
993 /* Set data rate related variables. */
994 cpi->Configuration.TargetBandwidth = (c->target_bitrate) / 8;
996 cpi->Configuration.OutputFrameRate =
997 (double)( c->fps_numerator /
998 c->fps_denominator );
1000 cpi->frame_target_rate = cpi->Configuration.TargetBandwidth /
1001 cpi->Configuration.OutputFrameRate;
1003 /* Set key frame data rate target; this is nominal keyframe size */
1004 cpi->Configuration.KeyFrameDataTarget = (c->keyframe_data_target_bitrate *
1005 c->fps_denominator /
1006 c->fps_numerator ) / 8;
1008 /* Note the height and width in the pre-processor control structure. */
1009 cpi->ScanConfig.VideoFrameHeight = cpi->pb.info.height;
1010 cpi->ScanConfig.VideoFrameWidth = cpi->pb.info.width;
1012 InitFrameDetails(&cpi->pb);
1013 EInitFragmentInfo(cpi);
1014 EInitFrameInfo(cpi);
1016 /* Set up pre-processor config pointers. */
1017 cpi->ScanConfig.Yuv0ptr = cpi->yuv0ptr;
1018 cpi->ScanConfig.Yuv1ptr = cpi->yuv1ptr;
1019 cpi->ScanConfig.SrfWorkSpcPtr = cpi->ConvDestBuffer;
1020 cpi->ScanConfig.disp_fragments = cpi->pb.display_fragments;
1021 cpi->ScanConfig.RegionIndex = cpi->pb.pixel_index_table;
1023 /* Initialise the pre-processor module. */
1024 ScanYUVInit(&cpi->pp, &(cpi->ScanConfig));
1026 /* Initialise Motion compensation */
1027 InitMotionCompensation(cpi);
1029 /* Initialise the compression process. */
1030 /* We always start at frame 1 */
1031 cpi->CurrentFrame = 1;
1033 /* Reset the rate targeting correction factor. */
1034 cpi->BpbCorrectionFactor = 1.0;
1036 cpi->TotalByteCount = 0;
1037 cpi->TotalMotionScore = 0;
1039 /* Up regulation variables. */
1040 cpi->FinalPassLastPos = 0; /* Used to regulate a final unrestricted pass. */
1041 cpi->LastEndSB = 0; /* Where we were in the loop last time. */
1042 cpi->ResidueLastEndSB = 0; /* Where we were in the residue update
1043 loop last time. */
1045 InitHuffmanSet(&cpi->pb);
1047 /* This makes sure encoder version specific tables are initialised */
1048 memcpy(&cpi->pb.quant_info, &TH_VP31_QUANT_INFO, sizeof(th_quant_info));
1049 InitQTables(&cpi->pb);
1051 /* Indicate that the next frame to be compressed is the first in the
1052 current clip. */
1053 cpi->ThisIsFirstFrame = 1;
1054 cpi->readyflag = 1;
1056 cpi->pb.HeadersWritten = 0;
1057 /*We overload this flag to track header output.*/
1058 cpi->doneflag=-3;
1060 return 0;
1063 int theora_encode_YUVin(theora_state *t,
1064 yuv_buffer *yuv){
1065 ogg_int32_t i;
1066 unsigned char *LocalDataPtr;
1067 unsigned char *InputDataPtr;
1068 CP_INSTANCE *cpi=(CP_INSTANCE *)(t->internal_encode);
1070 if(!cpi->readyflag)return OC_EINVAL;
1071 if(cpi->doneflag>0)return OC_EINVAL;
1073 /* If frame size has changed, abort out for now */
1074 if (yuv->y_height != (int)cpi->pb.info.height ||
1075 yuv->y_width != (int)cpi->pb.info.width )
1076 return(-1);
1079 /* Copy over input YUV to internal YUV buffers. */
1080 /* we invert the image for backward compatibility with VP3 */
1081 /* First copy over the Y data */
1082 LocalDataPtr = cpi->yuv1ptr + yuv->y_width*(yuv->y_height - 1);
1083 InputDataPtr = yuv->y;
1084 for ( i = 0; i < yuv->y_height; i++ ){
1085 memcpy( LocalDataPtr, InputDataPtr, yuv->y_width );
1086 LocalDataPtr -= yuv->y_width;
1087 InputDataPtr += yuv->y_stride;
1090 /* Now copy over the U data */
1091 LocalDataPtr = &cpi->yuv1ptr[(yuv->y_height * yuv->y_width)];
1092 LocalDataPtr += yuv->uv_width*(yuv->uv_height - 1);
1093 InputDataPtr = yuv->u;
1094 for ( i = 0; i < yuv->uv_height; i++ ){
1095 memcpy( LocalDataPtr, InputDataPtr, yuv->uv_width );
1096 LocalDataPtr -= yuv->uv_width;
1097 InputDataPtr += yuv->uv_stride;
1100 /* Now copy over the V data */
1101 LocalDataPtr =
1102 &cpi->yuv1ptr[((yuv->y_height*yuv->y_width)*5)/4];
1103 LocalDataPtr += yuv->uv_width*(yuv->uv_height - 1);
1104 InputDataPtr = yuv->v;
1105 for ( i = 0; i < yuv->uv_height; i++ ){
1106 memcpy( LocalDataPtr, InputDataPtr, yuv->uv_width );
1107 LocalDataPtr -= yuv->uv_width;
1108 InputDataPtr += yuv->uv_stride;
1111 /* Special case for first frame */
1112 if ( cpi->ThisIsFirstFrame ){
1113 CompressFirstFrame(cpi);
1114 cpi->ThisIsFirstFrame = 0;
1115 cpi->ThisIsKeyFrame = 0;
1116 } else {
1118 /* don't allow generating invalid files that overflow the p-frame
1119 shift, even if keyframe_auto_p is turned off */
1120 if(cpi->LastKeyFrame >= (ogg_uint32_t)
1121 cpi->pb.info.keyframe_frequency_force)
1122 cpi->ThisIsKeyFrame = 1;
1124 if ( cpi->ThisIsKeyFrame ) {
1125 CompressKeyFrame(cpi);
1126 cpi->ThisIsKeyFrame = 0;
1127 } else {
1128 /* Compress the frame. */
1129 CompressFrame( cpi );
1134 /* Update stats variables. */
1135 cpi->LastFrameSize = oggpackB_bytes(cpi->oggbuffer);
1136 cpi->CurrentFrame++;
1137 cpi->packetflag=1;
1139 t->granulepos=
1140 ((cpi->CurrentFrame - cpi->LastKeyFrame)<<cpi->pb.keyframe_granule_shift)+
1141 cpi->LastKeyFrame - 1;
1143 #ifdef _TH_DEBUG_
1144 dframe++;
1145 #endif
1147 return 0;
1150 int theora_encode_packetout( theora_state *t, int last_p, ogg_packet *op){
1151 CP_INSTANCE *cpi=(CP_INSTANCE *)(t->internal_encode);
1152 long bytes=oggpackB_bytes(cpi->oggbuffer);
1154 if(!bytes)return(0);
1155 if(!cpi->packetflag)return(0);
1156 if(cpi->doneflag>0)return(-1);
1158 #ifndef LIBOGG2
1159 op->packet=oggpackB_get_buffer(cpi->oggbuffer);
1160 #else
1161 op->packet=oggpackB_writebuffer(cpi->oggbuffer);
1162 #endif
1163 op->bytes=bytes;
1164 op->b_o_s=0;
1165 op->e_o_s=last_p;
1167 op->packetno=cpi->CurrentFrame;
1168 op->granulepos=t->granulepos;
1170 cpi->packetflag=0;
1171 if(last_p)cpi->doneflag=1;
1173 return 1;
1176 static void _tp_writebuffer(oggpack_buffer *opb, const char *buf, const long len)
1178 long i;
1180 for (i = 0; i < len; i++)
1181 oggpackB_write(opb, *buf++, 8);
1184 static void _tp_writelsbint(oggpack_buffer *opb, long value)
1186 oggpackB_write(opb, value&0xFF, 8);
1187 oggpackB_write(opb, value>>8&0xFF, 8);
1188 oggpackB_write(opb, value>>16&0xFF, 8);
1189 oggpackB_write(opb, value>>24&0xFF, 8);
1192 /* build the initial short header for stream recognition and format */
1193 int theora_encode_header(theora_state *t, ogg_packet *op){
1194 CP_INSTANCE *cpi=(CP_INSTANCE *)(t->internal_encode);
1195 int offset_y;
1197 #ifndef LIBOGG2
1198 oggpackB_reset(cpi->oggbuffer);
1199 #else
1200 oggpackB_writeinit(cpi->oggbuffer, cpi->oggbufferstate);
1201 #endif
1202 oggpackB_write(cpi->oggbuffer,0x80,8);
1203 _tp_writebuffer(cpi->oggbuffer, "theora", 6);
1205 oggpackB_write(cpi->oggbuffer,TH_VERSION_MAJOR,8);
1206 oggpackB_write(cpi->oggbuffer,TH_VERSION_MINOR,8);
1207 oggpackB_write(cpi->oggbuffer,TH_VERSION_SUB,8);
1209 oggpackB_write(cpi->oggbuffer,cpi->pb.info.width>>4,16);
1210 oggpackB_write(cpi->oggbuffer,cpi->pb.info.height>>4,16);
1211 oggpackB_write(cpi->oggbuffer,cpi->pb.info.frame_width,24);
1212 oggpackB_write(cpi->oggbuffer,cpi->pb.info.frame_height,24);
1213 oggpackB_write(cpi->oggbuffer,cpi->pb.info.offset_x,8);
1214 /* Applications use offset_y to mean offset from the top of the image; the
1215 * meaning in the bitstream is the opposite (from the bottom). Transform.
1217 offset_y = cpi->pb.info.height - cpi->pb.info.frame_height -
1218 cpi->pb.info.offset_y;
1219 oggpackB_write(cpi->oggbuffer,offset_y,8);
1221 oggpackB_write(cpi->oggbuffer,cpi->pb.info.fps_numerator,32);
1222 oggpackB_write(cpi->oggbuffer,cpi->pb.info.fps_denominator,32);
1223 oggpackB_write(cpi->oggbuffer,cpi->pb.info.aspect_numerator,24);
1224 oggpackB_write(cpi->oggbuffer,cpi->pb.info.aspect_denominator,24);
1226 oggpackB_write(cpi->oggbuffer,cpi->pb.info.colorspace,8);
1227 oggpackB_write(cpi->oggbuffer,cpi->pb.info.target_bitrate,24);
1228 oggpackB_write(cpi->oggbuffer,cpi->pb.info.quality,6);
1230 oggpackB_write(cpi->oggbuffer,cpi->pb.keyframe_granule_shift,5);
1232 oggpackB_write(cpi->oggbuffer,cpi->pb.info.pixelformat,2);
1234 oggpackB_write(cpi->oggbuffer,0,3); /* spare config bits */
1236 #ifndef LIBOGG2
1237 op->packet=oggpackB_get_buffer(cpi->oggbuffer);
1238 #else
1239 op->packet=oggpackB_writebuffer(cpi->oggbuffer);
1240 #endif
1241 op->bytes=oggpackB_bytes(cpi->oggbuffer);
1243 op->b_o_s=1;
1244 op->e_o_s=0;
1246 op->packetno=0;
1248 op->granulepos=0;
1249 cpi->packetflag=0;
1251 return(0);
1254 /* build the comment header packet from the passed metadata */
1255 int theora_encode_comment(theora_comment *tc, ogg_packet *op)
1257 const char *vendor = theora_version_string();
1258 const int vendor_length = strlen(vendor);
1259 oggpack_buffer *opb;
1261 #ifndef LIBOGG2
1262 opb = _ogg_malloc(sizeof(oggpack_buffer));
1263 oggpackB_writeinit(opb);
1264 #else
1265 opb = _ogg_malloc(oggpack_buffersize());
1266 oggpackB_writeinit(opb, ogg_buffer_create());
1267 #endif
1268 oggpackB_write(opb, 0x81, 8);
1269 _tp_writebuffer(opb, "theora", 6);
1271 _tp_writelsbint(opb, vendor_length);
1272 _tp_writebuffer(opb, vendor, vendor_length);
1274 _tp_writelsbint(opb, tc->comments);
1275 if(tc->comments){
1276 int i;
1277 for(i=0;i<tc->comments;i++){
1278 if(tc->user_comments[i]){
1279 _tp_writelsbint(opb,tc->comment_lengths[i]);
1280 _tp_writebuffer(opb,tc->user_comments[i],tc->comment_lengths[i]);
1281 }else{
1282 oggpackB_write(opb,0,32);
1286 op->bytes=oggpack_bytes(opb);
1288 #ifndef LIBOGG2
1289 /* So we're expecting the application will free this? */
1290 op->packet=_ogg_malloc(oggpack_bytes(opb));
1291 memcpy(op->packet, oggpack_get_buffer(opb), oggpack_bytes(opb));
1292 oggpack_writeclear(opb);
1293 #else
1294 op->packet = oggpack_writebuffer(opb);
1295 /* When the application puts op->packet into a stream_state object,
1296 it becomes the property of libogg2's internal memory management. */
1297 #endif
1299 _ogg_free(opb);
1301 op->b_o_s=0;
1302 op->e_o_s=0;
1304 op->packetno=0;
1305 op->granulepos=0;
1307 return (0);
1310 /* build the final header packet with the tables required
1311 for decode */
1312 int theora_encode_tables(theora_state *t, ogg_packet *op){
1313 CP_INSTANCE *cpi=(CP_INSTANCE *)(t->internal_encode);
1315 #ifndef LIBOGG2
1316 oggpackB_reset(cpi->oggbuffer);
1317 #else
1318 oggpackB_writeinit(cpi->oggbuffer, cpi->oggbufferstate);
1319 #endif
1320 oggpackB_write(cpi->oggbuffer,0x82,8);
1321 _tp_writebuffer(cpi->oggbuffer,"theora",6);
1323 WriteQTables(&cpi->pb,cpi->oggbuffer);
1324 WriteHuffmanTrees(cpi->pb.HuffRoot_VP3x,cpi->oggbuffer);
1326 #ifndef LIBOGG2
1327 op->packet=oggpackB_get_buffer(cpi->oggbuffer);
1328 #else
1329 op->packet=oggpackB_writebuffer(cpi->oggbuffer);
1330 #endif
1331 op->bytes=oggpackB_bytes(cpi->oggbuffer);
1333 op->b_o_s=0;
1334 op->e_o_s=0;
1336 op->packetno=0;
1338 op->granulepos=0;
1339 cpi->packetflag=0;
1341 cpi->pb.HeadersWritten = 1;
1343 return(0);
1346 static void theora_encode_clear (theora_state *th){
1347 CP_INSTANCE *cpi;
1348 cpi=(CP_INSTANCE *)th->internal_encode;
1349 if(cpi){
1351 ClearHuffmanSet(&cpi->pb);
1352 ClearFragmentInfo(&cpi->pb);
1353 ClearFrameInfo(&cpi->pb);
1354 EClearFragmentInfo(cpi);
1355 EClearFrameInfo(cpi);
1356 ClearTmpBuffers(&cpi->pb);
1357 ClearPPInstance(&cpi->pp);
1359 oggpackB_writeclear(cpi->oggbuffer);
1360 _ogg_free(cpi->oggbuffer);
1361 _ogg_free(cpi);
1364 #ifdef _TH_DEBUG_
1365 fclose(debugout);
1366 debugout=NULL;
1367 #endif
1369 memset(th,0,sizeof(*th));
1373 /* returns, in seconds, absolute time of current packet in given
1374 logical stream */
1375 static double theora_encode_granule_time(theora_state *th,
1376 ogg_int64_t granulepos){
1377 #ifndef THEORA_DISABLE_FLOAT
1378 CP_INSTANCE *cpi=(CP_INSTANCE *)(th->internal_encode);
1379 PB_INSTANCE *pbi=(PB_INSTANCE *)(th->internal_decode);
1381 if(cpi)pbi=&cpi->pb;
1383 if(granulepos>=0){
1384 ogg_int64_t iframe=granulepos>>pbi->keyframe_granule_shift;
1385 ogg_int64_t pframe=granulepos-(iframe<<pbi->keyframe_granule_shift);
1387 return (iframe+pframe)*
1388 ((double)pbi->info.fps_denominator/pbi->info.fps_numerator);
1391 #endif
1393 return(-1); /* negative granulepos or float calculations disabled */
1396 /* returns frame number of current packet in given logical stream */
1397 static ogg_int64_t theora_encode_granule_frame(theora_state *th,
1398 ogg_int64_t granulepos){
1399 CP_INSTANCE *cpi=(CP_INSTANCE *)(th->internal_encode);
1400 PB_INSTANCE *pbi=(PB_INSTANCE *)(th->internal_decode);
1402 if(cpi)pbi=&cpi->pb;
1404 if(granulepos>=0){
1405 ogg_int64_t iframe=granulepos>>pbi->keyframe_granule_shift;
1406 ogg_int64_t pframe=granulepos-(iframe<<pbi->keyframe_granule_shift);
1408 return (iframe+pframe-1);
1411 return(-1);
1415 static int theora_encode_control(theora_state *th,int req,
1416 void *buf,size_t buf_sz) {
1417 CP_INSTANCE *cpi;
1418 PB_INSTANCE *pbi;
1419 int value;
1421 if(th == NULL)
1422 return TH_EFAULT;
1424 cpi = th->internal_encode;
1425 pbi = &cpi->pb;
1427 switch(req) {
1428 case TH_ENCCTL_SET_QUANT_PARAMS:
1429 if( ( buf==NULL&&buf_sz!=0 )
1430 || ( buf!=NULL&&buf_sz!=sizeof(th_quant_info) )
1431 || cpi->pb.HeadersWritten ){
1432 return TH_EINVAL;
1435 memcpy(&pbi->quant_info, buf, sizeof(th_quant_info));
1436 InitQTables(pbi);
1438 return 0;
1439 case TH_ENCCTL_SET_VP3_COMPATIBLE:
1440 if(cpi->pb.HeadersWritten)
1441 return TH_EINVAL;
1443 memcpy(&pbi->quant_info, &TH_VP31_QUANT_INFO, sizeof(th_quant_info));
1444 InitQTables(pbi);
1446 return 0;
1447 case TH_ENCCTL_SET_SPLEVEL:
1448 if(buf == NULL || buf_sz != sizeof(int))
1449 return TH_EINVAL;
1451 memcpy(&value, buf, sizeof(int));
1453 switch(value) {
1454 case 0:
1455 cpi->MotionCompensation = 1;
1456 pbi->info.quick_p = 0;
1457 break;
1459 case 1:
1460 cpi->MotionCompensation = 1;
1461 pbi->info.quick_p = 1;
1462 break;
1464 case 2:
1465 cpi->MotionCompensation = 0;
1466 pbi->info.quick_p = 1;
1467 break;
1469 default:
1470 return TH_EINVAL;
1473 return 0;
1474 case TH_ENCCTL_GET_SPLEVEL_MAX:
1475 value = 2;
1476 memcpy(buf, &value, sizeof(int));
1477 return 0;
1478 default:
1479 return TH_EIMPL;
1483 static void theora_encode_dispatch_init(CP_INSTANCE *cpi){
1484 cpi->dispatch_vtbl.clear=theora_encode_clear;
1485 cpi->dispatch_vtbl.control=theora_encode_control;
1486 cpi->dispatch_vtbl.granule_frame=theora_encode_granule_frame;
1487 cpi->dispatch_vtbl.granule_time=theora_encode_granule_time;