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 ********************************************************************
13 function: routines for validating encoder granulepos generation
16 ********************************************************************/
19 #include <theora/theora.h>
24 static int ilog(unsigned int v
){
34 granulepos_test_encode (int frequency
, int auto_p
)
39 int frame
, tframe
, keyframe
, keydist
;
43 unsigned char *framedata
;
45 long long int last_granule
= -1;
47 /* INFO ("+ Initializing theora_info struct"); */
48 theora_info_init (&ti
);
52 ti
.frame_width
= ti
.width
;
53 ti
.frame_height
= ti
.frame_height
;
56 ti
.fps_numerator
= 16;
57 ti
.fps_denominator
= 1;
58 ti
.aspect_numerator
= 1;
59 ti
.aspect_denominator
= 1;
60 ti
.colorspace
= OC_CS_UNSPECIFIED
;
61 ti
.pixelformat
= OC_PF_420
;
62 ti
.target_bitrate
= 0;
68 /* check variations of automatic or forced keyframe choice */
69 ti
.keyframe_auto_p
= auto_p
;
70 /* check with variations of the maximum gap */
71 ti
.keyframe_frequency
= frequency
;
72 ti
.keyframe_frequency_force
= frequency
;
74 ti
.keyframe_data_target_bitrate
= ti
.target_bitrate
* 1.5;
75 ti
.keyframe_auto_threshold
= 80;
76 ti
.keyframe_mindistance
= MIN(8, frequency
);
77 ti
.noise_sensitivity
= 1;
79 /* INFO ("+ Initializing theora_state for encoding"); */
80 result
= theora_encode_init (&th
, &ti
);
81 if (result
== OC_DISABLED
) {
82 INFO ("+ Clearing theora_state");
84 } else if (result
< 0) {
85 FAIL ("negative return code initializing encoder");
88 /* INFO ("+ Setting up dummy 4:2:0 frame data"); */
89 framedata
= calloc(ti
.height
, ti
.width
);
90 yuv
.y_width
= ti
.width
;
91 yuv
.y_height
= ti
.height
;
92 yuv
.y_stride
= ti
.width
;
94 yuv
.uv_width
= ti
.width
/ 2;
95 yuv
.uv_height
= ti
.width
/ 2;
96 yuv
.uv_stride
= ti
.width
;
100 INFO ("+ Checking granulepos generation");
101 shift
= theora_granule_shift(&ti
);
102 rate
= (double)ti
.fps_denominator
/ti
.fps_numerator
;
103 for (frame
= 0; frame
< frequency
* 2 + 1; frame
++) {
104 result
= theora_encode_YUVin (&th
, &yuv
);
106 printf("theora_encode_YUVin() returned %d\n", result
);
107 FAIL ("negative error code submitting frame for compression");
109 theora_encode_packetout (&th
, frame
>= frequency
* 2, &op
);
110 if ((long long int)op
.granulepos
< last_granule
)
111 FAIL ("encoder returned a decreasing granulepos value");
112 last_granule
= op
.granulepos
;
113 keyframe
= op
.granulepos
>> shift
;
114 keydist
= op
.granulepos
- (keyframe
<< shift
);
115 tframe
= theora_granule_frame (&th
, op
.granulepos
);
116 ttime
= theora_granule_time(&th
, op
.granulepos
);
118 printf("++ frame %d granulepos %lld %d:%d %d %.3lfs\n",
119 frame
, (long long int)op
.granulepos
, keyframe
, keydist
,
120 tframe
, theora_granule_time (&th
, op
.granulepos
));
122 if ((keyframe
+ keydist
) != frame
+ 1)
123 FAIL ("encoder granulepos does not map to the correct frame number");
125 FAIL ("theora_granule_frame returned incorrect results");
126 if (fabs(rate
*(frame
+1) - ttime
) > 1.0e-6)
127 FAIL ("theora_granule_time returned incorrect results");
131 /* INFO ("+ Freeing dummy frame data"); */
134 /* INFO ("+ Clearing theora_info struct"); */
135 theora_info_clear (&ti
);
137 /* INFO ("+ Clearing theora_state"); */
143 int main(int argc
, char *argv
[])
146 granulepos_test_encode (1, 1);
147 granulepos_test_encode (2, 1);
148 granulepos_test_encode (3, 1);
149 granulepos_test_encode (4, 1);
150 granulepos_test_encode (8, 1);
151 granulepos_test_encode (64, 1);