# include "libavfilter/avcodec.h"
# include "libavfilter/avfilter.h"
# include "libavfilter/avfiltergraph.h"
+# include "libavfilter/vsink_buffer.h"
# include "libavfilter/vsrc_buffer.h"
#endif
static int nb_input_files_ts_scale[MAX_FILES] = {0};
static AVFormatContext *output_files[MAX_FILES];
-static AVCodec **output_codecs = NULL;
static int nb_output_files = 0;
-static int nb_output_codecs = 0;
static AVStreamMap *stream_maps = NULL;
static int nb_stream_maps;
struct AVInputStream *sync_ist; /* input stream to sync against */
int64_t sync_opts; /* output frame counter, could be changed to some true timestamp */ //FIXME look at frame_number
AVBitStreamFilterContext *bitstream_filters;
+ AVCodec *enc;
+
/* video only */
int video_resample;
AVFrame resample_frame; /* temporary frame for image resampling */
/** filter graph containing all filters including input & output */
AVCodecContext *codec = ost->st->codec;
AVCodecContext *icodec = ist->st->codec;
- FFSinkContext ffsink_ctx = { .pix_fmt = codec->pix_fmt };
+ enum PixelFormat pix_fmts[] = { codec->pix_fmt, PIX_FMT_NONE };
AVRational sample_aspect_ratio;
char args[255];
int ret;
"src", args, NULL, ost->graph);
if (ret < 0)
return ret;
- ret = avfilter_graph_create_filter(&ost->output_video_filter, &ffsink,
- "out", NULL, &ffsink_ctx, ost->graph);
+ ret = avfilter_graph_create_filter(&ost->output_video_filter, avfilter_get_by_name("buffersink"),
+ "out", NULL, pix_fmts, ost->graph);
if (ret < 0)
return ret;
last_filter = ost->input_video_filter;
static void term_exit(void)
{
- av_log(NULL, AV_LOG_QUIET, "");
+ av_log(NULL, AV_LOG_QUIET, "%s", "");
#if HAVE_TERMIOS_H
if(!run_as_daemon)
tcsetattr (0, TCSANOW, &oldtty);
av_free(streamid_map);
av_free(input_codecs);
- av_free(output_codecs);
av_free(stream_maps);
av_free(meta_data_maps);
break;
}
if (*p == -1) {
+ if((codec->capabilities & CODEC_CAP_LOSSLESS) && av_get_sample_fmt_name(st->codec->sample_fmt) > av_get_sample_fmt_name(codec->sample_fmts[0]))
+ av_log(NULL, AV_LOG_ERROR, "Convertion will not be lossless'\n");
av_log(NULL, AV_LOG_WARNING,
"Incompatible sample format '%s' for codec '%s', auto-selecting format '%s'\n",
av_get_sample_fmt_name(st->codec->sample_fmt),
int size_out, frame_bytes, ret, resample_changed;
AVCodecContext *enc= ost->st->codec;
AVCodecContext *dec= ist->st->codec;
- int osize= av_get_bits_per_sample_fmt(enc->sample_fmt)/8;
- int isize= av_get_bits_per_sample_fmt(dec->sample_fmt)/8;
+ int osize = av_get_bytes_per_sample(enc->sample_fmt);
+ int isize = av_get_bytes_per_sample(dec->sample_fmt);
const int coded_bps = av_get_bits_per_sample(enc->codec->id);
need_realloc:
#endif
AVPacket avpkt;
- int bps = av_get_bits_per_sample_fmt(ist->st->codec->sample_fmt)>>3;
+ int bps = av_get_bytes_per_sample(ist->st->codec->sample_fmt);
if(ist->next_pts == AV_NOPTS_VALUE)
ist->next_pts= ist->pts;
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)
- if (get_filtered_video_frame(ost->output_video_filter, &picture, &ost->picref, &ist_pts_tb) < 0)
+ if (ist->st->codec->codec_type == AVMEDIA_TYPE_VIDEO && ost->output_video_filter) {
+ AVRational ist_pts_tb = ost->output_video_filter->inputs[0]->time_base;
+ if (av_vsink_buffer_get_video_buffer_ref(ost->output_video_filter, &ost->picref, 0) < 0)
goto cont;
- if (ost->picref)
- ist->pts = av_rescale_q(ost->picref->pts, ist_pts_tb, AV_TIME_BASE_Q);
+ if (ost->picref) {
+ avfilter_fill_frame_from_video_buffer_ref(&picture, ost->picref);
+ ist->pts = av_rescale_q(ost->picref->pts, ist_pts_tb, AV_TIME_BASE_Q);
+ }
+ }
#endif
os = output_files[ost->file_index];
abort();
}
} else {
+ if (!ost->enc)
+ ost->enc = avcodec_find_encoder(ost->st->codec->codec_id);
switch(codec->codec_type) {
case AVMEDIA_TYPE_AUDIO:
ost->fifo= av_fifo_alloc(1024);
if (icodec->lowres)
codec->sample_rate >>= icodec->lowres;
}
- choose_sample_rate(ost->st, codec->codec);
+ choose_sample_rate(ost->st, ost->enc);
codec->time_base = (AVRational){1, codec->sample_rate};
- if (!codec->channels)
+ if (!codec->channels) {
codec->channels = icodec->channels;
+ codec->channel_layout = icodec->channel_layout;
+ }
if (av_get_channel_layout_nb_channels(codec->channel_layout) != codec->channels)
codec->channel_layout = 0;
ost->audio_resample = codec->sample_rate != icodec->sample_rate || audio_sync_method > 1;
ost->resample_channels = icodec->channels;
break;
case AVMEDIA_TYPE_VIDEO:
+ if (codec->pix_fmt == PIX_FMT_NONE)
+ codec->pix_fmt = icodec->pix_fmt;
+ choose_pixel_fmt(ost->st, ost->enc);
+
if (ost->st->codec->pix_fmt == PIX_FMT_NONE) {
fprintf(stderr, "Video pixel format is unknown, stream cannot be encoded\n");
ffmpeg_exit(1);
if (ost->video_resample) {
codec->bits_per_raw_sample= frame_bits_per_raw_sample;
}
+ if (!codec->width || !codec->height) {
+ codec->width = icodec->width;
+ codec->height = icodec->height;
+ }
ost->resample_height = icodec->height;
ost->resample_width = icodec->width;
ost->resample_pix_fmt= icodec->pix_fmt;
if (!ost->frame_rate.num)
ost->frame_rate = ist->st->r_frame_rate.num ? ist->st->r_frame_rate : (AVRational){25,1};
- if (codec->codec && codec->codec->supported_framerates && !force_fps) {
- int idx = av_find_nearest_q_idx(ost->frame_rate, codec->codec->supported_framerates);
- ost->frame_rate = codec->codec->supported_framerates[idx];
+ if (ost->enc && ost->enc->supported_framerates && !force_fps) {
+ int idx = av_find_nearest_q_idx(ost->frame_rate, ost->enc->supported_framerates);
+ ost->frame_rate = ost->enc->supported_framerates[idx];
}
codec->time_base = (AVRational){ost->frame_rate.den, ost->frame_rate.num};
+ if( av_q2d(codec->time_base) < 0.001 && video_sync_method
+ && (video_sync_method==1 || (video_sync_method<0 && !(os->oformat->flags & AVFMT_VARIABLE_FPS)))){
+ av_log(os, AV_LOG_WARNING, "Frame rate very high for a muxer not effciciently supporting it.\n"
+ "Please consider specifiying a lower framerate, a different muxer or -vsync 2\n");
+ }
#if CONFIG_AVFILTER
if (configure_video_filters(ist, ost)) {
for(i=0;i<nb_ostreams;i++) {
ost = ost_table[i];
if (ost->encoding_needed) {
- AVCodec *codec = i < nb_output_codecs ? output_codecs[i] : NULL;
+ AVCodec *codec = ost->enc;
AVCodecContext *dec = input_streams[ost->source_index].st->codec;
- if (!codec)
- codec = avcodec_find_encoder(ost->st->codec->codec_id);
if (!codec) {
snprintf(error, sizeof(error), "Encoder (codec id %d) not found for output stream #%d.%d",
ost->st->codec->codec_id, ost->file_index, ost->index);
return AVERROR(EINVAL);
}
} else {
- show_pix_fmts();
+ opt_pix_fmts(NULL, NULL);
ffmpeg_exit(0);
}
return 0;
if(!input_codecs[nb_input_codecs-1])
input_codecs[nb_input_codecs-1] = avcodec_find_decoder(dec->codec_id);
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;
- frame_pix_fmt = dec->pix_fmt;
rfps = ic->streams[i]->r_frame_rate.num;
rfps_base = ic->streams[i]->r_frame_rate.den;
if (dec->lowres) {
dec->flags |= CODEC_FLAG_EMU_EDGE;
- frame_height >>= dec->lowres;
- frame_width >>= dec->lowres;
- dec->height = frame_height;
- dec->width = frame_width;
+ dec->height >>= dec->lowres;
+ dec->width >>= dec->lowres;
}
if(me_threshold)
dec->debug |= FF_DEBUG_MV;
input_files[nb_input_files - 1].ctx = ic;
input_files[nb_input_files - 1].ist_index = nb_input_streams - ic->nb_streams;
- video_channel = 0;
top_field_first = -1;
+ video_channel = 0;
frame_rate = (AVRational){0, 0};
+ frame_pix_fmt = PIX_FMT_NONE;
+ frame_height = 0;
+ frame_width = 0;
audio_sample_rate = 0;
audio_channels = 0;
}
ost = new_output_stream(oc, file_idx);
- output_codecs = grow_array(output_codecs, sizeof(*output_codecs), &nb_output_codecs, nb_output_codecs + 1);
if(!video_stream_copy){
if (video_codec_name) {
codec_id = find_codec_or_die(video_codec_name, AVMEDIA_TYPE_VIDEO, 1,
avcodec_opts[AVMEDIA_TYPE_VIDEO]->strict_std_compliance);
codec = avcodec_find_encoder_by_name(video_codec_name);
- output_codecs[nb_output_codecs-1] = codec;
+ ost->enc = codec;
} else {
codec_id = av_guess_codec(oc->oformat, NULL, oc->filename, NULL, AVMEDIA_TYPE_VIDEO);
codec = avcodec_find_encoder(codec_id);
video_enc->bits_per_raw_sample = frame_bits_per_raw_sample;
st->sample_aspect_ratio = video_enc->sample_aspect_ratio;
- choose_pixel_fmt(st, codec);
-
if (intra_only)
video_enc->gop_size = 0;
if (video_qscale || same_quality) {
}
ost = new_output_stream(oc, file_idx);
- output_codecs = grow_array(output_codecs, sizeof(*output_codecs), &nb_output_codecs, nb_output_codecs + 1);
if(!audio_stream_copy){
if (audio_codec_name) {
codec_id = find_codec_or_die(audio_codec_name, AVMEDIA_TYPE_AUDIO, 1,
avcodec_opts[AVMEDIA_TYPE_AUDIO]->strict_std_compliance);
codec = avcodec_find_encoder_by_name(audio_codec_name);
- output_codecs[nb_output_codecs-1] = codec;
+ ost->enc = codec;
} else {
codec_id = av_guess_codec(oc->oformat, NULL, oc->filename, NULL, AVMEDIA_TYPE_AUDIO);
codec = avcodec_find_encoder(codec_id);
}
new_output_stream(oc, file_idx);
data_enc = st->codec;
- output_codecs = grow_array(output_codecs, sizeof(*output_codecs), &nb_output_codecs, nb_output_codecs + 1);
if (!data_stream_copy) {
fprintf(stderr, "Data stream encoding not supported yet (only streamcopy)\n");
ffmpeg_exit(1);
}
ost = new_output_stream(oc, file_idx);
subtitle_enc = st->codec;
- output_codecs = grow_array(output_codecs, sizeof(*output_codecs), &nb_output_codecs, nb_output_codecs + 1);
if(!subtitle_stream_copy){
if (subtitle_codec_name) {
codec_id = find_codec_or_die(subtitle_codec_name, AVMEDIA_TYPE_SUBTITLE, 1,
avcodec_opts[AVMEDIA_TYPE_SUBTITLE]->strict_std_compliance);
- codec= output_codecs[nb_output_codecs-1] = avcodec_find_encoder_by_name(subtitle_codec_name);
+ codec = avcodec_find_encoder_by_name(subtitle_codec_name);
+ ost->enc = codec;
} else {
codec_id = av_guess_codec(oc->oformat, NULL, oc->filename, NULL, AVMEDIA_TYPE_SUBTITLE);
codec = avcodec_find_encoder(codec_id);
set_context_opts(oc, avformat_opts, AV_OPT_FLAG_ENCODING_PARAM, NULL);
frame_rate = (AVRational){0, 0};
+ frame_width = 0;
+ frame_height = 0;
audio_sample_rate = 0;
audio_channels = 0;
}
}
-static void opt_inter_matrix(const char *arg)
+static int opt_inter_matrix(const char *opt, const char *arg)
{
inter_matrix = av_mallocz(sizeof(uint16_t) * 64);
parse_matrix_coeffs(inter_matrix, arg);
+ return 0;
}
-static void opt_intra_matrix(const char *arg)
+static int opt_intra_matrix(const char *opt, const char *arg)
{
intra_matrix = av_mallocz(sizeof(uint16_t) * 64);
parse_matrix_coeffs(intra_matrix, arg);
+ return 0;
}
static void show_usage(void)
printf("\n");
}
-static void show_help(void)
+static int opt_help(const char *opt, const char *arg)
{
AVCodec *c;
AVOutputFormat *oformat = NULL;
}
av_opt_show2(sws_opts, NULL, AV_OPT_FLAG_ENCODING_PARAM|AV_OPT_FLAG_DECODING_PARAM, 0);
+ return 0;
}
static int opt_target(const char *opt, const char *arg)
opt_frame_size("s", norm == PAL ? "480x576" : "480x480");
opt_frame_rate("r", frame_rates[norm]);
+ opt_frame_pix_fmt("pix_fmt", "yuv420p");
opt_default("g", norm == PAL ? "15" : "18");
opt_default("b", "2040000");
opt_frame_size("vcodec", norm == PAL ? "720x576" : "720x480");
opt_frame_rate("r", frame_rates[norm]);
+ opt_frame_pix_fmt("pix_fmt", "yuv420p");
opt_default("g", norm == PAL ? "15" : "18");
opt_default("b", "6000000");
{
}
-static void opt_passlogfile(const char *arg)
+static int opt_passlogfile(const char *opt, const char *arg)
{
pass_logfilename_prefix = arg;
opt_default("passlogfile", arg);
+ return 0;
}
static const OptionDef options[] = {