[xiph-cvs] cvs commit: theora/lib encoder_internal.h quant.c toplevel.c
Monty
xiphmont at xiph.org
Mon Sep 23 02:15:04 PDT 2002
xiphmont 02/09/23 05:15:04
Modified: . Makefile.am
examples Makefile.am
include/theora theora.h
lib encoder_internal.h quant.c toplevel.c
Added: . COPYING
examples encoder_example.c
Log:
more API cleanup
add encoder example; not quite functional yet
Revision Changes Path
1.2 +3 -3 theora/Makefile.am
Index: Makefile.am
===================================================================
RCS file: /usr/local/cvsroot/theora/Makefile.am,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- Makefile.am 23 Sep 2002 03:02:07 -0000 1.1
+++ Makefile.am 23 Sep 2002 09:15:03 -0000 1.2
@@ -7,10 +7,10 @@
EXTRA_DIST = COPYING autogen.sh
dist-hook:
- rm -rf `find $(distdir)/macos -name CVS`
+ rm -rf `find $(distdir)/macos -name CVS`
debug:
- $(MAKE) all CFLAGS="@DEBUG@"
+ $(MAKE) all CFLAGS="@DEBUG@"
profile:
- $(MAKE) all CFLAGS="@PROFILE@"
+ $(MAKE) all CFLAGS="@PROFILE@"
<p><p>1.1 theora/COPYING
Index: COPYING
===================================================================
Copyright (c) 2002, Xiph.org Foundation
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
- Neither the name of the Xiph.org Foundation nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
<p><p>1.2 +6 -6 theora/examples/Makefile.am
Index: Makefile.am
===================================================================
RCS file: /usr/local/cvsroot/theora/examples/Makefile.am,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- Makefile.am 23 Sep 2002 03:02:07 -0000 1.1
+++ Makefile.am 23 Sep 2002 09:15:03 -0000 1.2
@@ -4,16 +4,16 @@
INCLUDES = -I$(top_srcdir)/include
-noinst_PROGRAMS = player_example encoder_example
+noinst_PROGRAMS = encoder_example #player_example
-LDFLAGS = -all-static
-LDADD = ../lib/libtheora.la
+LDFLAGS = -all-static
+LDADD = ../lib/libtheora.la -lm -logg -lvorbis -lvorbisenc
-player_example_SOURCES = player_example.c
+#player_example_SOURCES = player_example.c
encoder_example_SOURCES = encoder_example.c
debug:
- $(MAKE) all CFLAGS="@DEBUG@"
+ $(MAKE) all CFLAGS="@DEBUG@"
profile:
- $(MAKE) all CFLAGS="@PROFILE@"
+ $(MAKE) all CFLAGS="@PROFILE@"
<p><p>1.1 theora/examples/encoder_example.c
Index: encoder_example.c
===================================================================
/********************************************************************
* *
* 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 OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 *
* 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: encoder_example.c,v 1.1 2002/09/23 09:15:03 xiphmont Exp $
********************************************************************/
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <getopt.h>
#include <math.h>
#include "theora/theora.h"
#include "vorbis/codec.h"
#include "vorbis/vorbisenc.h"
const char *optstring = "a:A:v:V:";
struct option options [] = {
{"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}
};
/* 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=-99;
int audio_r=-1;
int video_x=0;
int video_y=0;
int video_x_adj=0;
int video_y_adj=0;
int video_hzn=0;
int video_hzd=0;
int video_an=0;
int video_ad=0;
int video_r=-1;
int video_q=-1;
tatic void usage(void){
fprintf(stderr,
"Usage: encoder_example [options] [audio_file] video_file\n\n"
"Options: \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);
}
tatic void id_file(char *f){
FILE *test;
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",f);
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;
return;
}
}
}
}
}
fprintf(stderr,"Couldn't find WAVE data in RIFF file %s.\n",f);
exit(1);
}
if(!memcmp(buffer,"YUV4",4)){
/* possible YUV2MPEG2 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 YUV2MPEG2 file?\n",f);
}
buffer[i]='\0';
if(!memcmp(buffer,"MPEG",4)){
char interlace;
int aspectn;
int aspectd;
if(video){
/* umm, we already have one */
fprintf(stderr,"Multiple video files specified on command line.\n");
exit(1);
}
if(buffer[4]!='2'){
fprintf(stderr,"Incorrect YUV input file version; YUV4MPEG2 required.\n");
}
ret=sscanf(buffer,"MPEG2 W%d H%d F%d:%d I%c A%d:%d",
&video_x,&video_y,&video_hzn,&video_hzd,&interlace,
&video_an,&video_ad);
if(ret<7){
fprintf(stderr,"Error parsing YUV4MPEG2 header in file %s.\n",f);
exit(1);
}
if(interlace!='p'){
fprintf(stderr,"Input video is interlaced; Theora handles only progressive scan\n",f);
exit(1);
}
video=test;
return;
}
}
fprintf(stderr,"Input file %s is niether a WAV nor YUV4MPEG2 file.\n",f);
exit(1);
riff_err:
fprintf(stderr,"EOF parsing RIFF file %s.\n",f);
exit(1);
yuv_err:
fprintf(stderr,"EOF parsing YUV4MPEG2 file %s.\n",f);
exit(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;
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 */
yuv_buffer yuv;
#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 'a':
audio_q=atof(optarg)*.1;
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());
/* 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 encoding */
video_x_adj=(video_x>>4)<<4;
video_y_adj=(video_y>>4)<<4;
ti.width=video_x_adj;
ti.height=video_y_adj;
ti.fps_numerator=video_hzn;
ti.fps_denominator=video_hzd;
ti.target_bitrate=video_r;
ti.quality=video_r;
ti.droppedframes_p=0;
ti.quickcompress_p=1;
ti.keyframe_auto_p=1;
ti.keyframe_frequency=128;
ti.keyframe_frequency_force=128;
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);
/* 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,2,44100,.4);
else
ret = vorbis_encode_init(&vi,2,44100,-1,128000,-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);
}
/* get the bitstream header pages; one for theora, three for vorbis */
theora_encode_header(&td,&op);
ogg_stream_packetin(&to,&op); /* first packet, so it's flushed
immediately */
if(ogg_stream_pageout(&to,&og)!=1){
/*can't get here unless Ogg is borked */
fprintf(stderr,"Internal Ogg library error.\n");
exit(1);
}
fwrite(og.header,1,og.header_len,stdout);
fwrite(og.body,1,og.body_len,stdout);
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 */
ogg_stream_packetin(&vo,&header_comm);
ogg_stream_packetin(&vo,&header_code);
/* This ensures the actual
* audio data will start on a new page, as per spec
*/
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,stdout);
fwrite(og.body,1,og.body_len,stdout);
}
}
/* setup complete. Raw processing loop! */
while(1){
/* is there an audio page ready to flush? If not, work until there is. */
<p><p> /* is there a video page ready to flush? If not, work until there is. */
<p> /* no pages of either? Must be end of stream. */
if(ogg_stream_pageout(&to,&og)<=0 && ogg_stream_pageout(&vo,&og)<=0)break;
/* which is earlier; the end of the audio page or the end of the
video page? Flush the earlier to stream */
}
fprintf(stderr,
"\r \n"
"done.\n\n");
return(0);
}
<p><p>1.2 +5 -2 theora/include/theora/theora.h
Index: theora.h
===================================================================
RCS file: /usr/local/cvsroot/theora/include/theora/theora.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- theora.h 23 Sep 2002 03:02:07 -0000 1.1
+++ theora.h 23 Sep 2002 09:15:03 -0000 1.2
@@ -11,7 +11,7 @@
********************************************************************
function:
- last mod: $Id: theora.h,v 1.1 2002/09/23 03:02:07 xiphmont Exp $
+ last mod: $Id: theora.h,v 1.2 2002/09/23 09:15:03 xiphmont Exp $
********************************************************************/
@@ -44,6 +44,8 @@
ogg_uint32_t height;
ogg_uint32_t fps_numerator;
ogg_uint32_t fps_denominator;
+ ogg_uint32_t aspect_numerator;
+ ogg_uint32_t aspect_denominator;
int target_bitrate;
int quality;
@@ -53,7 +55,7 @@
unsigned char version_subminor;
/* encode only */
- int droppedframes_p;
+ int dropframes_p;
int quickcompress_p;
int keyframe_auto_p;
ogg_uint32_t keyframe_frequency;
@@ -88,6 +90,7 @@
extern void theora_decode_clear(theora_state *th);
extern int theora_decode_packetin(theora_state *th,ogg_packet *op);
extern int theora_decode_YUVout(theora_state *th,yuv_buffer *yuv);
+extern double theora_packet_time(theora_state *th,ogg_packet *op);
<p><p>1.8 +3 -12 theora/lib/encoder_internal.h
Index: encoder_internal.h
===================================================================
RCS file: /usr/local/cvsroot/theora/lib/encoder_internal.h,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- encoder_internal.h 23 Sep 2002 08:31:02 -0000 1.7
+++ encoder_internal.h 23 Sep 2002 09:15:04 -0000 1.8
@@ -11,7 +11,7 @@
********************************************************************
function:
- last mod: $Id: encoder_internal.h,v 1.7 2002/09/23 08:31:02 xiphmont Exp $
+ last mod: $Id: encoder_internal.h,v 1.8 2002/09/23 09:15:04 xiphmont Exp $
********************************************************************/
@@ -63,6 +63,7 @@
typedef struct CONFIG_TYPE2{
double OutputFrameRate;
ogg_uint32_t TargetBandwidth;
+ ogg_uint32_t KeyFrameDataTarget ; /* Data rate target for key frames */
ogg_uint32_t FirstFrameQ;
ogg_uint32_t BaseQ;
@@ -460,22 +461,12 @@
int GoldenFrameEnabled;
int InterPrediction;
int MotionCompensation;
- int AutoKeyFrameEnabled ;
- ogg_int32_t ForceKeyFrameEvery ;
- ogg_int32_t AutoKeyFrameThreshold ;
+
ogg_uint32_t LastKeyFrame ;
- ogg_uint32_t MinimumDistanceToKeyFrame ;
- ogg_uint32_t KeyFrameDataTarget ; /* Data rate target for key frames */
- ogg_uint32_t KeyFrameFrequency ;
- int DropFramesAllowed ;
ogg_int32_t DropCount ;
ogg_int32_t MaxConsDroppedFrames ;
ogg_int32_t DropFrameTriggerBytes;
int DropFrameCandidate;
- ogg_uint32_t QualitySetting;
- ogg_uint32_t Sharpness;
- ogg_uint32_t PreProcFilterLevel;
- int NoDrops;
/* Compressor Statistics */
double TotErrScore;
<p><p>1.4 +2 -2 theora/lib/quant.c
Index: quant.c
===================================================================
RCS file: /usr/local/cvsroot/theora/lib/quant.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- quant.c 23 Sep 2002 08:31:02 -0000 1.3
+++ quant.c 23 Sep 2002 09:15:04 -0000 1.4
@@ -11,7 +11,7 @@
********************************************************************
function:
- last mod: $Id: quant.c,v 1.3 2002/09/23 08:31:02 xiphmont Exp $
+ last mod: $Id: quant.c,v 1.4 2002/09/23 09:15:04 xiphmont Exp $
********************************************************************/
@@ -121,7 +121,7 @@
UVDcScaleFactorTable = DcScaleFactorTableV1;
ZBinFactor = 0.9;
- switch(cpi->Sharpness){
+ switch(cpi->pb.info.sharpness){
case 0:
ZBinFactor = 0.65;
if ( scale_factor <= 50 )
<p><p>1.8 +38 -54 theora/lib/toplevel.c
Index: toplevel.c
===================================================================
RCS file: /usr/local/cvsroot/theora/lib/toplevel.c,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- toplevel.c 23 Sep 2002 08:31:02 -0000 1.7
+++ toplevel.c 23 Sep 2002 09:15:04 -0000 1.8
@@ -11,7 +11,7 @@
********************************************************************
function:
- last mod: $Id: toplevel.c,v 1.7 2002/09/23 08:31:02 xiphmont Exp $
+ last mod: $Id: toplevel.c,v 1.8 2002/09/23 09:15:04 xiphmont Exp $
********************************************************************/
@@ -406,8 +406,8 @@
/* set up context of key frame sizes and distances for more local
datarate control */
for( i = 0 ; i < KEY_FRAME_CONTEXT ; i ++ ) {
- cpi->PriorKeyFrameSize[i] = cpi->KeyFrameDataTarget;
- cpi->PriorKeyFrameDistance[i] = cpi->ForceKeyFrameEvery;
+ cpi->PriorKeyFrameSize[i] = cpi->Configuration.KeyFrameDataTarget;
+ cpi->PriorKeyFrameDistance[i] = cpi->pb.info.keyframe_frequency_force;
}
/* Keep track of the total number of Key Frames Coded. */
@@ -424,14 +424,15 @@
/* Calculate a new target rate per frame allowing for average key
frame frequency and size thus far. */
if ( cpi->Configuration.TargetBandwidth >
- ((cpi->KeyFrameDataTarget * cpi->Configuration.OutputFrameRate)/
- cpi->KeyFrameFrequency) ) {
+ ((cpi->Configuration.KeyFrameDataTarget *
+ cpi->Configuration.OutputFrameRate)/
+ cpi->pb.info.keyframe_frequency) ) {
cpi->frame_target_rate =
(ogg_int32_t)((cpi->Configuration.TargetBandwidth -
- ((cpi->KeyFrameDataTarget *
+ ((cpi->Configuration.KeyFrameDataTarget *
cpi->Configuration.OutputFrameRate)/
- cpi->KeyFrameFrequency)) /
+ cpi->pb.info.keyframe_frequency)) /
cpi->Configuration.OutputFrameRate);
}else
cpi->frame_target_rate = 1;
@@ -448,7 +449,7 @@
/* Set a target size for this key frame based upon the baseline
target and frequency */
- cpi->ThisFrameTargetBytes = cpi->KeyFrameDataTarget;
+ cpi->ThisFrameTargetBytes = cpi->Configuration.KeyFrameDataTarget;
/* Get a DCT quantizer level for the key frame. */
cpi->MotionScore = cpi->pb.UnitFragments;
@@ -493,11 +494,11 @@
/* set a target size for this frame */
cpi->ThisFrameTargetBytes = (ogg_int32_t) cpi->frame_target_rate +
- ( (cpi->KeyFrameDataTarget - cpi->frame_target_rate) *
- cpi->LastKeyFrame / cpi->ForceKeyFrameEvery );
+ ( (cpi->Configuration.KeyFrameDataTarget - cpi->frame_target_rate) *
+ cpi->LastKeyFrame / cpi->pb.info.keyframe_frequency_force );
- if ( cpi->ThisFrameTargetBytes > cpi->KeyFrameDataTarget )
- cpi->ThisFrameTargetBytes = cpi->KeyFrameDataTarget;
+ if ( cpi->ThisFrameTargetBytes > cpi->Configuration.KeyFrameDataTarget )
+ cpi->ThisFrameTargetBytes = cpi->Configuration.KeyFrameDataTarget;
/* Get a DCT quantizer level for the key frame. */
cpi->MotionScore = cpi->pb.UnitFragments;
@@ -599,7 +600,7 @@
/* if we are allowed to drop frames and are falling behind (eg more
than x frames worth of bandwidth) */
- if ( cpi->DropFramesAllowed &&
+ if ( cpi->pb.info.dropframes_p &&
( cpi->DropCount < cpi->MaxConsDroppedFrames) &&
( cpi->CarryOver <
-((ogg_int32_t)cpi->Configuration.TargetBandwidth)) &&
@@ -642,7 +643,7 @@
/* Set Baseline filter level. */
- ConfigurePP( &cpi->pp, cpi->PreProcFilterLevel );
+ ConfigurePP( &cpi->pp, cpi->pb.info.noise_sensitivity);
/* Score / analyses the fragments. */
cpi->MotionScore = YUVAnalyseFrame(&cpi->pp, &KFIndicator );
@@ -718,12 +719,14 @@
/* decide whether we really should have made this frame a key frame */
- if( cpi->AutoKeyFrameEnabled ) {
+ if( cpi->pb.info.keyframe_auto_p){
if( ( ( 2* IntraError < 5 * InterError )
- && ( KFIndicator >= (ogg_uint32_t) cpi->AutoKeyFrameThreshold)
- && ( cpi->LastKeyFrame > cpi->MinimumDistanceToKeyFrame)
+ && ( KFIndicator >= (ogg_uint32_t)
+ cpi->pb.info.keyframe_auto_threshold)
+ && ( cpi->LastKeyFrame > cpi->pb.info.keyframe_mindistance)
) ||
- (cpi->LastKeyFrame >= (ogg_uint32_t)cpi->ForceKeyFrameEvery) ) {
+ (cpi->LastKeyFrame >= (ogg_uint32_t)
+ cpi->pb.info.keyframe_frequency_force) ){
CompressKeyFrame(cpi); // Code a key frame
return;
@@ -749,9 +752,10 @@
}
}else{
- if (cpi->NoDrops == 1){
- UpdateFrame(cpi);
- }
+ /* even if we 'drop' a frame, a placeholder must be written as we
+ currently assume fixed frame rate timebase as Ogg mapping
+ invariant */
+ UpdateFrame(cpi);
}
}
@@ -814,12 +818,10 @@
cpi->MotionCompensation = 1;
cpi->ThreshMapThreshold = 5;
cpi->MaxConsDroppedFrames = 1;
- cpi->Sharpness = c->sharpness;
/* Set encoder flags. */
/* if not AutoKeyframing cpi->ForceKeyFrameEvery = is frequency */
- cpi->AutoKeyFrameEnabled = c->keyframe_auto_p;
- if(!cpi->AutoKeyFrameEnabled)
+ if(!c->keyframe_auto_p)
c->keyframe_frequency_force = c->keyframe_frequency;
/* Set the frame rate variables. */
@@ -828,32 +830,27 @@
if ( c->fps_denominator < 1 )
c->fps_denominator = 1;
+ /* don't go too nuts on keyframe spacing; impose a high limit to
+ make certain the granulepos encoding strategy works */
+ if(c->keyframe_frequency_force>32768)c->keyframe_frequency_force=32768;
+ if(c->keyframe_mindistance>32768)c->keyframe_mindistance=32768;
+ if(c->keyframe_mindistance>c->keyframe_frequency_force)
+ c->keyframe_mindistance=c->keyframe_frequency_force;
+ cpi->pb.keyframe_granule_shift=_ilog(c->keyframe_frequency_force-1);
+
/* copy in config */
memcpy(&cpi->pb.info,c,sizeof(*c));
- cpi->ForceKeyFrameEvery = c->keyframe_frequency_force;
- cpi->KeyFrameFrequency = c->keyframe_frequency;
- cpi->DropFramesAllowed = c->droppedframes_p;
- cpi->QuickCompress = c->quickcompress_p;
- cpi->MinimumDistanceToKeyFrame = c->keyframe_mindistance;
- cpi->PreProcFilterLevel = c->noise_sensitivity;
- cpi->AutoKeyFrameThreshold = c->keyframe_auto_threshold;
-
-
/* Set up default values for QTargetModifier[Q_TABLE_SIZE] table */
for ( i = 0; i < Q_TABLE_SIZE; i++ )
cpi->QTargetModifier[i] = 1.0;
/* Set up an encode buffer */
- oggpackB_writeinit(&cpi->oggbuffer);
-
+ oggpackB_writeinit(&cpi->oggbuffer);
/* Set data rate related variables. */
cpi->Configuration.TargetBandwidth = (c->target_bitrate) / 8;
- /* Set key frame data rate target */
- cpi->KeyFrameDataTarget = (c->keyframe_data_target_bitrate) / 8;
-
cpi->Configuration.OutputFrameRate =
(double)( c->fps_numerator /
c->fps_denominator );
@@ -862,10 +859,9 @@
cpi->Configuration.OutputFrameRate;
/* Set key frame data rate target; this is nominal keyframe size */
- cpi->KeyFrameDataTarget = (c->keyframe_data_target_bitrate *
- c->fps_numerator /
- c->fps_denominator ) / 8;
-
+ cpi->Configuration.KeyFrameDataTarget = (c->keyframe_data_target_bitrate *
+ c->fps_numerator /
+ c->fps_denominator ) / 8;
/* Note the height and width in the pre-processor control structure. */
cpi->ScanConfig.VideoFrameHeight = cpi->pb.info.height;
@@ -884,18 +880,6 @@
/* Initialise the pre-processor module. */
ScanYUVInit(&cpi->pp, &(cpi->ScanConfig));
-
- /* don't go too nuts on keyframe spacing; impose a high limit to
- make certain the granulepos encoding strategy works */
- if(cpi->ForceKeyFrameEvery>32768)cpi->ForceKeyFrameEvery=32768;
- if(cpi->MinimumDistanceToKeyFrame>32768)cpi->MinimumDistanceToKeyFrame=32768;
-
- {
- long maxPframes=(int)cpi->ForceKeyFrameEvery >
- (int)cpi->MinimumDistanceToKeyFrame ?
- cpi->ForceKeyFrameEvery : cpi->MinimumDistanceToKeyFrame ;
- cpi->pb.keyframe_granule_shift=_ilog(maxPframes-1);
- }
/* Initialise Motion compensation */
InitMotionCompensation(cpi);
<p><p>--- >8 ----
List archives: http://www.xiph.org/archives/
Ogg project homepage: http://www.xiph.org/ogg/
To unsubscribe from this list, send a message to 'cvs-request at xiph.org'
containing only the word 'unsubscribe' in the body. No subject is needed.
Unsubscribe messages sent to the list will be ignored/filtered.
More information about the commits
mailing list