[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