aboutsummaryrefslogtreecommitdiffstats
path: root/ffmpeg.c
diff options
context:
space:
mode:
authorFabrice Bellard <fabrice@bellard.org>2002-10-10 17:09:01 +0000
committerFabrice Bellard <fabrice@bellard.org>2002-10-10 17:09:01 +0000
commit5abdb4b199dae804b25ab319e54fa55f882c69d6 (patch)
treee5f13f28fc952ed1ec6f7351206fe6d02d8e505b /ffmpeg.c
parent4973397975851f0e811cb532f5914926eb74df88 (diff)
downloadffmpeg-5abdb4b199dae804b25ab319e54fa55f882c69d6.tar.gz
added two pass support (same syntax as mencoder)
Originally committed as revision 1020 to svn://svn.ffmpeg.org/ffmpeg/trunk
Diffstat (limited to 'ffmpeg.c')
-rw-r--r--ffmpeg.c75
1 files changed, 75 insertions, 0 deletions
diff --git a/ffmpeg.c b/ffmpeg.c
index e2b24b17d4..a3f9ca2f0b 100644
--- a/ffmpeg.c
+++ b/ffmpeg.c
@@ -141,6 +141,10 @@ static int do_play = 0;
static int do_psnr = 0;
static int do_vstats = 0;
static int mpeg_vcd = 0;
+static int do_pass = 0;
+static char *pass_logfilename = NULL;
+
+#define DEFAULT_PASS_LOGFILENAME "ffmpeg2pass"
#ifndef CONFIG_AUDIO_OSS
const char *audio_device = "none";
@@ -165,6 +169,7 @@ typedef struct AVOutputStream {
int audio_resample;
ReSampleContext *resample; /* for audio resampling */
FifoBuffer fifo; /* for compression: one audio fifo per codec */
+ FILE *logfile;
} AVOutputStream;
typedef struct AVInputStream {
@@ -546,6 +551,10 @@ static void do_video_out(AVFormatContext *s,
//fprintf(stderr,"\nFrame: %3d %3d size: %5d type: %d",
// enc->frame_number-1, enc->real_pict_num, ret,
// enc->pict_type);
+ /* if two pass, output log */
+ if (ost->logfile && enc->stats_out) {
+ fprintf(ost->logfile, "%s", enc->stats_out);
+ }
} else {
write_picture(s, ost->index, picture, enc->pix_fmt, enc->width, enc->height);
}
@@ -842,6 +851,45 @@ static int av_encode(AVFormatContext **output_files,
default:
av_abort();
}
+ /* two pass mode */
+ if (ost->encoding_needed &&
+ (codec->flags & (CODEC_FLAG_PASS1 | CODEC_FLAG_PASS2))) {
+ char logfilename[1024];
+ FILE *f;
+ int size;
+ char *logbuffer;
+
+ snprintf(logfilename, sizeof(logfilename), "%s-%d.log",
+ pass_logfilename ?
+ pass_logfilename : DEFAULT_PASS_LOGFILENAME, i);
+ if (codec->flags & CODEC_FLAG_PASS1) {
+ f = fopen(logfilename, "w");
+ if (!f) {
+ perror(logfilename);
+ exit(1);
+ }
+ ost->logfile = f;
+ } else {
+ /* read the log file */
+ f = fopen(logfilename, "r");
+ if (!f) {
+ perror(logfilename);
+ exit(1);
+ }
+ fseek(f, 0, SEEK_END);
+ size = ftell(f);
+ fseek(f, 0, SEEK_SET);
+ logbuffer = av_malloc(size + 1);
+ if (!logbuffer) {
+ fprintf(stderr, "Could not allocate log buffer\n");
+ exit(1);
+ }
+ fread(logbuffer, 1, size, f);
+ fclose(f);
+ logbuffer[size] = '\0';
+ codec->stats_in = logbuffer;
+ }
+ }
}
/* open each encoder */
@@ -1245,6 +1293,7 @@ static int av_encode(AVFormatContext **output_files,
for(i=0;i<nb_ostreams;i++) {
ost = ost_table[i];
if (ost->encoding_needed) {
+ av_freep(&ost->st->codec.stats_in);
avcodec_close(&ost->st->codec);
}
}
@@ -1280,6 +1329,10 @@ static int av_encode(AVFormatContext **output_files,
for(i=0;i<nb_ostreams;i++) {
ost = ost_table[i];
if (ost) {
+ if (ost->logfile) {
+ fclose(ost->logfile);
+ ost->logfile = NULL;
+ }
fifo_free(&ost->fifo); /* works even if fifo is not
initialized but set to zero */
av_free(ost->pict_tmp.data[0]);
@@ -1942,6 +1995,15 @@ void opt_output_file(const char *filename)
video_enc->get_psnr = 0;
video_enc->me_method = me_method;
+
+ /* two pass mode */
+ if (do_pass) {
+ if (do_pass == 1) {
+ video_enc->flags |= CODEC_FLAG_PASS1;
+ } else {
+ video_enc->flags |= CODEC_FLAG_PASS2;
+ }
+ }
/* XXX: need to find a way to set codec parameters */
if (oc->oformat->flags & AVFMT_RGB24) {
@@ -2128,6 +2190,17 @@ void prepare_play(void)
opt_output_file(audio_device);
}
+/* same option as mencoder */
+void opt_pass(const char *pass_str)
+{
+ int pass;
+ pass = atoi(pass_str);
+ if (pass != 1 && pass != 2) {
+ fprintf(stderr, "pass number can be only 1 or 2\n");
+ exit(1);
+ }
+ do_pass = pass;
+}
#ifndef CONFIG_WIN32
INT64 getutime(void)
@@ -2265,6 +2338,8 @@ const OptionDef options[] = {
{ "author", HAS_ARG | OPT_STRING, {(void*)&str_author}, "set the author", "string" },
{ "copyright", HAS_ARG | OPT_STRING, {(void*)&str_copyright}, "set the copyright", "string" },
{ "comment", HAS_ARG | OPT_STRING, {(void*)&str_comment}, "set the comment", "string" },
+ { "pass", HAS_ARG, {(void*)&opt_pass}, "select the pass number (1 or 2)", "n" },
+ { "passlogfile", HAS_ARG | OPT_STRING, {(void*)&pass_logfilename}, "select two pass log file name", "file" },
/* video options */
{ "b", HAS_ARG, {(void*)opt_video_bitrate}, "set video bitrate (in kbit/s)", "bitrate" },
{ "r", HAS_ARG, {(void*)opt_frame_rate}, "set frame rate (in Hz)", "rate" },