[xiph-commits] r9845 - trunk/ffmpeg2theora

j at svn.xiph.org j at svn.xiph.org
Wed Aug 24 14:35:58 PDT 2005


Author: j
Date: 2005-08-24 14:35:54 -0700 (Wed, 24 Aug 2005)
New Revision: 9845

Modified:
   trunk/ffmpeg2theora/ffmpeg2theora.c
   trunk/ffmpeg2theora/theorautils.c
   trunk/ffmpeg2theora/theorautils.h
Log:
- rename theoraframes to oggmux
- make theorautils.[ch] independent of ffmpeg. 
  might be of interest for other projects, 
- make ogg_packet op local too.



Modified: trunk/ffmpeg2theora/ffmpeg2theora.c
===================================================================
--- trunk/ffmpeg2theora/ffmpeg2theora.c	2005-08-24 20:43:57 UTC (rev 9844)
+++ trunk/ffmpeg2theora/ffmpeg2theora.c	2005-08-24 21:35:54 UTC (rev 9845)
@@ -1,7 +1,7 @@
 /* -*- tab-width:4;c-file-style:"cc-mode"; -*- */
 /*
- * ffmpeg2theora.c -- Convert ffmpeg supported a/v files to  Ogg Theora
- * Copyright (C) 2003-2004 <j at v2v.cc>
+ * ffmpeg2theora.c -- Convert ffmpeg supported a/v files to  Ogg Theora / Ogg Vorbis
+ * Copyright (C) 2003-2005 <j at v2v.cc>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -38,7 +38,6 @@
 #include "theorautils.h"
 
 #define DEINTERLACE_FLAG     1
-#define DEBUG_FLAG           2
 #define SYNC_FLAG            3
 #define NOSOUND_FLAG         4
 #define V4L_FLAG             5
@@ -50,6 +49,65 @@
 #define INPUTFPS_FLAG       11
 #define AUDIOSTREAM_FLAG    12
 
+
+
+#define V2V_PRESET_PRO 1
+#define V2V_PRESET_PREVIEW 2
+
+
+typedef struct ff2theora{
+    AVFormatContext *context;
+    int video_index;
+    int audio_index;
+    
+    int deinterlace;
+    int audiostream;
+    int sample_rate;
+    int channels;
+    int disable_audio;
+    float audio_quality;
+    int audio_bitrate;
+    int preset;
+
+    int picture_width;
+    int picture_height;
+    double fps;
+    ImgReSampleContext *img_resample_ctx; /* for image resampling/resizing */
+    ReSampleContext *audio_resample_ctx;
+    ogg_int32_t aspect_numerator;
+    ogg_int32_t aspect_denominator;
+    double    frame_aspect;
+
+    int video_quality;
+    int video_bitrate;
+    int sharpness;
+    int keyint;
+
+    double force_input_fps;
+    int sync;
+    
+    /* cropping */
+    int frame_topBand;
+    int frame_bottomBand;
+    int frame_leftBand;
+    int frame_rightBand;
+    
+    int frame_width;
+    int frame_height;
+    int frame_x_offset;
+    int frame_y_offset;
+
+    /* In seconds */
+    int start_time;
+    int end_time; 
+
+    double pts_offset; /* between given input pts and calculated output pts */
+    int64_t frame_count; /* total video frames output so far */
+    int64_t sample_count; /* total audio samples output so far */
+}
+*ff2theora;
+
+
 static double rint(double x) {
     if (x < 0.0)
         return (double)(int)(x - 0.5);
@@ -57,7 +115,7 @@
         return (double)(int)(x + 0.5);
 }
 
-theoraframes_info info;
+oggmux_info info;
 
 static int using_stdin = 0;
 
@@ -181,7 +239,7 @@
 
         this->fps = fps;
         
-        if(info.preset == V2V_PRESET_PREVIEW){
+        if(this->preset == V2V_PRESET_PREVIEW){
             // possible sizes 384/288,320/240
             int pal_width=384;
             int pal_height=288;
@@ -196,7 +254,7 @@
                 this->picture_height=ntsc_height;
             }
         }
-        else if(info.preset == V2V_PRESET_PRO){
+        else if(this->preset == V2V_PRESET_PRO){
             if(this->fps==25 && (venc->width!=720 || venc->height!=576) ){
                 this->picture_width=720;
                 this->picture_height=576;
@@ -391,7 +449,6 @@
             else {
                 info.ti.fps_numerator=vstream->r_frame_rate.num;
                 info.ti.fps_denominator = vstream->r_frame_rate.den;
-                info.fps = (double) vstream->r_frame_rate.num / vstream->r_frame_rate.den;
             }
             /* this is pixel aspect ratio */
             info.ti.aspect_numerator=this->aspect_numerator;
@@ -425,7 +482,7 @@
         info.sample_rate = this->sample_rate;
         info.vorbis_quality = this->audio_quality;
         info.vorbis_bitrate = this->audio_bitrate;
-        theoraframes_init (&info);
+        oggmux_init (&info);
         /*seek to start time*/    
 #if LIBAVFORMAT_BUILD <= 4616
         av_seek_frame( this->context, -1, (int64_t)AV_TIME_BASE*this->start_time);
@@ -446,8 +503,6 @@
         do{    
             if(no_frames > 0){
                 if(this->frame_count > no_frames){
-                    if(info.debug)
-                        fprintf(stderr,"\nreached end specified with --endtime\n");
                     break;
                 }
             }
@@ -527,13 +582,24 @@
                     }    
                     first=0;
                     //now output_resized
-                    do {
-                        if( theoraframes_add_video(this, &info, 
-                                             output_resized ,e_o_s) ){
-                            ret = -1;
-                            fprintf (stderr,"No theora frames available\n");
-                            break;
-                        }
+                    /* pysical pages */
+                    yuv_buffer yuv;
+                    /* Theora is a one-frame-in,one-frame-out system; submit a frame
+                     * for compression and pull out the packet */
+                    yuv.y_width = this->frame_width;
+                    yuv.y_height = this->frame_height;
+                    yuv.y_stride = output_resized->linesize[0];
+
+                    yuv.uv_width = this->frame_width / 2;
+                    yuv.uv_height = this->frame_height / 2;
+                    yuv.uv_stride = output_resized->linesize[1];
+
+                    yuv.y = output_resized->data[0];
+                    yuv.u = output_resized->data[1];
+                    yuv.v = output_resized->data[2];
+
+                    do {                        
+                        oggmux_add_video(&info, &yuv ,e_o_s);
                         this->frame_count++;
                     } while(dups--);
                     if(e_o_s){
@@ -569,11 +635,8 @@
                                 resampled=audio_buf;
                         }
                     }
-                    if (theoraframes_add_audio(&info, resampled, 
-                        samples_out *(this->channels),samples_out,e_o_s)){
-                        ret = -1;
-                        fprintf (stderr,"No audio frames available\n");
-                    }
+                    oggmux_add_audio(&info, resampled, 
+                        samples_out *(this->channels),samples_out,e_o_s);
                     this->sample_count += samples_out;
                     if(e_o_s && len <= 0){
                         break;
@@ -582,7 +645,7 @@
 
             }
             /* flush out the file */
-            theoraframes_flush (&info, e_o_s);
+            oggmux_flush (&info, e_o_s);
             av_free_packet (&pkt);
         }
         while (ret >= 0);
@@ -605,7 +668,7 @@
         if (this->audio_resample_ctx)
             audio_resample_close(this->audio_resample_ctx);
 
-        theoraframes_close (&info);
+        oggmux_close (&info);
     }
     else{
         fprintf (stderr, "No video or audio stream found\n");
@@ -729,7 +792,6 @@
 #ifndef _WIN32
         "\t --nice\t\t\tset niceness to n\n"
 #endif
-        "\t --debug\t\toutput some more information during encoding\n"
         "\t --help,-h\t\tthis message\n"
 
 
@@ -799,7 +861,6 @@
       {"copyright",required_argument,&metadata_flag,15},
       {"license",required_argument,&metadata_flag,16},
 
-      {"debug",0,&flag,DEBUG_FLAG},
       {"help",0,NULL,'h'},
       {NULL,0,NULL,0}
     };
@@ -825,10 +886,6 @@
                             convert->deinterlace=1;
                             flag=-1;
                             break;
-                        case DEBUG_FLAG:
-                            info.debug=1;
-                            flag=-1;
-                            break;
                         case SYNC_FLAG:
                             convert->sync=1;
                             flag=-1;
@@ -982,7 +1039,7 @@
                 }
                 else if(!strcmp(optarg, "pro")){
                     //need a way to set resize here. and not later
-                    info.preset=V2V_PRESET_PRO;
+                    convert->preset=V2V_PRESET_PRO;
                     convert->video_quality = rint(7*6.3);
                     convert->audio_quality=3*.099;
                     convert->channels=2;
@@ -991,7 +1048,7 @@
                 }
                 else if(!strcmp(optarg,"preview")){
                     //need a way to set resize here. and not later
-                    info.preset=V2V_PRESET_PREVIEW;
+                    convert->preset=V2V_PRESET_PREVIEW;
                     convert->video_quality = rint(5*6.3);
                     convert->audio_quality=1*.099;
                     convert->channels=2;
@@ -1022,7 +1079,7 @@
     //use PREVIEW as default setting
     if(argc==2){
         //need a way to set resize here. and not later
-        info.preset=V2V_PRESET_PREVIEW;
+        convert->preset=V2V_PRESET_PREVIEW;
         convert->video_quality = rint(5*6.3);
         convert->audio_quality=1*.099;
         convert->channels=2;

Modified: trunk/ffmpeg2theora/theorautils.c
===================================================================
--- trunk/ffmpeg2theora/theorautils.c	2005-08-24 20:43:57 UTC (rev 9844)
+++ trunk/ffmpeg2theora/theorautils.c	2005-08-24 21:35:54 UTC (rev 9845)
@@ -1,7 +1,7 @@
 /* -*- tab-width:4;c-file-style:"cc-mode"; -*- */
 /*
- * theorautils.c - Ogg Theora abstraction layer
- * Copyright (C) 2003-2004 <j at v2v.cc>
+ * theorautils.c - Ogg Theora/Ogg Vorbis Abstraction and Muxing
+ * Copyright (C) 2003-2005 <j at v2v.cc>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -18,8 +18,6 @@
  * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  * 
  */
-#include "common.h"
-#include "avformat.h"
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -32,7 +30,6 @@
 
 #include "theorautils.h"
 
-
 static double rint(double x)
 {
   if (x < 0.0)
@@ -41,10 +38,12 @@
     return (double)(int)(x + 0.5);
 }
 
-void init_info(theoraframes_info *info) {
+void init_info(oggmux_info *info) {
     info->videotime =  0;
     info->audiotime = 0;
-    info->debug = 0;
+    info->audio_bytesout = 0;
+    info->video_bytesout = 0;
+
     info->videopage_valid = 0;
     info->audiopage_valid = 0;
     info->audiopage_buffer_length = 0;
@@ -53,13 +52,10 @@
     info->videopage = NULL;
 }
 
-
-void theoraframes_init (theoraframes_info *info){
+void oggmux_init (oggmux_info *info){
     ogg_page og;
+    ogg_packet op;
 
-    info->audio_bytesout = 0;
-    info->video_bytesout = 0;
-
     /* yayness.  Set up Ogg output stream */
     srand (time (NULL));
     ogg_stream_init (&info->vo, rand ());    
@@ -101,8 +97,8 @@
 
     /* first packet will get its own page automatically */
     if(!info->audio_only){
-        theora_encode_header (&info->td, &info->op);
-        ogg_stream_packetin (&info->to, &info->op);
+        theora_encode_header (&info->td, &op);
+        ogg_stream_packetin (&info->to, &op);
         if (ogg_stream_pageout (&info->to, &og) != 1){
             fprintf (stderr, "Internal Ogg library error.\n");
             exit (1);
@@ -113,10 +109,10 @@
         /* create the remaining theora headers */
         /* theora_comment_init (&info->tc); is called in main() prior to parsing options */
         theora_comment_add_tag (&info->tc, "ENCODER",PACKAGE_STRING);
-        theora_encode_comment (&info->tc, &info->op);
-        ogg_stream_packetin (&info->to, &info->op);
-        theora_encode_tables (&info->td, &info->op);
-        ogg_stream_packetin (&info->to, &info->op);
+        theora_encode_comment (&info->tc, &op);
+        ogg_stream_packetin (&info->to, &op);
+        theora_encode_tables (&info->td, &op);
+        ogg_stream_packetin (&info->to, &op);
     }
     if(!info->video_only){
         ogg_packet header;
@@ -166,42 +162,23 @@
         fwrite (og.header, 1, og.header_len,info->outfile);
         fwrite (og.body, 1, og.body_len, info->outfile);
     }
-
 }
 
-
 /**    
  * adds a video frame to the encoding sink
  * if e_o_s is 1 the end of the logical bitstream will be marked.
  * @param this ff2theora struct 
- * @param info theoraframes_info
- * @param avframe AVFrame to encode
+ * @param info oggmux_info
+ * @param yuv_buffer
  * @param e_o_s 1 indicates ond of stream
  */
-int theoraframes_add_video (ff2theora this, theoraframes_info *info, AVFrame * avframe, int e_o_s){
-    /* pysical pages */
-    yuv_buffer yuv;
-    /* Theora is a one-frame-in,one-frame-out system; submit a frame
-     * for compression and pull out the packet */
-    {
-        yuv.y_width = this->frame_width;
-        yuv.y_height = this->frame_height;
-        yuv.y_stride = avframe->linesize[0];
+void oggmux_add_video (oggmux_info *info, yuv_buffer *yuv, int e_o_s){
+    ogg_packet op;
 
-        yuv.uv_width = this->frame_width / 2;
-        yuv.uv_height = this->frame_height / 2;
-        yuv.uv_stride = avframe->linesize[1];
-
-        yuv.y = avframe->data[0];
-        yuv.u = avframe->data[1];
-        yuv.v = avframe->data[2];
-
+    theora_encode_YUVin (&info->td, yuv);
+    while(theora_encode_packetout (&info->td, e_o_s, &op)) {
+      ogg_stream_packetin (&info->to, &op);
     }
-    theora_encode_YUVin (&info->td, &yuv);
-    while(theora_encode_packetout (&info->td, e_o_s, &info->op)) {
-      ogg_stream_packetin (&info->to, &info->op);
-    }
-    return 0;
 }
     
 /** 
@@ -211,7 +188,9 @@
  * @param samples samples in buffer
  * @param e_o_s 1 indicates end of stream.
  */
-int theoraframes_add_audio (theoraframes_info *info, int16_t * buffer, int bytes, int samples, int e_o_s){
+void oggmux_add_audio (oggmux_info *info, int16_t * buffer, int bytes, int samples, int e_o_s){
+    ogg_packet op;
+
     int i,j, count = 0;
     float **vorbis_buffer;
     if (bytes <= 0 && samples <= 0){
@@ -230,21 +209,18 @@
         vorbis_analysis_wrote (&info->vd, samples);
     }
     while(vorbis_analysis_blockout (&info->vd, &info->vb) == 1){
-        
         /* analysis, assume we want to use bitrate management */
         vorbis_analysis (&info->vb, NULL);
         vorbis_bitrate_addblock (&info->vb);
         
         /* weld packets into the bitstream */
-        while (vorbis_bitrate_flushpacket (&info->vd, &info->op)){
-            ogg_stream_packetin (&info->vo, &info->op);
+        while (vorbis_bitrate_flushpacket (&info->vd, &op)){
+            ogg_stream_packetin (&info->vo, &op);
         }
-
     }
-    return 0;
 }
 
-static void print_stats(theoraframes_info *info, double timebase){
+static void print_stats(oggmux_info *info, double timebase){
     int hundredths = timebase * 100 - (long) timebase * 100;
     int seconds = (long) timebase % 60;
     int minutes = ((long) timebase / 60) % 60;
@@ -255,40 +231,45 @@
     if(info->akbps<0)
         info->akbps=0;
 
-    if(info->debug==1 && !info->video_only && !info->audio_only){
-        fprintf (stderr,"\r      %d:%02d:%02d.%02d audio: %dkbps video: %dkbps diff: %.4f             ",
-         hours, minutes, seconds, hundredths,info->akbps, info->vkbps,info->audiotime-info->videotime);
-    }
-    else{
-        fprintf (stderr,"\r      %d:%02d:%02d.%02d audio: %dkbps video: %dkbps                  ",
+    fprintf (stderr,"\r      %d:%02d:%02d.%02d audio: %dkbps video: %dkbps                  ",
          hours, minutes, seconds, hundredths,info->akbps, info->vkbps);
-    }
-
 }
 
-static int write_audio_page(theoraframes_info *info)
+static int write_audio_page(oggmux_info *info)
 {
-  /* TODO: Check return values */
-  info->audio_bytesout +=
-    fwrite(info->audiopage, 1, info->audiopage_len, info->outfile);
+  int ret;
+
+  ret = fwrite(info->audiopage, 1, info->audiopage_len, info->outfile);
+  if(ret < info->audiopage_len) {
+    fprintf(stderr,"error writing audio page\n"); 
+  }
+  else {
+    info->audio_bytesout += ret;
+  }
   info->audiopage_valid = 0;
 
   info->akbps = rint (info->audio_bytesout * 8. / info->audiotime * .001);
   print_stats(info, info->audiotime);
 }
 
-static int write_video_page(theoraframes_info *info)
+static int write_video_page(oggmux_info *info)
 {
-  /* TODO: Check return values */
-  info->video_bytesout +=
-    fwrite(info->videopage, 1, info->videopage_len, info->outfile);
+  int ret;
+
+  ret = fwrite(info->videopage, 1, info->videopage_len, info->outfile);
+  if(ret < info->videopage_len) {
+    fprintf(stderr,"error writing video page\n");
+  }
+  else {
+    info->video_bytesout += ret;
+  }
   info->videopage_valid = 0;
 
   info->vkbps = rint (info->video_bytesout * 8. / info->videotime * .001);
   print_stats(info, info->videotime);
 }
 
-void theoraframes_flush (theoraframes_info *info, int e_o_s)
+void oggmux_flush (oggmux_info *info, int e_o_s)
 {
     int len;
     ogg_page og;
@@ -358,7 +339,7 @@
     }
 }
 
-void theoraframes_close (theoraframes_info *info){
+void oggmux_close (oggmux_info *info){
     ogg_stream_clear (&info->vo);
     vorbis_block_clear (&info->vb);
     vorbis_dsp_clear (&info->vd);

Modified: trunk/ffmpeg2theora/theorautils.h
===================================================================
--- trunk/ffmpeg2theora/theorautils.h	2005-08-24 20:43:57 UTC (rev 9844)
+++ trunk/ffmpeg2theora/theorautils.h	2005-08-24 21:35:54 UTC (rev 9845)
@@ -1,6 +1,7 @@
+/* -*- tab-width:4;c-file-style:"cc-mode"; -*- */
 /*
- * theorautils.h -- ogg/theora Utils for ffmpeg2ogg
- * Copyright (C) 2003 <j at v2v.cc>
+ * theorautils.h -- Ogg Theora/Ogg Vorbis Abstraction and Muxing
+ * Copyright (C) 2003-2005 <j at v2v.cc>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -23,103 +24,39 @@
 #include "vorbis/vorbisenc.h"
 #include "ogg/ogg.h"
 
-#define V2V_PRESET_PRO 1
-#define V2V_PRESET_PREVIEW 2
 
-typedef struct ff2theora{
-    AVFormatContext *context;
-    int video_index;
-    int audio_index;
-    
-    int deinterlace;
-    int audiostream;
-    int sample_rate;
-    int channels;
-    int disable_audio;
-    float audio_quality;
-    int audio_bitrate;
-    
-    int picture_width;
-    int picture_height;
-    double fps;
-    ImgReSampleContext *img_resample_ctx; /* for image resampling/resizing */
-    ReSampleContext *audio_resample_ctx;
-    ogg_int32_t aspect_numerator;
-    ogg_int32_t aspect_denominator;
-    double    frame_aspect;
-
-    int video_quality;
-    int video_bitrate;
-    int sharpness;
-    int keyint;
-
-    double force_input_fps;
-    int sync;
-    
-    /* cropping */
-    int frame_topBand;
-    int frame_bottomBand;
-    int frame_leftBand;
-    int frame_rightBand;
-    
-    int frame_width;
-    int frame_height;
-    int frame_x_offset;
-    int frame_y_offset;
-
-    /* In seconds */
-    int start_time;
-    int end_time; 
-
-    double pts_offset; /* between given input pts and calculated output pts */
-    int64_t frame_count; /* total video frames output so far */
-    int64_t sample_count; /* total audio samples output so far */
-}
-*ff2theora;
-
-
-
 typedef struct
 {
-    int debug;
-    int preset;
+    /* the file the mixed ogg stream is written to */
+    FILE *outfile;
+
     int audio_only;
     int video_only;
+
+    /* vorbis settings */
     int sample_rate;
     int channels;
     double vorbis_quality;
     int vorbis_bitrate;
-    int scale;
-    int wide;
-    double fps;
-    double start;
-    double end;
-    double audiotime;
-    double videotime;
-    int vkbps;
-    int akbps;
-    ogg_int64_t audio_bytesout;
-    ogg_int64_t video_bytesout;
 
-    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_packet op;  /* one raw packet of data for decode */
+    vorbis_info vi;       /* struct that stores all the static vorbis bitstream settings */
+    vorbis_comment vc;    /* struct that stores all the user comments */
 
+    /* theora settings */
     theora_info ti;
     theora_comment tc;
-    
-    theora_state td;
 
-
-    vorbis_info vi;       /* struct that stores all the static vorbis bitstream settings */
-    vorbis_comment vc;    /* struct that stores all the user comments */
-
+    /* state info */    
+    theora_state td;
     vorbis_dsp_state vd; /* central working state for the packet->PCM decoder */
     vorbis_block vb;     /* local working space for packet->PCM decode */
-    FILE *outfile;
 
+    /* used for muxing */
+    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 */
+
     int audiopage_valid;
     int videopage_valid;
     unsigned char *audiopage;
@@ -128,12 +65,20 @@
     int audiopage_len;
     int videopage_buffer_length;
     int audiopage_buffer_length;
+
+    /* some stats */
+    double audiotime;
+    double videotime;
+    int vkbps;
+    int akbps;
+    ogg_int64_t audio_bytesout;
+    ogg_int64_t video_bytesout;
 }
-theoraframes_info;
+oggmux_info;
 
-extern void init_info(theoraframes_info *info);
-extern void theoraframes_init (theoraframes_info *info);
-extern int theoraframes_add_video (ff2theora this, theoraframes_info *info, AVFrame *avframe, int e_o_s);
-extern int theoraframes_add_audio (theoraframes_info *info, int16_t * readbuffer, int bytesread, int samplesread,int e_o_s);
-extern void theoraframes_flush (theoraframes_info *info, int e_o_s);
-extern void theoraframes_close (theoraframes_info *info);
+extern void init_info(oggmux_info *info);
+extern void oggmux_init (oggmux_info *info);
+extern void oggmux_add_video (oggmux_info *info, yuv_buffer *yuv, int e_o_s);
+extern void oggmux_add_audio (oggmux_info *info, int16_t * readbuffer, int bytesread, int samplesread,int e_o_s);
+extern void oggmux_flush (oggmux_info *info, int e_o_s);
+extern void oggmux_close (oggmux_info *info);



More information about the commits mailing list