| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149 |
- /********************************************************************
- * *
- * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE. *
- * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
- * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
- * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
- * *
- * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2009 *
- * by the Xiph.Org Foundation http://www.xiph.org/ *
- * *
- ********************************************************************
- function: routines for validating encoder granulepos generation
- last mod: $Id: granulepos.c 16503 2009-08-22 18:14:02Z giles $
- ********************************************************************/
- #include <stdlib.h>
- #include <theora/theoraenc.h>
- #include <math.h>
- #include "tests.h"
- static int ilog(unsigned int v){
- int ret=0;
- while(v){
- ret++;
- v>>=1;
- }
- return(ret);
- }
- static int
- granulepos_test_encode (int frequency)
- {
- th_info ti;
- th_enc_ctx *te;
- int result;
- int frame, tframe, keyframe, keydist;
- int shift;
- double rate, ttime;
- th_ycbcr_buffer yuv;
- unsigned char *framedata;
- ogg_packet op;
- long long int last_granule = -1;
- /* INFO ("+ Initializing th_info struct"); */
- th_info_init (&ti);
- ti.frame_width = 32;
- ti.frame_height = 32;
- ti.pic_width = ti.frame_width;
- ti.pic_height = ti.frame_height;
- ti.pic_x = 0;
- ti.pic_y = 0;
- ti.fps_numerator = 16;
- ti.fps_denominator = 1;
- ti.aspect_numerator = 1;
- ti.aspect_denominator = 1;
- ti.colorspace = TH_CS_UNSPECIFIED;
- ti.pixel_fmt = TH_PF_420;
- ti.quality = 16;
- ti.keyframe_granule_shift=ilog(frequency);
- /* INFO ("+ Allocating encoder context"); */
- te = th_encode_alloc(&ti);
- if (te == NULL) {
- INFO ("+ Clearing th_info");
- th_info_clear(&ti);
- FAIL ("negative return code initializing encoder");
- }
- /* INFO ("+ Setting up dummy 4:2:0 frame data"); */
- framedata = calloc(ti.frame_height, ti.frame_width);
- yuv[0].width = ti.frame_width;
- yuv[0].height = ti.frame_height;
- yuv[0].stride = ti.frame_width;
- yuv[0].data = framedata;
- yuv[1].width = ti.frame_width / 2;
- yuv[1].height = ti.frame_width / 2;
- yuv[1].stride = ti.frame_width;
- yuv[1].data = framedata;
- yuv[2].width = ti.frame_width / 2;
- yuv[2].height = ti.frame_width / 2;
- yuv[2].stride = ti.frame_width;
- yuv[2].data = framedata;
- INFO ("+ Checking granulepos generation");
- shift = ti.keyframe_granule_shift;
- rate = (double)ti.fps_denominator/ti.fps_numerator;
- for (frame = 0; frame < frequency * 2 + 1; frame++) {
- result = th_encode_ycbcr_in (te, yuv);
- if (result < 0) {
- printf("th_encode_ycbcr_in() returned %d\n", result);
- FAIL ("negative error code submitting frame for compression");
- }
- result = th_encode_packetout (te, frame >= frequency * 2, &op);
- if (result <= 0) {
- printf("th_encode_packetout() returned %d\n", result);
- FAIL("failed to retrieve compressed frame");
- }
- if ((long long int)op.granulepos < last_granule)
- FAIL ("encoder returned a decreasing granulepos value");
- last_granule = op.granulepos;
- keyframe = op.granulepos >> shift;
- keydist = op.granulepos - (keyframe << shift);
- tframe = th_granule_frame (te, op.granulepos);
- ttime = th_granule_time(te, op.granulepos);
- #if DEBUG
- printf("++ frame %d granulepos %lld %d:%d %d %.3lfs\n",
- frame, (long long int)op.granulepos, keyframe, keydist,
- tframe, th_granule_time (te, op.granulepos));
- #endif
- /* granulepos stores the frame count */
- if ((keyframe + keydist) != frame + 1)
- FAIL ("encoder granulepos does not map to the correct frame number");
- /* th_granule_frame() returns the frame index */
- if (tframe != frame)
- FAIL ("th_granule_frame() returned incorrect results");
- /* th_granule_time() returns the end time */
- if (fabs(rate*(frame+1) - ttime) > 1.0e-6)
- FAIL ("th_granule_time() returned incorrect results");
- }
- /* clean up */
- /* INFO ("+ Freeing dummy frame data"); */
- free(framedata);
- /* INFO ("+ Clearing th_info struct"); */
- th_info_clear(&ti);
- /* INFO ("+ Freeing encoder context"); */
- th_encode_free(te);
- return 0;
- }
- int main(int argc, char *argv[])
- {
- granulepos_test_encode (1);
- granulepos_test_encode (2);
- granulepos_test_encode (3);
- granulepos_test_encode (4);
- granulepos_test_encode (8);
- granulepos_test_encode (64);
- exit (0);
- }
|