Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/WolfireGames/overgrowth.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'Libraries/libtheora-1.1.1/win32/experimental/transcoder/transcoder_example.c')
-rw-r--r--Libraries/libtheora-1.1.1/win32/experimental/transcoder/transcoder_example.c926
1 files changed, 0 insertions, 926 deletions
diff --git a/Libraries/libtheora-1.1.1/win32/experimental/transcoder/transcoder_example.c b/Libraries/libtheora-1.1.1/win32/experimental/transcoder/transcoder_example.c
deleted file mode 100644
index 28c2b52a..00000000
--- a/Libraries/libtheora-1.1.1/win32/experimental/transcoder/transcoder_example.c
+++ /dev/null
@@ -1,926 +0,0 @@
-/********************************************************************
- * *
- * 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-2004 *
- * by the Xiph.Org Foundation http://www.xiph.org/ *
- * *
- ********************************************************************
-
- function: example encoder application; makes an Ogg Theora/Vorbis
- file from YUV4MPEG2 and WAV input
- last mod: $Id: transcoder_example.c,v 1.4 2004/03/20 00:14:04 tterribe Exp $
-
- ********************************************************************/
-
-#define _GNU_SOURCE
-#define _REENTRANT
-#define _LARGEFILE_SOURCE
-#define _LARGEFILE64_SOURCE
-#define _FILE_OFFSET_BITS 64
-
-#include <stdio.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <string.h>
-#include <getopt.h>
-#include <time.h>
-#include <math.h>
-#include "theora/theora.h"
-#include "vorbis/codec.h"
-#include "vorbis/vorbisenc.h"
-
-#ifdef _WIN32
-/*supply missing headers and functions to Win32. going to hell, I know*/
-#include <io.h>
-#include <fcntl.h>
-
-static double rint(double x)
-{
- if (x < 0.0)
- return (double)(int)(x - 0.5);
- else
- return (double)(int)(x + 0.5);
-}
-#endif
-
-/*Copied from vorbis/sharedbook.c*/
-static int _ilog(unsigned int v){
- int ret=0;
- while(v){
- ret++;
- v>>=1;
- }
- return(ret);
-}
-
-
-const char *optstring = "o:a:A:v:V:";
-struct option options [] = {
- {"output",required_argument,NULL,'o'},
- {"audio-rate-target",required_argument,NULL,'A'},
- {"video-rate-target",required_argument,NULL,'V'},
- {"audio-quality",required_argument,NULL,'a'},
- {"video-quality",required_argument,NULL,'v'},
- {NULL,0,NULL,0}
-};
-
-typedef struct TC_INSTANCE {
- ogg_uint32_t LastKeyFrame ;
- ogg_int64_t KeyFrameCount;
- int ThisIsFirstFrame;
- int ThisIsKeyFrame;
- ogg_uint32_t CurrentFrame;
- ogg_int64_t granulepos;
- int keyframe_granule_shift;
- char * in_bytes;
- long in_bytecount;
- ogg_uint32_t fps_denominator;
- ogg_uint32_t fps_numerator;
- oggpack_buffer opb_in;
- oggpack_buffer opb_out;
-} TC_INSTANCE;
-
-/* You'll go to Hell for using globals. */
-
-FILE *audio=NULL;
-FILE *video=NULL;
-
-int audio_ch=0;
-int audio_hz=0;
-
-float audio_q=.1;
-int audio_r=-1;
-
-int video_x=0;
-int video_y=0;
-int frame_x=0;
-int frame_y=0;
-int frame_x_offset=0;
-int frame_y_offset=0;
-int video_hzn=0;
-int video_hzd=0;
-int video_an=0;
-int video_ad=0;
-
-int video_r=-1;
-int video_q=16;
-
- char *vp3frame[2];
- int framebytecount[2];
- int frameiskey[2];
-
- ogg_page audiopage;
- ogg_page videopage;
-
-static void usage(void){
- fprintf(stderr,
- "Usage: encoder_example [options] [audio_file] video_file\n\n"
- "Options: \n\n"
- " -o --output <filename.ogv> file name for encoded output;\n"
- " If this option is not given, the\n"
- " compressed data is sent to stdout.\n\n"
- " -A --audio-rate-target <n> bitrate target for Vorbis audio;\n"
- " use -a and not -A if at all possible,\n"
- " as -a gives higher quality for a given\n"
- " bitrate.\n\n"
- " -V --video-rate-target <n> bitrate target for Theora video\n\n"
- " -a --audio-quality <n> Vorbis quality selector from -1 to 10\n"
- " (-1 yields smallest files but lowest\n"
- " fidelity; 10 yields highest fidelity\n"
- " but large files. '2' is a reasonable\n"
- " default).\n\n"
- " -v --video-quality <n> Theora quality selector fro 0 to 10\n"
- " (0 yields smallest files but lowest\n"
- " video quality. 10 yields highest\n"
- " fidelity but large files).\n\n"
- "encoder_example accepts only uncompressed RIFF WAV format audio and\n"
- "YUV4MPEG2 uncompressed video.\n\n");
- exit(1);
-}
-
-static void id_file(char *f){
- FILE *test;
- unsigned char buffer[80];
- int ret;
-
- /* open it, look for magic */
-
- if(!strcmp(f,"-")){
- /* stdin */
- test=stdin;
- }else{
- test=fopen(f,"rb");
- if(!test){
- fprintf(stderr,"Unable to open file %s.\n",f);
- exit(1);
- }
- }
-
- ret=fread(buffer,1,4,test);
- if(ret<4){
- fprintf(stderr,"EOF determining file type of file %s.\n",f);
- exit(1);
- }
-
- if(!memcmp(buffer,"RIFF",4)){
- /* possible WAV file */
-
- if(audio){
- /* umm, we already have one */
- fprintf(stderr,"Multiple RIFF WAVE files specified on command line.\n");
- exit(1);
- }
-
- /* Parse the rest of the header */
-
- ret=fread(buffer,1,4,test);
- ret=fread(buffer,1,4,test);
- if(ret<4)goto riff_err;
- if(!memcmp(buffer,"WAVE",4)){
-
- while(!feof(test)){
- ret=fread(buffer,1,4,test);
- if(ret<4)goto riff_err;
- if(!memcmp("fmt",buffer,3)){
-
- /* OK, this is our audio specs chunk. Slurp it up. */
-
- ret=fread(buffer,1,20,test);
- if(ret<20)goto riff_err;
-
- if(memcmp(buffer+4,"\001\000",2)){
- fprintf(stderr,"The WAV file %s is in a compressed format; "
- "can't read it.\n",f);
- exit(1);
- }
-
- audio=test;
- audio_ch=buffer[6]+(buffer[7]<<8);
- audio_hz=buffer[8]+(buffer[9]<<8)+
- (buffer[10]<<16)+(buffer[11]<<24);
-
- if(buffer[18]+(buffer[19]<<8)!=16){
- fprintf(stderr,"Can only read 16 bit WAV files for now.\n");
- exit(1);
- }
-
- /* Now, align things to the beginning of the data */
- /* Look for 'dataxxxx' */
- while(!feof(test)){
- ret=fread(buffer,1,4,test);
- if(ret<4)goto riff_err;
- if(!memcmp("data",buffer,4)){
- /* We're there. Ignore the declared size for now. */
- ret=fread(buffer,1,4,test);
- if(ret<4)goto riff_err;
-
- fprintf(stderr,"File %s is 16 bit %d channel %d Hz RIFF WAV audio.\n",
- f,audio_ch,audio_hz);
-
- return;
- }
- }
- }
- }
- }
-
- fprintf(stderr,"Couldn't find WAVE data in RIFF file %s.\n",f);
- exit(1);
-
- }
- if(!memcmp(buffer,"AVI2",4)){
- /* possible AVI2VP31 format file */
- /* read until newline, or 80 cols, whichever happens first */
- int i;
- for(i=0;i<79;i++){
- ret=fread(buffer+i,1,1,test);
- if(ret<1)goto yuv_err;
- if(buffer[i]=='\n')break;
- }
- if(i==79){
- fprintf(stderr,"Error parsing %s header; not a VP31 raw frames file?\n",f);
- }
- buffer[i]='\0';
-
- if(!memcmp(buffer,"VP31",4)){
- char interlace;
-
- if(video){
- /* umm, we already have one */
- fprintf(stderr,"Multiple video files specified on command line.\n");
- exit(1);
- }
-
- if(buffer[4]!='R'){
- fprintf(stderr,"Incorrect file ; VP31 raw frames required.\n");
- }
-
- ret=sscanf(buffer,"VP31R W%d H%d F%d:%d I%c A%d:%d",
- &frame_x,&frame_y,&video_hzn,&video_hzd,&interlace,
- &video_an,&video_ad);
- if(ret<7){
- fprintf(stderr,"Error parsing AVI2VP31R header in file %s.\n",f);
- exit(1);
- }
-
- if(interlace!='p'){
- fprintf(stderr,"Input video is interlaced; Theora handles only progressive scan\n");
- exit(1);
- }
-
- video=test;
-
- fprintf(stderr,"File %s is %dx%d %.02f fps VP31 video.\n",
- f,frame_x,frame_y,(double)video_hzn/video_hzd);
-
- return;
- }
- }
- fprintf(stderr,"Input file %s is neither a WAV nor VP31 file.\n",f);
- exit(1);
-
- riff_err:
- fprintf(stderr,"EOF parsing RIFF file %s.\n",f);
- exit(1);
- yuv_err:
- fprintf(stderr,"EOF parsing VP31 file %s.\n",f);
- exit(1);
-
-}
-
-int spinner=0;
-char *spinascii="|/-\\";
-void spinnit(void){
- spinner++;
- if(spinner==4)spinner=0;
- fprintf(stderr,"\r%c",spinascii[spinner]);
-}
-
-int fetch_and_process_audio(FILE *audio,ogg_page *audiopage,
- ogg_stream_state *vo,
- vorbis_dsp_state *vd,
- vorbis_block *vb,
- int audioflag){
- ogg_packet op;
- int i,j;
-
- while(audio && !audioflag){
- /* process any audio already buffered */
- spinnit();
- if(ogg_stream_pageout(vo,audiopage)>0) return 1;
- if(ogg_stream_eos(vo))return 0;
-
- {
- /* read and process more audio */
- signed char readbuffer[4096];
- int toread=4096/2/audio_ch;
- int bytesread=fread(readbuffer,1,toread*2*audio_ch,audio);
- int sampread=bytesread/2/audio_ch;
- float **vorbis_buffer;
- int count=0;
-
- if(bytesread<=0){
- /* end of file. this can be done implicitly, but it's
- easier to see here in non-clever fashion. Tell the
- library we're at end of stream so that it can handle the
- last frame and mark end of stream in the output properly */
- vorbis_analysis_wrote(vd,0);
- }else{
- vorbis_buffer=vorbis_analysis_buffer(vd,sampread);
- /* uninterleave samples */
- for(i=0;i<sampread;i++){
- for(j=0;j<audio_ch;j++){
- vorbis_buffer[j][i]=((readbuffer[count+1]<<8)|
- (0x00ff&(int)readbuffer[count]))/32768.f;
- count+=2;
- }
- }
-
- vorbis_analysis_wrote(vd,sampread);
-
- }
-
- while(vorbis_analysis_blockout(vd,vb)==1){
-
- /* analysis, assume we want to use bitrate management */
- vorbis_analysis(vb,NULL);
- vorbis_bitrate_addblock(vb);
-
- /* weld packets into the bitstream */
- while(vorbis_bitrate_flushpacket(vd,&op))
- ogg_stream_packetin(vo,&op);
-
- }
- }
- }
-
- return audioflag;
-}
-
-int theora_transcode_packetout( TC_INSTANCE *ttc, int last_p, ogg_packet *op){
-
- long bytes=ttc->in_bytecount;
-
- if(!bytes)return(0);
-
- op->packet=ttc->in_bytes;
- op->bytes=bytes;
- op->b_o_s=0;
- op->e_o_s=last_p;
-
- op->packetno=ttc->CurrentFrame;
- op->granulepos=ttc->granulepos;
-
- return 1;
-}
-
-void TranscodeKeyFrame(TC_INSTANCE *ttc){
- /* Keep track of the total number of Key Frames Coded */
- ttc->KeyFrameCount += 1;
- ttc->LastKeyFrame = 1;
-}
-
-void TranscodeFrame(TC_INSTANCE *ttc){
- ttc->LastKeyFrame++;
-}
-
-void TranscodeFirstFrame(TC_INSTANCE *ttc){
- /* Keep track of the total number of Key Frames Coded. */
- ttc->KeyFrameCount = 1;
- ttc->LastKeyFrame = 1;
-}
-
-int theora_transcode_bufferin( TC_INSTANCE *ttc, int isKeyFrame, char * bytes, int bytecount){
-
- /*transcode: record keyframe flag*/
- ttc->ThisIsKeyFrame = isKeyFrame;
-
- /* Special case for first frame */
- if ( ttc->ThisIsFirstFrame ){
- ttc->ThisIsFirstFrame = 0;
- ttc->ThisIsKeyFrame = 0;
- } else if ( ttc->ThisIsKeyFrame ) {
- TranscodeKeyFrame(ttc);
- ttc->ThisIsKeyFrame = 0;
- } else {
- /* Compress the frame. */
- TranscodeFrame( ttc );
- }
- /*need to pack info here*/
- {
-
- int frame_type;
- long total_bits;
- long total_words;
- int frac_bits;
-
- oggpackB_readinit(&ttc->opb_in,bytes,bytecount);
- oggpackB_reset(&ttc->opb_out);
-
- /*Mark as video frame.*/
- oggpackB_write(&ttc->opb_out,0,1);
- /*Copy frame type.*/
- frame_type=oggpackB_read1(&ttc->opb_in);
- oggpackB_write(&ttc->opb_out,frame_type,1);
- /*Skip an unused bit in the VP32 header.*/
- oggpackB_adv1(&ttc->opb_in);
- /*Copy Q multiplier.*/
- oggpackB_write(&ttc->opb_out,oggpackB_read(&ttc->opb_in,6),6);
- /*VP3 has no per-block Q multipliers*/
- oggpackB_write(&ttc->opb_out,0,1);
- /*If the frame is a base/key/golden frame, copy a few extra bits.*/
- if(frame_type==0){
- /*These 13 bits are not included in a Theora frame header.
- They were 0's and VP3 version info in VP32.*/
- oggpackB_adv(&ttc->opb_in,13);
- /*Copy the key frame type and the spare configuration bits.*/
- oggpackB_write(&ttc->opb_out,oggpackB_read(&ttc->opb_in,3),3);
- }
-
- /*Copy the rest of the bits over.*/
- total_bits=bytecount*8-oggpack_bits(&ttc->opb_in);
- frac_bits=(int)(total_bits&31);
- if(frac_bits){
- oggpackB_write(&ttc->opb_out,oggpackB_read(&ttc->opb_in,frac_bits),
- frac_bits);
- }
- total_words=total_bits>>5;
- while(total_words-->0){
- oggpackB_write(&ttc->opb_out,oggpackB_read(&ttc->opb_in,32),32);
- }
-
- ttc->in_bytecount = oggpackB_bytes(&ttc->opb_out);
- ttc->in_bytes = oggpackB_get_buffer(&ttc->opb_out);
- }
-
- /* Update stats variables. */
- ttc->CurrentFrame++;
-
- ttc->granulepos=
- ((ttc->CurrentFrame-ttc->LastKeyFrame-1)<<ttc->keyframe_granule_shift)+
- ttc->LastKeyFrame-1;
-
- return 0;
-}
-
-//static void _tp_writebuffer(oggpack_buffer *opb, const char *buf, const long len)
-
-int theora_transcoder_init(theora_info * ti, TC_INSTANCE * ttc){
- memset(ttc, 0, sizeof(*ttc));
- ttc->granulepos = -1;
- ttc->keyframe_granule_shift=_ilog(ti->keyframe_frequency_force-1);
- ttc->LastKeyFrame = 0;
- ttc->KeyFrameCount = 0;
- ttc->ThisIsFirstFrame = 1;
- ttc->ThisIsKeyFrame = 0;
- ttc->CurrentFrame = 1;
- ttc->in_bytes = 0;
- ttc->in_bytecount = 0;
- ttc->fps_denominator = ti->fps_denominator;
- ttc->fps_numerator = ti->fps_numerator;
- oggpackB_writeinit(&ttc->opb_out);
- return 0;
-}
-
-int fetch_and_process_video(FILE *video,ogg_page *videopage,
- ogg_stream_state *to,
- TC_INSTANCE *ttc,
- int videoflag){
- /* You'll go to Hell for using static variables */
- static int state=-1;
- ogg_packet op;
- int i;
- int keyframeflag, framelength;
-
-
- if(state==-1){
- /* initialize the double frame buffer */
- state=0;
- }
-
- /* is there a video page flushed? If not, work until there is. */
- while(!videoflag){
- spinnit();
-
- if(ogg_stream_pageout(to,videopage)>0) return 1;
- if(ogg_stream_eos(to)) return 0;
-
- {
- /* read and process more video */
- /* video strategy reads one frame ahead so we know when we're
- at end of stream and can mark last video frame as such
- (vorbis audio has to flush one frame past last video frame
- due to overlap and thus doesn't need this extra work */
-
- /* have two frame buffers full (if possible) before
- proceeding. after first pass and until eos, one will
- always be full when we get here */
-
- for(i=state;i<2;i++){
- char c,frame[6];
- int ret=fread(frame,1,6,video);
-
- /* match and skip the frame header */
- if(ret<6)break;
- if(memcmp(frame,"FRAME",5)){
- fprintf(stderr,"Loss of framing in VP31 input data\n");
- exit(1);
- }
- if(frame[5]!='\n'){
- int j;
- for(j=0;j<79;j++)
- if(fread(&c,1,1,video)&&c=='\n')break;
- if(j==79){
- fprintf(stderr,"Error parsing VP31 frame header\n");
- exit(1);
- }
- }
-
- /*read the length*/
- ret=fread(&framelength, sizeof(int), 1, video);
-
- /*read the keyframeflag*/
- ret=fread(&keyframeflag, sizeof(int), 1, video);
-
- vp3frame[i] = malloc(framelength);
- framebytecount[i] = framelength;
- frameiskey[i] = keyframeflag;
-
- /* read the frame */
- ret=fread((char *) vp3frame[i], sizeof(char), framelength, video);
- if(ret!=framelength) break;
-
- state++;
- }
-
- if(state<1){
- /* can't get here unless VP31 stream has no video */
- fprintf(stderr,"Video input contains no frames.\n");
- exit(1);
- }
-
- /* Theora is a one-frame-in,one-frame-out system; submit a frame
- for compression and pull out the packet */
-
- //theora_encode_YUVin(td,&yuv);
- theora_transcode_bufferin( ttc, frameiskey[0], vp3frame[0], framebytecount[0]);
-
- /* if there's only one frame, it's the last in the stream */
- if(state<2)
- theora_transcode_packetout(ttc,1,&op);
- else
- theora_transcode_packetout(ttc,0,&op);
-
- ogg_stream_packetin(to,&op);
-
- {
- signed char *temp=vp3frame[0];
- vp3frame[0]=vp3frame[1];
- vp3frame[1] = temp;
- free(temp);
-
- framebytecount[0]= framebytecount[1];
- frameiskey[0] = frameiskey[1];
- state--;
- }
- }
- }
- return videoflag;
-}
-
-/* returns, in seconds, absolute time of current packet in given
- logical stream */
-double transcode_granule_time(TC_INSTANCE *ttc,ogg_int64_t granulepos){
- if(granulepos>=0){
- ogg_int64_t iframe=granulepos>>ttc->keyframe_granule_shift;
- ogg_int64_t pframe=granulepos-(iframe<<ttc->keyframe_granule_shift);
-
- return (iframe+pframe)*
- ((double)ttc->fps_denominator/ttc->fps_numerator);
-
- }
- return(-1);
-}
-
-int main(int argc,char *argv[]){
- int c,long_option_index,ret;
-
- ogg_stream_state to; /* take physical pages, weld into a logical
- stream of packets */
- ogg_stream_state vo; /* take physical pages, weld into a logical
- stream of packets */
- ogg_page og; /* one Ogg bitstream page. Vorbis packets are inside */
- ogg_packet op; /* one raw packet of data for decode */
-
- theora_state td;
- theora_info ti;
- theora_comment tc;
-
- vorbis_info vi; /* struct that stores all the static vorbis bitstream
- settings */
- vorbis_comment vc; /* struct that stores all the user comments */
-
- vorbis_dsp_state vd; /* central working state for the packet->PCM decoder */
- vorbis_block vb; /* local working space for packet->PCM decode */
-
- int audioflag=0;
- int videoflag=0;
- int akbps=0;
- int vkbps=0;
-
- ogg_int64_t audio_bytesout=0;
- ogg_int64_t video_bytesout=0;
- double timebase;
-
- FILE* outfile = stdout;
-
- TC_INSTANCE ttc;
-
-#ifdef _WIN32 /* We need to set stdin/stdout to binary mode. Damn windows. */
- /* if we were reading/writing a file, it would also need to in
- binary mode, eg, fopen("file.wav","wb"); */
- /* Beware the evil ifdef. We avoid these where we can, but this one we
- cannot. Don't add any more, you'll probably go to hell if you do. */
- _setmode( _fileno( stdin ), _O_BINARY );
- _setmode( _fileno( stdout ), _O_BINARY );
-#endif
-
- while((c=getopt_long(argc,argv,optstring,options,&long_option_index))!=EOF){
- switch(c){
- case 'o':
- outfile=fopen(optarg,"wb");
- if(outfile==NULL){
- fprintf(stderr,"Unable to open output file '%s'\n", optarg);
- exit(1);
- }
- break;;
-
- case 'a':
- audio_q=atof(optarg)*.099;
- if(audio_q<-.1 || audio_q>1){
- fprintf(stderr,"Illegal audio quality (choose -1 through 10)\n");
- exit(1);
- }
- audio_r=-1;
- break;
-
- case 'v':
- video_q=rint(atof(optarg)*6.3);
- if(video_q<0 || video_q>63){
- fprintf(stderr,"Illegal video quality (choose 0 through 10)\n");
- exit(1);
- }
- video_r=0;
- break;
-
- case 'A':
- audio_r=atof(optarg)*1000;
- if(audio_q<0){
- fprintf(stderr,"Illegal audio quality (choose > 0 please)\n");
- exit(1);
- }
- audio_q=-99;
- break;
-
- case 'V':
- video_r=rint(atof(optarg)*1000);
- if(video_r<45000 || video_r>2000000){
- fprintf(stderr,"Illegal video bitrate (choose 45kbps through 2000kbps)\n");
- exit(1);
- }
- video_q=0;
- break;
- default:
- usage();
- }
- }
-
- while(optind<argc){
- /* assume that anything following the options must be a filename */
- id_file(argv[optind]);
- optind++;
- }
-
- /* yayness. Set up Ogg output stream */
- srand(time(NULL));
- ogg_stream_init(&vo,rand());
- ogg_stream_init(&to,rand()); /* oops, add one ot the above */
-
- /* Set up Theora encoder */
- if(!video){
- fprintf(stderr,"No video files submitted for compression?\n");
- exit(1);
- }
- /* Theora has a divisible-by-sixteen restriction for the encoded video size */
- /* scale the frame size up to the nearest /16 and calculate offsets */
- video_x=((frame_x + 15) >>4)<<4;
- video_y=((frame_y + 15) >>4)<<4;
- frame_x_offset=(video_x-frame_x)/2;
- frame_y_offset=(video_y-frame_y)/2;
-
- theora_info_init(&ti);
- ti.width=video_x;
- ti.height=video_y;
- ti.frame_width=frame_x;
- ti.frame_height=frame_y;
- ti.offset_x=frame_x_offset;
- ti.offset_y=frame_y_offset;
- ti.fps_numerator=video_hzn;
- ti.fps_denominator=video_hzd;
- ti.aspect_numerator=video_an;
- ti.aspect_denominator=video_ad;
- ti.colorspace=OC_CS_UNSPECIFIED;
- ti.target_bitrate=video_r;
- ti.quality=video_q;
-
- ti.dropframes_p=0;
- ti.quick_p=1;
- ti.keyframe_auto_p=1;
- ti.keyframe_frequency=32768;
- ti.keyframe_frequency_force=32768;
- ti.keyframe_data_target_bitrate=video_r*1.5;
- ti.keyframe_auto_threshold=80;
- ti.keyframe_mindistance=8;
- ti.noise_sensitivity=1;
-
- theora_encode_init(&td,&ti);
- theora_transcoder_init(&ti, &ttc);
- theora_info_clear(&ti);
-
- /* initialize Vorbis too, assuming we have audio to compress. */
- if(audio){
- vorbis_info_init(&vi);
- if(audio_q>-99)
- ret = vorbis_encode_init_vbr(&vi,audio_ch,audio_hz,audio_q);
- else
- ret = vorbis_encode_init(&vi,audio_ch,audio_hz,-1,audio_r,-1);
- if(ret){
- fprintf(stderr,"The Vorbis encoder could not set up a mode according to\n"
- "the requested quality or bitrate.\n\n");
- exit(1);
- }
-
- vorbis_comment_init(&vc);
- vorbis_analysis_init(&vd,&vi);
- vorbis_block_init(&vd,&vb);
- }
-
- /* write the bitstream header packets with proper page interleave */
-
- /* first packet will get its own page automatically */
- theora_encode_header(&td,&op);
- ogg_stream_packetin(&to,&op);
- if(ogg_stream_pageout(&to,&og)!=1){
- fprintf(stderr,"Internal Ogg library error.\n");
- exit(1);
- }
- fwrite(og.header,1,og.header_len,outfile);
- fwrite(og.body,1,og.body_len,outfile);
-
- /* create the remaining theora headers */
- theora_comment_init(&tc);
- theora_encode_comment(&tc,&op);
- ogg_stream_packetin(&to,&op);
- theora_encode_tables(&td,&op);
- ogg_stream_packetin(&to,&op);
-
- if(audio){
- ogg_packet header;
- ogg_packet header_comm;
- ogg_packet header_code;
-
- vorbis_analysis_headerout(&vd,&vc,&header,&header_comm,&header_code);
- ogg_stream_packetin(&vo,&header); /* automatically placed in its own
- page */
- if(ogg_stream_pageout(&vo,&og)!=1){
- fprintf(stderr,"Internal Ogg library error.\n");
- exit(1);
- }
- fwrite(og.header,1,og.header_len,outfile);
- fwrite(og.body,1,og.body_len,outfile);
-
- /* remaining vorbis header packets */
- ogg_stream_packetin(&vo,&header_comm);
- ogg_stream_packetin(&vo,&header_code);
- }
-
- /* Flush the rest of our headers. This ensures
- the actual data in each stream will start
- on a new page, as per spec. */
- while(1){
- int result = ogg_stream_flush(&to,&og);
- if(result<0){
- /* can't get here */
- fprintf(stderr,"Internal Ogg library error.\n");
- exit(1);
- }
- if(result==0)break;
- fwrite(og.header,1,og.header_len,outfile);
- fwrite(og.body,1,og.body_len,outfile);
- }
- if(audio){
- while(1){
- int result=ogg_stream_flush(&vo,&og);
- if(result<0){
- /* can't get here */
- fprintf(stderr,"Internal Ogg library error.\n");
- exit(1);
- }
- if(result==0)break;
- fwrite(og.header,1,og.header_len,outfile);
- fwrite(og.body,1,og.body_len,outfile);
- }
- }
-
- /* setup complete. Raw processing loop */
- fprintf(stderr,"Compressing....\n");
- while(1){
-
-
- /* is there an audio page flushed? If not, fetch one if possible */
- audioflag=fetch_and_process_audio(audio,&audiopage,&vo,&vd,&vb,audioflag);
-
- /* is there a video page flushed? If not, fetch one if possible */
- videoflag=fetch_and_process_video(video,&videopage,&to,&ttc,videoflag);
-
- /* no pages of either? Must be end of stream. */
- if(!audioflag && !videoflag)break;
-
- /* which is earlier; the end of the audio page or the end of the
- video page? Flush the earlier to stream */
- {
- int audio_or_video=-1;
- double audiotime=
- audioflag?vorbis_granule_time(&vd,ogg_page_granulepos(&audiopage)):-1;
- double videotime=
- videoflag?transcode_granule_time(&ttc,ogg_page_granulepos(&videopage)):-1;
-
- if(!audioflag){
- audio_or_video=1;
- } else if(!videoflag) {
- audio_or_video=0;
- } else {
- if(audiotime<videotime)
- audio_or_video=0;
- else
- audio_or_video=1;
- }
-
- if(audio_or_video==1){
- /* flush a video page */
- video_bytesout+=fwrite(videopage.header,1,videopage.header_len,outfile);
- video_bytesout+=fwrite(videopage.body,1,videopage.body_len,outfile);
- videoflag=0;
- timebase=videotime;
-
- }else{
- /* flush an audio page */
- audio_bytesout+=fwrite(audiopage.header,1,audiopage.header_len,outfile);
- audio_bytesout+=fwrite(audiopage.body,1,audiopage.body_len,outfile);
- audioflag=0;
- timebase=audiotime;
- }
- {
- int hundredths=timebase*100-(long)timebase*100;
- int seconds=(long)timebase%60;
- int minutes=((long)timebase/60)%60;
- int hours=(long)timebase/3600;
-
- if(audio_or_video)
- vkbps=rint(video_bytesout*8./timebase*.001);
- else
- akbps=rint(audio_bytesout*8./timebase*.001);
-
- fprintf(stderr,
- "\n %d:%02d:%02d.%02d audio: %dkbps video: %dkbps ",
- hours,minutes,seconds,hundredths,akbps,vkbps);
- }
- }
-
- }
-
- /* clear out state */
-
- if(audio){
- ogg_stream_clear(&vo);
- vorbis_block_clear(&vb);
- vorbis_dsp_clear(&vd);
- vorbis_comment_clear(&vc);
- vorbis_info_clear(&vi);
- }
- if(video){
- ogg_stream_clear(&to);
- theora_clear(&td);
- }
-
- if(outfile && outfile!=stdout)fclose(outfile);
-
- fprintf(stderr,"\r \ndone.\n\n");
-
- return(0);
-
-}