You've already forked FFmpeg
mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-08-10 06:10:52 +02:00
added two pass support (same syntax as mencoder)
Originally committed as revision 1020 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
75
ffmpeg.c
75
ffmpeg.c
@@ -141,6 +141,10 @@ static int do_play = 0;
|
|||||||
static int do_psnr = 0;
|
static int do_psnr = 0;
|
||||||
static int do_vstats = 0;
|
static int do_vstats = 0;
|
||||||
static int mpeg_vcd = 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
|
#ifndef CONFIG_AUDIO_OSS
|
||||||
const char *audio_device = "none";
|
const char *audio_device = "none";
|
||||||
@@ -165,6 +169,7 @@ typedef struct AVOutputStream {
|
|||||||
int audio_resample;
|
int audio_resample;
|
||||||
ReSampleContext *resample; /* for audio resampling */
|
ReSampleContext *resample; /* for audio resampling */
|
||||||
FifoBuffer fifo; /* for compression: one audio fifo per codec */
|
FifoBuffer fifo; /* for compression: one audio fifo per codec */
|
||||||
|
FILE *logfile;
|
||||||
} AVOutputStream;
|
} AVOutputStream;
|
||||||
|
|
||||||
typedef struct AVInputStream {
|
typedef struct AVInputStream {
|
||||||
@@ -546,6 +551,10 @@ static void do_video_out(AVFormatContext *s,
|
|||||||
//fprintf(stderr,"\nFrame: %3d %3d size: %5d type: %d",
|
//fprintf(stderr,"\nFrame: %3d %3d size: %5d type: %d",
|
||||||
// enc->frame_number-1, enc->real_pict_num, ret,
|
// enc->frame_number-1, enc->real_pict_num, ret,
|
||||||
// enc->pict_type);
|
// enc->pict_type);
|
||||||
|
/* if two pass, output log */
|
||||||
|
if (ost->logfile && enc->stats_out) {
|
||||||
|
fprintf(ost->logfile, "%s", enc->stats_out);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
write_picture(s, ost->index, picture, enc->pix_fmt, enc->width, enc->height);
|
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:
|
default:
|
||||||
av_abort();
|
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 */
|
/* open each encoder */
|
||||||
@@ -1245,6 +1293,7 @@ static int av_encode(AVFormatContext **output_files,
|
|||||||
for(i=0;i<nb_ostreams;i++) {
|
for(i=0;i<nb_ostreams;i++) {
|
||||||
ost = ost_table[i];
|
ost = ost_table[i];
|
||||||
if (ost->encoding_needed) {
|
if (ost->encoding_needed) {
|
||||||
|
av_freep(&ost->st->codec.stats_in);
|
||||||
avcodec_close(&ost->st->codec);
|
avcodec_close(&ost->st->codec);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1280,6 +1329,10 @@ static int av_encode(AVFormatContext **output_files,
|
|||||||
for(i=0;i<nb_ostreams;i++) {
|
for(i=0;i<nb_ostreams;i++) {
|
||||||
ost = ost_table[i];
|
ost = ost_table[i];
|
||||||
if (ost) {
|
if (ost) {
|
||||||
|
if (ost->logfile) {
|
||||||
|
fclose(ost->logfile);
|
||||||
|
ost->logfile = NULL;
|
||||||
|
}
|
||||||
fifo_free(&ost->fifo); /* works even if fifo is not
|
fifo_free(&ost->fifo); /* works even if fifo is not
|
||||||
initialized but set to zero */
|
initialized but set to zero */
|
||||||
av_free(ost->pict_tmp.data[0]);
|
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->get_psnr = 0;
|
||||||
|
|
||||||
video_enc->me_method = me_method;
|
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 */
|
/* XXX: need to find a way to set codec parameters */
|
||||||
if (oc->oformat->flags & AVFMT_RGB24) {
|
if (oc->oformat->flags & AVFMT_RGB24) {
|
||||||
@@ -2128,6 +2190,17 @@ void prepare_play(void)
|
|||||||
opt_output_file(audio_device);
|
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
|
#ifndef CONFIG_WIN32
|
||||||
INT64 getutime(void)
|
INT64 getutime(void)
|
||||||
@@ -2265,6 +2338,8 @@ const OptionDef options[] = {
|
|||||||
{ "author", HAS_ARG | OPT_STRING, {(void*)&str_author}, "set the author", "string" },
|
{ "author", HAS_ARG | OPT_STRING, {(void*)&str_author}, "set the author", "string" },
|
||||||
{ "copyright", HAS_ARG | OPT_STRING, {(void*)&str_copyright}, "set the copyright", "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" },
|
{ "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 */
|
/* video options */
|
||||||
{ "b", HAS_ARG, {(void*)opt_video_bitrate}, "set video bitrate (in kbit/s)", "bitrate" },
|
{ "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" },
|
{ "r", HAS_ARG, {(void*)opt_frame_rate}, "set frame rate (in Hz)", "rate" },
|
||||||
|
Reference in New Issue
Block a user