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-2009 *
9 * by the Xiph.Org Foundation http://www.xiph.org/ *
11 ********************************************************************
13 function: routines for validating encoder granulepos generation
14 last mod: $Id: granulepos_theora.c 16503 2009-08-22 18:14:02Z giles $
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);