* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-/* needed for usleep() */
-#define _XOPEN_SOURCE 600
-
#include "config.h"
#include <ctype.h>
#include <string.h>
#include <sys/select.h>
#endif
-#if HAVE_KBHIT
-#include <conio.h>
-#endif
#include <time.h>
#include "cmdutils.h"
static int qp_hist = 0;
#if CONFIG_AVFILTER
static char *vfilters = NULL;
-static AVFilterGraph *graph = NULL;
#endif
static int intra_only = 0;
static int using_stdin = 0;
static int verbose = 1;
static int thread_count= 1;
-static int q_pressed = 0;
static int64_t video_size = 0;
static int64_t audio_size = 0;
static int64_t extra_size = 0;
int resample_width;
int resample_pix_fmt;
- /* full frame size of first frame */
- int original_height;
- int original_width;
+ float frame_aspect_ratio;
/* forced key frames */
int64_t *forced_kf_pts;
AVFifoBuffer *fifo; /* for compression: one audio fifo per codec */
FILE *logfile;
+#if CONFIG_AVFILTER
+ AVFilterContext *output_video_filter;
+ AVFilterContext *input_video_filter;
+ AVFilterBufferRef *picref;
+ char *avfilter;
+ AVFilterGraph *graph;
+#endif
+
int sws_flags;
} AVOutputStream;
int showed_multi_packet_warning;
int is_past_recording_time;
#if CONFIG_AVFILTER
- AVFilterContext *output_video_filter;
- AVFilterContext *input_video_filter;
AVFrame *filter_frame;
int has_filter_frame;
- AVFilterBufferRef *picref;
#endif
} AVInputStream;
char args[255];
int ret;
- graph = avfilter_graph_alloc();
+ ost->graph = avfilter_graph_alloc();
if (ist->st->sample_aspect_ratio.num){
sample_aspect_ratio = ist->st->sample_aspect_ratio;
ist->st->codec->height, ist->st->codec->pix_fmt, 1, AV_TIME_BASE,
sample_aspect_ratio.num, sample_aspect_ratio.den);
- ret = avfilter_graph_create_filter(&ist->input_video_filter, avfilter_get_by_name("buffer"),
- "src", args, NULL, graph);
+ ret = avfilter_graph_create_filter(&ost->input_video_filter, avfilter_get_by_name("buffer"),
+ "src", args, NULL, ost->graph);
if (ret < 0)
return ret;
- ret = avfilter_graph_create_filter(&ist->output_video_filter, &ffsink,
- "out", NULL, &ffsink_ctx, graph);
+ ret = avfilter_graph_create_filter(&ost->output_video_filter, &ffsink,
+ "out", NULL, &ffsink_ctx, ost->graph);
if (ret < 0)
return ret;
- last_filter = ist->input_video_filter;
+ last_filter = ost->input_video_filter;
if (codec->width != icodec->width || codec->height != icodec->height) {
snprintf(args, 255, "%d:%d:flags=0x%X",
codec->height,
ost->sws_flags);
if ((ret = avfilter_graph_create_filter(&filter, avfilter_get_by_name("scale"),
- NULL, args, NULL, graph)) < 0)
+ NULL, args, NULL, ost->graph)) < 0)
return ret;
if ((ret = avfilter_link(last_filter, 0, filter, 0)) < 0)
return ret;
}
snprintf(args, sizeof(args), "flags=0x%X", ost->sws_flags);
- graph->scale_sws_opts = av_strdup(args);
+ ost->graph->scale_sws_opts = av_strdup(args);
- if (vfilters) {
+ if (ost->avfilter) {
AVFilterInOut *outputs = av_malloc(sizeof(AVFilterInOut));
AVFilterInOut *inputs = av_malloc(sizeof(AVFilterInOut));
outputs->next = NULL;
inputs->name = av_strdup("out");
- inputs->filter_ctx = ist->output_video_filter;
+ inputs->filter_ctx = ost->output_video_filter;
inputs->pad_idx = 0;
inputs->next = NULL;
- if ((ret = avfilter_graph_parse(graph, vfilters, inputs, outputs, NULL)) < 0)
+ if ((ret = avfilter_graph_parse(ost->graph, ost->avfilter, inputs, outputs, NULL)) < 0)
return ret;
- av_freep(&vfilters);
+ av_freep(&ost->avfilter);
} else {
- if ((ret = avfilter_link(last_filter, 0, ist->output_video_filter, 0)) < 0)
+ if ((ret = avfilter_link(last_filter, 0, ost->output_video_filter, 0)) < 0)
return ret;
}
- if ((ret = avfilter_graph_config(graph, NULL)) < 0)
+ if ((ret = avfilter_graph_config(ost->graph, NULL)) < 0)
return ret;
- codec->width = ist->output_video_filter->inputs[0]->w;
- codec->height = ist->output_video_filter->inputs[0]->h;
+ codec->width = ost->output_video_filter->inputs[0]->w;
+ codec->height = ost->output_video_filter->inputs[0]->h;
codec->sample_aspect_ratio = ost->st->sample_aspect_ratio =
- ist->output_video_filter->inputs[0]->sample_aspect_ratio;
+ ost->frame_aspect_ratio ? // overriden by the -aspect cli option
+ av_d2q(ost->frame_aspect_ratio*codec->height/codec->width, 255) :
+ ost->output_video_filter->inputs[0]->sample_aspect_ratio;
return 0;
}
#endif
}
-/* read a key without blocking */
-static int read_key(void)
-{
-#if HAVE_KBHIT
- if(kbhit())
- return(getch());
-#endif
- return -1;
-}
-
static int decode_interrupt_cb(void)
{
- return q_pressed || (q_pressed = read_key() == 'q');
+ return received_sigterm;
}
static int ffmpeg_exit(int ret)
}
}
+/**
+ * Update the requested input sample format based on the output sample format.
+ * This is currently only used to request float output from decoders which
+ * support multiple sample formats, one of which is AV_SAMPLE_FMT_FLT.
+ * Ideally this will be removed in the future when decoders do not do format
+ * conversion and only output in their native format.
+ */
+static void update_sample_fmt(AVCodecContext *dec, AVCodec *dec_codec,
+ AVCodecContext *enc)
+{
+ /* if sample formats match or a decoder sample format has already been
+ requested, just return */
+ if (enc->sample_fmt == dec->sample_fmt ||
+ dec->request_sample_fmt > AV_SAMPLE_FMT_NONE)
+ return;
+
+ /* if decoder supports more than one output format */
+ if (dec_codec && dec_codec->sample_fmts &&
+ dec_codec->sample_fmts[0] != AV_SAMPLE_FMT_NONE &&
+ dec_codec->sample_fmts[1] != AV_SAMPLE_FMT_NONE) {
+ enum AVSampleFormat *p;
+ int min_dec = -1, min_inc = -1;
+
+ /* find a matching sample format in the encoder */
+ for (p = dec_codec->sample_fmts; *p != AV_SAMPLE_FMT_NONE; p++) {
+ if (*p == enc->sample_fmt) {
+ dec->request_sample_fmt = *p;
+ return;
+ } else if (*p > enc->sample_fmt) {
+ min_inc = FFMIN(min_inc, *p - enc->sample_fmt);
+ } else
+ min_dec = FFMIN(min_dec, enc->sample_fmt - *p);
+ }
+
+ /* if none match, provide the one that matches quality closest */
+ dec->request_sample_fmt = min_inc > 0 ? enc->sample_fmt + min_inc :
+ enc->sample_fmt - min_dec;
+ }
+}
+
static void choose_sample_rate(AVStream *st, AVCodec *codec)
{
if(codec && codec->supported_samplerates){
if(*p == st->codec->pix_fmt)
break;
}
- if(*p == -1)
+ if (*p == -1) {
+ if(st->codec->pix_fmt != PIX_FMT_NONE)
+ av_log(NULL, AV_LOG_WARNING,
+ "Incompatible pixel format '%s' for codec '%s', auto-selecting format '%s'\n",
+ av_pix_fmt_descriptors[st->codec->pix_fmt].name,
+ codec->name,
+ av_pix_fmt_descriptors[codec->pix_fmts[0]].name);
st->codec->pix_fmt = codec->pix_fmts[0];
+ }
}
}
ffmpeg_exit(1);
}
- if (enc->channels != dec->channels)
+ if (enc->channels != dec->channels || enc->sample_rate != dec->sample_rate)
ost->audio_resample = 1;
resample_changed = ost->resample_sample_fmt != dec->sample_fmt ||
ost->resample_sample_rate == enc->sample_rate) {
ost->resample = NULL;
ost->audio_resample = 0;
- } else {
+ } else if (ost->audio_resample) {
if (dec->sample_fmt != AV_SAMPLE_FMT_S16)
fprintf(stderr, "Warning, using s16 intermediate sample format for resampling\n");
ost->resample = av_audio_resample_init(enc->channels, dec->channels,
AVFrame *in_picture,
int *frame_size)
{
- int nb_frames, i, ret;
- AVFrame *final_picture, *formatted_picture, *resampling_dst, *padding_src;
+ int nb_frames, i, ret, resample_changed;
+ AVFrame *final_picture, *formatted_picture, *resampling_dst;
AVCodecContext *enc, *dec;
double sync_ipts;
formatted_picture = in_picture;
final_picture = formatted_picture;
- padding_src = formatted_picture;
resampling_dst = &ost->pict_tmp;
- if ( ost->resample_height != ist->st->codec->height
- || ost->resample_width != ist->st->codec->width
- || (ost->resample_pix_fmt!= ist->st->codec->pix_fmt) ) {
+ resample_changed = ost->resample_width != dec->width ||
+ ost->resample_height != dec->height ||
+ ost->resample_pix_fmt != dec->pix_fmt;
- fprintf(stderr,"Input Stream #%d.%d frame size changed to %dx%d, %s\n", ist->file_index, ist->index, ist->st->codec->width, ist->st->codec->height,avcodec_get_pix_fmt_name(ist->st->codec->pix_fmt));
+ if (resample_changed) {
+ av_log(NULL, AV_LOG_INFO,
+ "Input stream #%d.%d frame changed from size:%dx%d fmt:%s to size:%dx%d fmt:%s\n",
+ ist->file_index, ist->index,
+ ost->resample_width, ost->resample_height, avcodec_get_pix_fmt_name(ost->resample_pix_fmt),
+ dec->width , dec->height , avcodec_get_pix_fmt_name(dec->pix_fmt));
if(!ost->video_resample)
ffmpeg_exit(1);
}
#if !CONFIG_AVFILTER
if (ost->video_resample) {
- padding_src = NULL;
final_picture = &ost->pict_tmp;
- if( ost->resample_height != ist->st->codec->height
- || ost->resample_width != ist->st->codec->width
- || (ost->resample_pix_fmt!= ist->st->codec->pix_fmt) ) {
-
+ if (resample_changed) {
/* initialize a new scaler context */
sws_freeContext(ost->img_resample_ctx);
ost->img_resample_ctx = sws_getContext(
ti1 = 1e10;
vid = 0;
for(i=0;i<nb_ostreams;i++) {
+ float q = -1;
ost = ost_table[i];
enc = ost->st->codec;
+ if (!ost->st->stream_copy && enc->coded_frame)
+ q = enc->coded_frame->quality/(float)FF_QP2LAMBDA;
if (vid && enc->codec_type == AVMEDIA_TYPE_VIDEO) {
- snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "q=%2.1f ",
- !ost->st->stream_copy ?
- enc->coded_frame->quality/(float)FF_QP2LAMBDA : -1);
+ snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "q=%2.1f ", q);
}
if (!vid && enc->codec_type == AVMEDIA_TYPE_VIDEO) {
float t = (av_gettime()-timer_start) / 1000000.0;
frame_number = ost->frame_number;
snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "frame=%5d fps=%3d q=%3.1f ",
- frame_number, (t>1)?(int)(frame_number/t+0.5) : 0,
- !ost->st->stream_copy ?
- enc->coded_frame->quality/(float)FF_QP2LAMBDA : -1);
+ frame_number, (t>1)?(int)(frame_number/t+0.5) : 0, q);
if(is_last_report)
snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "L");
if(qp_hist){
int j;
- int qp= lrintf(enc->coded_frame->quality/(float)FF_QP2LAMBDA);
+ int qp = lrintf(q);
if(qp>=0 && qp<FF_ARRAY_ELEMS(qp_histogram))
qp_histogram[qp]++;
for(j=0; j<32; j++)
if (ti1 < 0.01)
ti1 = 0.01;
- if (verbose || is_last_report) {
+ if (verbose > 0 || is_last_report) {
bitrate = (double)(total_size * 8) / ti1 / 1000.0;
snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),
AVFormatContext *os;
AVOutputStream *ost;
int ret, i;
- int got_picture;
+ int got_output;
AVFrame picture;
- void *buffer_to_free;
+ void *buffer_to_free = NULL;
static unsigned int samples_size= 0;
AVSubtitle subtitle, *subtitle_to_free;
int64_t pkt_pts = AV_NOPTS_VALUE;
pkt_pts = av_rescale_q(pkt->pts, ist->st->time_base, AV_TIME_BASE_Q);
//while we have more to decode or while the decoder did output something on EOF
- while (avpkt.size > 0 || (!pkt && ist->next_pts != ist->pts)) {
+ while (avpkt.size > 0 || (!pkt && got_output)) {
uint8_t *data_buf, *decoded_data_buf;
int data_size, decoded_data_size;
handle_eof:
avpkt.data += ret;
avpkt.size -= ret;
data_size = ret;
+ got_output = decoded_data_size > 0;
/* Some bug in mpeg audio decoder gives */
/* decoded_data_size < 0, it seems they are overflows */
- if (decoded_data_size <= 0) {
+ if (!got_output) {
/* no audio frame */
continue;
}
pkt_pts = AV_NOPTS_VALUE;
ret = avcodec_decode_video2(ist->st->codec,
- &picture, &got_picture, &avpkt);
+ &picture, &got_output, &avpkt);
ist->st->quality= picture.quality;
if (ret < 0)
goto fail_decode;
- if (!got_picture) {
+ if (!got_output) {
/* no picture yet */
goto discard_packet;
}
ist->st->codec->time_base.den;
}
avpkt.size = 0;
+ buffer_to_free = NULL;
+ pre_process_video_frame(ist, (AVPicture *)&picture, &buffer_to_free);
break;
case AVMEDIA_TYPE_SUBTITLE:
ret = avcodec_decode_subtitle2(ist->st->codec,
- &subtitle, &got_picture, &avpkt);
+ &subtitle, &got_output, &avpkt);
if (ret < 0)
goto fail_decode;
- if (!got_picture) {
+ if (!got_output) {
goto discard_packet;
}
subtitle_to_free = &subtitle;
avpkt.size = 0;
}
- buffer_to_free = NULL;
- if (ist->st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
- pre_process_video_frame(ist, (AVPicture *)&picture,
- &buffer_to_free);
- }
-
#if CONFIG_AVFILTER
- if (ist->st->codec->codec_type == AVMEDIA_TYPE_VIDEO && ist->input_video_filter) {
- AVRational sar;
- if (ist->st->sample_aspect_ratio.num) sar = ist->st->sample_aspect_ratio;
- else sar = ist->st->codec->sample_aspect_ratio;
- // add it to be filtered
- av_vsrc_buffer_add_frame(ist->input_video_filter, &picture,
- ist->pts,
- sar);
+ if (ist->st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
+ for (i = 0; i < nb_ostreams; i++) {
+ ost = ost_table[i];
+ if (ost->input_video_filter && ost->source_index == ist_index) {
+ AVRational sar;
+ if (ist->st->sample_aspect_ratio.num)
+ sar = ist->st->sample_aspect_ratio;
+ else
+ sar = ist->st->codec->sample_aspect_ratio;
+ // add it to be filtered
+ av_vsrc_buffer_add_frame(ost->input_video_filter, &picture,
+ ist->pts,
+ sar);
+ }
+ }
}
#endif
if (pts > now)
usleep(pts - now);
}
-#if CONFIG_AVFILTER
- frame_available = ist->st->codec->codec_type != AVMEDIA_TYPE_VIDEO ||
- !ist->output_video_filter || avfilter_poll_frame(ist->output_video_filter->inputs[0]);
-#endif
/* if output time reached then transcode raw format,
encode packets and output them */
if (start_time == 0 || ist->pts >= start_time)
-#if CONFIG_AVFILTER
- while (frame_available) {
- AVRational ist_pts_tb;
- if (ist->st->codec->codec_type == AVMEDIA_TYPE_VIDEO && ist->output_video_filter)
- get_filtered_video_frame(ist->output_video_filter, &picture, &ist->picref, &ist_pts_tb);
- if (ist->picref)
- ist->pts = av_rescale_q(ist->picref->pts, ist_pts_tb, AV_TIME_BASE_Q);
-#endif
for(i=0;i<nb_ostreams;i++) {
int frame_size;
ost = ost_table[i];
if (ost->source_index == ist_index) {
+#if CONFIG_AVFILTER
+ frame_available = ist->st->codec->codec_type != AVMEDIA_TYPE_VIDEO ||
+ !ost->output_video_filter || avfilter_poll_frame(ost->output_video_filter->inputs[0]);
+ while (frame_available) {
+ AVRational ist_pts_tb;
+ if (ist->st->codec->codec_type == AVMEDIA_TYPE_VIDEO && ost->output_video_filter)
+ get_filtered_video_frame(ost->output_video_filter, &picture, &ost->picref, &ist_pts_tb);
+ if (ost->picref)
+ ist->pts = av_rescale_q(ost->picref->pts, ist_pts_tb, AV_TIME_BASE_Q);
+#endif
os = output_files[ost->file_index];
/* set the input output pts pairs */
break;
case AVMEDIA_TYPE_VIDEO:
#if CONFIG_AVFILTER
- if (ist->picref->video)
- ost->st->codec->sample_aspect_ratio = ist->picref->video->pixel_aspect;
+ if (ost->picref->video && !ost->frame_aspect_ratio)
+ ost->st->codec->sample_aspect_ratio = ost->picref->video->pixel_aspect;
#endif
do_video_out(os, ost, ist, &picture, &frame_size);
if (vstats_filename && frame_size)
av_init_packet(&opkt);
if ((!ost->frame_number && !(pkt->flags & AV_PKT_FLAG_KEY)) && !copy_initial_nonkeyframes)
+#if !CONFIG_AVFILTER
continue;
+#else
+ goto cont;
+#endif
/* no reencoding needed : output the packet directly */
/* force the input stream PTS */
ost->frame_number++;
av_free_packet(&opkt);
}
+#if CONFIG_AVFILTER
+ cont:
+ frame_available = (ist->st->codec->codec_type == AVMEDIA_TYPE_VIDEO) &&
+ ost->output_video_filter && avfilter_poll_frame(ost->output_video_filter->inputs[0]);
+ if (ost->picref)
+ avfilter_unref_buffer(ost->picref);
+ }
+#endif
}
}
-#if CONFIG_AVFILTER
- frame_available = (ist->st->codec->codec_type == AVMEDIA_TYPE_VIDEO) &&
- ist->output_video_filter && avfilter_poll_frame(ist->output_video_filter->inputs[0]);
- if(ist->picref)
- avfilter_unref_buffer(ist->picref);
- }
-#endif
av_free(buffer_to_free);
/* XXX: allocate the subtitles in the codec ? */
if (subtitle_to_free) {
AVInputStream *ist, **ist_table = NULL;
AVInputFile *file_table;
char error[1024];
- int key;
int want_sdp = 1;
uint8_t no_packet[MAX_FILES]={0};
int no_packet_count=0;
codec->width = icodec->width;
codec->height = icodec->height;
codec->has_b_frames = icodec->has_b_frames;
+ if (!codec->sample_aspect_ratio.num) {
+ codec->sample_aspect_ratio =
+ ost->st->sample_aspect_ratio =
+ ist->st->sample_aspect_ratio.num ? ist->st->sample_aspect_ratio :
+ ist->st->codec->sample_aspect_ratio.num ?
+ ist->st->codec->sample_aspect_ratio : (AVRational){0, 1};
+ }
break;
case AVMEDIA_TYPE_SUBTITLE:
codec->width = icodec->width;
fprintf(stderr, "Video pixel format is unknown, stream cannot be encoded\n");
ffmpeg_exit(1);
}
- ost->video_resample = (codec->width != icodec->width ||
- codec->height != icodec->height ||
- (codec->pix_fmt != icodec->pix_fmt));
+ ost->video_resample = codec->width != icodec->width ||
+ codec->height != icodec->height ||
+ codec->pix_fmt != icodec->pix_fmt;
if (ost->video_resample) {
#if !CONFIG_AVFILTER
avcodec_get_frame_defaults(&ost->pict_tmp);
fprintf(stderr, "Cannot get resampling context\n");
ffmpeg_exit(1);
}
-
- ost->original_height = icodec->height;
- ost->original_width = icodec->width;
#endif
codec->bits_per_raw_sample= 0;
}
ret = AVERROR(EINVAL);
goto dump_format;
}
+
+ /* update requested sample format for the decoder based on the
+ corresponding encoder sample format */
+ for (j = 0; j < nb_ostreams; j++) {
+ ost = ost_table[j];
+ if (ost->source_index == i) {
+ update_sample_fmt(ist->st->codec, codec, ost->st->codec);
+ break;
+ }
+ }
+
if (avcodec_open(ist->st->codec, codec) < 0) {
snprintf(error, sizeof(error), "Error while opening decoder for input stream #%d.%d",
ist->file_index, ist->index);
print_sdp(output_files, nb_output_files);
}
- if (!using_stdin && verbose >= 0) {
-#if HAVE_KBHIT
- fprintf(stderr, "Press [q] to stop encoding\n");
-#else
+ if (verbose >= 0)
fprintf(stderr, "Press ctrl-c to stop encoding\n");
-#endif
- avio_set_interrupt_cb(decode_interrupt_cb);
- }
term_init();
timer_start = av_gettime();
redo:
ipts_min= 1e100;
opts_min= 1e100;
- /* if 'q' pressed, exits */
- if (!using_stdin) {
- if (q_pressed)
- break;
- /* read_key() returns 0 on EOF */
- key = read_key();
- if (key == 'q')
- break;
- }
/* select the stream that we must read now by looking at the
smallest output pts */
av_freep(&ost->st->codec->stats_in);
avcodec_close(ost->st->codec);
}
+#if CONFIG_AVFILTER
+ avfilter_graph_free(&ost->graph);
+#endif
}
/* close each decoder */
avcodec_close(ist->st->codec);
}
}
-#if CONFIG_AVFILTER
- avfilter_graph_free(&graph);
-#endif
/* finished ! */
ret = 0;
ffmpeg_exit(1);
}
frame_aspect_ratio = ar;
-
-#if CONFIG_AVFILTER
- x = vfilters ? strlen(vfilters) : 0;
- vfilters = av_realloc(vfilters, x+100);
- snprintf(vfilters+x, x+100, "%csetdar=%f\n", x?',':' ', ar);
-#endif
}
static int opt_metadata(const char *opt, const char *arg)
return 0;
}
-static void opt_qscale(const char *arg)
+static int opt_qscale(const char *opt, const char *arg)
{
- video_qscale = atof(arg);
- if (video_qscale <= 0 ||
- video_qscale > 255) {
+ video_qscale = parse_number_or_die(opt, arg, OPT_FLOAT, 0, 255);
+ if (video_qscale == 0) {
fprintf(stderr, "qscale must be > 0.0 and <= 255\n");
- ffmpeg_exit(1);
+ return AVERROR(EINVAL);
}
+ return 0;
}
-static void opt_top_field_first(const char *arg)
+static int opt_top_field_first(const char *opt, const char *arg)
{
- top_field_first= atoi(arg);
+ top_field_first = parse_number_or_die(opt, arg, OPT_INT, 0, 1);
+ return 0;
}
static int opt_thread_count(const char *opt, const char *arg)
return 0;
}
-static void opt_video_channel(const char *arg)
+static int opt_video_channel(const char *opt, const char *arg)
{
- video_channel = strtol(arg, NULL, 0);
+ video_channel = parse_number_or_die(opt, arg, OPT_INT64, 0, INT_MAX);
+ return 0;
}
static void opt_video_standard(const char *arg)
ic->loop_input = loop_input;
+ /* Set AVCodecContext options so they will be seen by av_find_stream_info() */
+ for (i = 0; i < ic->nb_streams; i++) {
+ AVCodecContext *dec = ic->streams[i]->codec;
+ switch (dec->codec_type) {
+ case AVMEDIA_TYPE_AUDIO:
+ set_context_opts(dec, avcodec_opts[AVMEDIA_TYPE_AUDIO],
+ AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_DECODING_PARAM,
+ NULL);
+ break;
+ case AVMEDIA_TYPE_VIDEO:
+ set_context_opts(dec, avcodec_opts[AVMEDIA_TYPE_VIDEO],
+ AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM,
+ NULL);
+ break;
+ }
+ }
+
/* If not enough info to get the stream parameters, we decode the
first frames to get it. (used in mpeg case for example) */
ret = av_find_stream_info(ic);
set_context_opts(dec, avcodec_opts[AVMEDIA_TYPE_VIDEO], AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM, input_codecs[nb_input_codecs-1]);
frame_height = dec->height;
frame_width = dec->width;
- if(ic->streams[i]->sample_aspect_ratio.num)
- frame_aspect_ratio=av_q2d(ic->streams[i]->sample_aspect_ratio);
- else
- frame_aspect_ratio=av_q2d(dec->sample_aspect_ratio);
- frame_aspect_ratio *= (float) dec->width / dec->height;
frame_pix_fmt = dec->pix_fmt;
rfps = ic->streams[i]->r_frame_rate.num;
rfps_base = ic->streams[i]->r_frame_rate.den;
codec_id = av_guess_codec(oc->oformat, NULL, oc->filename, NULL, AVMEDIA_TYPE_VIDEO);
codec = avcodec_find_encoder(codec_id);
}
+
+ ost->frame_aspect_ratio = frame_aspect_ratio;
+ frame_aspect_ratio = 0;
+#if CONFIG_AVFILTER
+ ost->avfilter= vfilters;
+ vfilters = NULL;
+#endif
}
avcodec_get_context_defaults3(st->codec, codec);
video_enc->width = frame_width;
video_enc->height = frame_height;
- video_enc->sample_aspect_ratio = av_d2q(frame_aspect_ratio*video_enc->height/video_enc->width, 255);
video_enc->pix_fmt = frame_pix_fmt;
st->sample_aspect_ratio = video_enc->sample_aspect_ratio;
}
/* same option as mencoder */
-static void opt_pass(const char *pass_str)
+static int opt_pass(const char *opt, const char *arg)
{
- int pass;
- pass = atoi(pass_str);
- if (pass != 1 && pass != 2) {
- fprintf(stderr, "pass number can be only 1 or 2\n");
- ffmpeg_exit(1);
- }
- do_pass = pass;
+ do_pass = parse_number_or_die(opt, arg, OPT_INT, 1, 2);
+ return 0;
}
static int64_t getutime(void)
}
}
}
- if(verbose && norm != UNKNOWN)
+ if(verbose > 0 && norm != UNKNOWN)
fprintf(stderr, "Assuming %s for target.\n", norm == PAL ? "PAL" : "NTSC");
}
{ "intra", OPT_BOOL | OPT_EXPERT | OPT_VIDEO, {(void*)&intra_only}, "use only intra frames"},
{ "vn", OPT_BOOL | OPT_VIDEO, {(void*)&video_disable}, "disable video" },
{ "vdt", OPT_INT | HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)&video_discard}, "discard threshold", "n" },
- { "qscale", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_qscale}, "use fixed video quantizer scale (VBR)", "q" },
+ { "qscale", HAS_ARG | OPT_FUNC2 | OPT_EXPERT | OPT_VIDEO, {(void*)opt_qscale}, "use fixed video quantizer scale (VBR)", "q" },
{ "rc_override", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_video_rc_override_string}, "rate control override for specific intervals", "override" },
{ "vcodec", HAS_ARG | OPT_VIDEO, {(void*)opt_video_codec}, "force video codec ('copy' to copy stream)", "codec" },
{ "me_threshold", HAS_ARG | OPT_FUNC2 | OPT_EXPERT | OPT_VIDEO, {(void*)opt_me_threshold}, "motion estimaton threshold", "threshold" },
{ "sameq", OPT_BOOL | OPT_VIDEO, {(void*)&same_quality},
"use same quantizer as source (implies VBR)" },
- { "pass", HAS_ARG | OPT_VIDEO, {(void*)&opt_pass}, "select the pass number (1 or 2)", "n" },
+ { "pass", HAS_ARG | OPT_FUNC2 | OPT_VIDEO, {(void*)opt_pass}, "select the pass number (1 or 2)", "n" },
{ "passlogfile", HAS_ARG | OPT_STRING | OPT_VIDEO, {(void*)&pass_logfilename_prefix}, "select two pass log file name prefix", "prefix" },
{ "deinterlace", OPT_BOOL | OPT_EXPERT | OPT_VIDEO, {(void*)&do_deinterlace},
"deinterlace pictures" },
#endif
{ "intra_matrix", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_intra_matrix}, "specify intra matrix coeffs", "matrix" },
{ "inter_matrix", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_inter_matrix}, "specify inter matrix coeffs", "matrix" },
- { "top", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_top_field_first}, "top=1/bottom=0/auto=-1 field first", "" },
+ { "top", HAS_ARG | OPT_FUNC2 | OPT_EXPERT | OPT_VIDEO, {(void*)opt_top_field_first}, "top=1/bottom=0/auto=-1 field first", "" },
{ "dc", OPT_INT | HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)&intra_dc_precision}, "intra_dc_precision", "precision" },
{ "vtag", OPT_FUNC2 | HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_codec_tag}, "force video tag/fourcc", "fourcc/tag" },
{ "newvideo", OPT_VIDEO | OPT_FUNC2, {(void*)opt_new_stream}, "add a new video stream to the current output stream" },
{ "stag", OPT_FUNC2 | HAS_ARG | OPT_EXPERT | OPT_SUBTITLE, {(void*)opt_codec_tag}, "force subtitle tag/fourcc", "fourcc/tag" },
/* grab options */
- { "vc", HAS_ARG | OPT_EXPERT | OPT_VIDEO | OPT_GRAB, {(void*)opt_video_channel}, "set video grab channel (DV1394 only)", "channel" },
+ { "vc", HAS_ARG | OPT_FUNC2 | OPT_EXPERT | OPT_VIDEO | OPT_GRAB, {(void*)opt_video_channel}, "set video grab channel (DV1394 only)", "channel" },
{ "tvstd", HAS_ARG | OPT_EXPERT | OPT_VIDEO | OPT_GRAB, {(void*)opt_video_standard}, "set television standard (NTSC, PAL (SECAM))", "standard" },
{ "isync", OPT_BOOL | OPT_EXPERT | OPT_GRAB, {(void*)&input_sync}, "sync read on input", "" },
#endif
av_register_all();
-#if HAVE_ISATTY
- if(isatty(STDIN_FILENO))
- avio_set_interrupt_cb(decode_interrupt_cb);
-#endif
+ avio_set_interrupt_cb(decode_interrupt_cb);
init_opts();