[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