aboutsummaryrefslogtreecommitdiffstats
path: root/ffmpeg.c
diff options
context:
space:
mode:
authorMichael Niedermayer <michaelni@gmx.at>2011-06-21 05:22:40 +0200
committerMichael Niedermayer <michaelni@gmx.at>2011-06-21 05:27:44 +0200
commit779d7610c71d267a88c787affd91000b826e812e (patch)
tree197be42d44c8fdf16b3f4fbdf12ad1e5e0f6de18 /ffmpeg.c
parent56629aa0127e7f8f2f5dad3ebe794424b51afd64 (diff)
parentd39b33c63bc080231d8d6e79c6301a60b86150de (diff)
downloadffmpeg-779d7610c71d267a88c787affd91000b826e812e.tar.gz
Merge branch 'master' into oldabi
* master: (109 commits) libx264: fix open gop default. Please use -x264opts to force open gop This fixes Ticket268 avfilter picture pool: double free hotfix mpegaudio_parser: be less picky on the start position ppc32: Fix movrel Replace usages of av_get_bits_per_sample_fmt() with av_get_bytes_per_sample(). x86: cabac: fix register constraints for 32-bit mode cabac: move x86 asm to libavcodec/x86/cabac.h x86: h264: cast pointers to intptr_t rather than int x86: h264: remove hardcoded edi in decode_significance_8x8_x86() x86: h264: remove hardcoded esi in decode_significance[_8x8]_x86() x86: h264: remove hardcoded edx in decode_significance[_8x8]_x86() x86: h264: remove hardcoded eax in decode_significance[_8x8]_x86() x86: cabac: change 'a' constraint to 'r' in get_cabac_inline() x86: cabac: remove hardcoded esi in get_cabac_inline() x86: cabac: remove hardcoded edx in get_cabac_inline() x86: cabac: remove unused macro parameter x86: cabac: remove hardcoded ebx in inline asm x86: cabac: remove hardcoded struct offsets from inline asm cabac: remove inline asm under #if 0 cabac: remove BRANCHLESS_CABAC_DECODER switch ... Conflicts: cmdutils.c ffserver.c libavfilter/avfilter.h libavformat/avformat.h libavformat/utils.c libavformat/version.h libavutil/avutil.h Merged-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'ffmpeg.c')
-rw-r--r--ffmpeg.c91
1 files changed, 53 insertions, 38 deletions
diff --git a/ffmpeg.c b/ffmpeg.c
index c21cb5a604..2fab0b56f4 100644
--- a/ffmpeg.c
+++ b/ffmpeg.c
@@ -51,6 +51,7 @@
# include "libavfilter/avcodec.h"
# include "libavfilter/avfilter.h"
# include "libavfilter/avfiltergraph.h"
+# include "libavfilter/vsink_buffer.h"
# include "libavfilter/vsrc_buffer.h"
#endif
@@ -124,9 +125,7 @@ static int nb_input_codecs = 0;
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;
@@ -278,6 +277,8 @@ typedef struct AVOutputStream {
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 */
@@ -365,7 +366,7 @@ static int configure_video_filters(AVInputStream *ist, AVOutputStream *ost)
/** 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;
@@ -385,8 +386,8 @@ static int configure_video_filters(AVInputStream *ist, AVOutputStream *ost)
"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;
@@ -556,7 +557,6 @@ static int ffmpeg_exit(int ret)
av_free(streamid_map);
av_free(input_codecs);
- av_free(output_codecs);
av_free(stream_maps);
av_free(meta_data_maps);
@@ -620,6 +620,8 @@ static void choose_sample_fmt(AVStream *st, AVCodec *codec)
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),
@@ -809,8 +811,8 @@ static void do_audio_out(AVFormatContext *s,
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:
@@ -1530,7 +1532,7 @@ static int output_packet(AVInputStream *ist, int ist_index,
#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;
@@ -1708,12 +1710,15 @@ static int output_packet(AVInputStream *ist, int ist_index,
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];
@@ -2263,6 +2268,8 @@ static int transcode(AVFormatContext **output_files,
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);
@@ -2274,7 +2281,7 @@ static int transcode(AVFormatContext **output_files,
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)
codec->channels = icodec->channels;
@@ -2289,6 +2296,10 @@ static int transcode(AVFormatContext **output_files,
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);
@@ -2299,6 +2310,10 @@ static int transcode(AVFormatContext **output_files,
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;
@@ -2307,11 +2322,16 @@ static int transcode(AVFormatContext **output_files,
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)) {
@@ -2375,10 +2395,8 @@ static int transcode(AVFormatContext **output_files,
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);
@@ -3399,17 +3417,12 @@ static int opt_input_file(const char *opt, const char *filename)
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;
@@ -3454,9 +3467,12 @@ static int opt_input_file(const char *opt, const char *filename)
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;
@@ -3526,13 +3542,12 @@ static void new_video_stream(AVFormatContext *oc, int file_idx)
}
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);
@@ -3581,8 +3596,6 @@ static void new_video_stream(AVFormatContext *oc, int file_idx)
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) {
@@ -3669,13 +3682,12 @@ static void new_audio_stream(AVFormatContext *oc, int file_idx)
}
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);
@@ -3741,7 +3753,6 @@ static void new_data_stream(AVFormatContext *oc, int file_idx)
}
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);
@@ -3781,12 +3792,12 @@ static void new_subtitle_stream(AVFormatContext *oc, int file_idx)
}
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);
@@ -3990,6 +4001,8 @@ static int opt_output_file(const char *opt, const char *filename)
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;
@@ -4226,6 +4239,7 @@ 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");
@@ -4248,6 +4262,7 @@ static int opt_target(const char *opt, const char *arg)
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");