#include "libswscale/swscale.h"
#include "libavcodec/opt.h"
#include "libavcodec/audioconvert.h"
-#include "libavcodec/colorspace.h"
+#include "libavutil/colorspace.h"
#include "libavutil/fifo.h"
#include "libavutil/pixdesc.h"
#include "libavutil/avstring.h"
static AVMetaDataMap meta_data_maps[MAX_FILES];
static int nb_meta_data_maps;
+/* indexed by output file stream index */
+static int streamid_map[MAX_STREAMS];
+
static int frame_width = 0;
static int frame_height = 0;
static float frame_aspect_ratio = 0;
static int video_disable = 0;
static int video_discard = 0;
static char *video_codec_name = NULL;
-static int video_codec_tag = 0;
+static unsigned int video_codec_tag = 0;
static char *video_language = NULL;
static int same_quality = 0;
static int do_deinterlace = 0;
static int audio_disable = 0;
static int audio_channels = 1;
static char *audio_codec_name = NULL;
-static int audio_codec_tag = 0;
+static unsigned int audio_codec_tag = 0;
static char *audio_language = NULL;
static int subtitle_disable = 0;
static char *subtitle_codec_name = NULL;
static char *subtitle_language = NULL;
-static int subtitle_codec_tag = 0;
+static unsigned int subtitle_codec_tag = 0;
static float mux_preload= 0.5;
static float mux_max_delay= 0.7;
static int64_t recording_time = INT64_MAX;
static int64_t start_time = 0;
-static int64_t rec_timestamp = 0;
+static int64_t recording_timestamp = 0;
static int64_t input_ts_offset = 0;
static int file_overwrite = 0;
static int metadata_count;
avfilter_graph_add_filter(graph, last_filter);
}
+ snprintf(args, sizeof(args), "flags=0x%X", (int)av_get_int(sws_opts, "sws_flags", NULL));
+ graph->scale_sws_opts = av_strdup(args);
+
if (vfilters) {
AVFilterInOut *outputs = av_malloc(sizeof(AVFilterInOut));
AVFilterInOut *inputs = av_malloc(sizeof(AVFilterInOut));
return -1;
}
- snprintf(args, sizeof(args), "flags=0x%X", (int)av_get_int(sws_opts, "sws_flags", NULL));
- graph->scale_sws_opts = av_strdup(args);
-
/* configure all the filter links */
if (avfilter_graph_check_validity(graph, NULL))
return -1;
#ifdef SIGXCPU
signal(SIGXCPU, sigterm_handler);
#endif
-
-#if CONFIG_BEOS_NETSERVER
- fcntl(0, F_SETFL, fcntl(0, F_GETFL) | O_NONBLOCK);
-#endif
}
/* read a key without blocking */
#if HAVE_TERMIOS_H
int n = 1;
unsigned char ch;
-#if !CONFIG_BEOS_NETSERVER
struct timeval tv;
fd_set rfds;
tv.tv_sec = 0;
tv.tv_usec = 0;
n = select(1, &rfds, NULL, NULL, &tv);
-#endif
if (n > 0) {
n = read(0, &ch, 1);
if (n == 1)
av_free(video_standard);
-#if CONFIG_POWERPC_PERF
- void powerpc_display_perf_report(void);
- powerpc_display_perf_report();
-#endif /* CONFIG_POWERPC_PERF */
-
for (i=0;i<AVMEDIA_TYPE_NB;i++)
av_free(avcodec_opts[i]);
av_free(avformat_opts);
{
if(codec && codec->supported_samplerates){
const int *p= codec->supported_samplerates;
- int best;
+ int best=0;
int best_dist=INT_MAX;
for(; *p; p++){
int dist= abs(st->codec->sample_rate - *p);
}
if(*p == -1
&& !( st->codec->codec_id==CODEC_ID_MJPEG
- && st->codec->strict_std_compliance <= FF_COMPLIANCE_INOFFICIAL
+ && st->codec->strict_std_compliance <= FF_COMPLIANCE_UNOFFICIAL
&& ( st->codec->pix_fmt == PIX_FMT_YUV420P
|| st->codec->pix_fmt == PIX_FMT_YUV422P)))
st->codec->pix_fmt = codec->pix_fmts[0];
audio_buf_size= (allocated_for_size + isize*dec->channels - 1) / (isize*dec->channels);
audio_buf_size= (audio_buf_size*enc->sample_rate + dec->sample_rate) / dec->sample_rate;
audio_buf_size= audio_buf_size*2 + 10000; //safety factors for the deprecated resampling API
+ audio_buf_size= FFMAX(audio_buf_size, enc->frame_size);
audio_buf_size*= osize*enc->channels;
audio_out_size= FFMAX(audio_buf_size, enc->frame_size * osize * enc->channels);
void *buffer_to_free;
static unsigned int samples_size= 0;
AVSubtitle subtitle, *subtitle_to_free;
- int got_subtitle;
#if CONFIG_AVFILTER
int frame_available;
#endif
break;
case AVMEDIA_TYPE_SUBTITLE:
ret = avcodec_decode_subtitle2(ist->st->codec,
- &subtitle, &got_subtitle, &avpkt);
+ &subtitle, &got_picture, &avpkt);
if (ret < 0)
goto fail_decode;
- if (!got_subtitle) {
+ if (!got_picture) {
goto discard_packet;
}
subtitle_to_free = &subtitle;
av_free_packet(&opkt);
}
}
-#if CONFIG_AVFILTER
- frame_available = (ist->st->codec->codec_type == AVMEDIA_TYPE_VIDEO) &&
- ist->out_video_filter && avfilter_poll_frame(ist->out_video_filter->inputs[0]);
-#endif
}
#if CONFIG_AVFILTER
+ frame_available = (ist->st->codec->codec_type == AVMEDIA_TYPE_VIDEO) &&
+ ist->out_video_filter && avfilter_poll_frame(ist->out_video_filter->inputs[0]);
if(ist->picref)
avfilter_unref_pic(ist->picref);
}
int osize = av_get_bits_per_sample_format(enc->sample_fmt) >> 3;
int fs_tmp = enc->frame_size;
- av_fifo_generic_read(ost->fifo, samples, fifo_bytes, NULL);
+ av_fifo_generic_read(ost->fifo, audio_buf, fifo_bytes, NULL);
if (enc->codec->capabilities & CODEC_CAP_SMALL_LAST_FRAME) {
enc->frame_size = fifo_bytes / (osize * enc->channels);
} else { /* pad */
int frame_bytes = enc->frame_size*osize*enc->channels;
- if (samples_size < frame_bytes)
+ if (allocated_audio_buf_size < frame_bytes)
av_exit(1);
- memset((uint8_t*)samples+fifo_bytes, 0, frame_bytes - fifo_bytes);
+ memset(audio_buf+fifo_bytes, 0, frame_bytes - fifo_bytes);
}
- ret = avcodec_encode_audio(enc, bit_buffer, bit_buffer_size, samples);
+ ret = avcodec_encode_audio(enc, bit_buffer, bit_buffer_size, (short *)audio_buf);
pkt.duration = av_rescale((int64_t)enc->frame_size*ost->st->time_base.den,
ost->st->time_base.num, enc->sample_rate);
enc->frame_size = fs_tmp;
if (!os->nb_streams) {
dump_format(output_files[i], i, output_files[i]->filename, 1);
fprintf(stderr, "Output file #%d does not contain any stream\n", i);
- av_exit(1);
+ ret = AVERROR(EINVAL);
+ goto fail;
}
nb_ostreams += os->nb_streams;
}
if (nb_stream_maps > 0 && nb_stream_maps != nb_ostreams) {
fprintf(stderr, "Number of stream maps must match number of output streams\n");
- av_exit(1);
+ ret = AVERROR(EINVAL);
+ goto fail;
}
/* Sanity check the mapping args -- do the input files & streams exist? */
if (fi < 0 || fi > nb_input_files - 1 ||
si < 0 || si > file_table[fi].nb_streams - 1) {
fprintf(stderr,"Could not find input stream #%d.%d\n", fi, si);
- av_exit(1);
+ ret = AVERROR(EINVAL);
+ goto fail;
}
fi = stream_maps[i].sync_file_index;
si = stream_maps[i].sync_stream_index;
if (fi < 0 || fi > nb_input_files - 1 ||
si < 0 || si > file_table[fi].nb_streams - 1) {
fprintf(stderr,"Could not find sync stream #%d.%d\n", fi, si);
- av_exit(1);
+ ret = AVERROR(EINVAL);
+ goto fail;
}
}
codec->chroma_sample_location = icodec->chroma_sample_location;
if (ost->st->stream_copy) {
+ uint64_t extra_size = (uint64_t)icodec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE;
+
+ if (extra_size > INT_MAX)
+ goto fail;
+
/* if stream_copy is selected, no need to decode or encode */
codec->codec_id = icodec->codec_id;
codec->codec_type = icodec->codec_type;
}
codec->bit_rate = icodec->bit_rate;
- codec->extradata= icodec->extradata;
+ codec->extradata= av_mallocz(extra_size);
+ if (!codec->extradata)
+ goto fail;
+ memcpy(codec->extradata, icodec->extradata, icodec->extradata_size);
codec->extradata_size= icodec->extradata_size;
if(av_q2d(icodec->time_base)*icodec->ticks_per_frame > av_q2d(ist->st->time_base) && av_q2d(ist->st->time_base) < 1.0/1000){
codec->time_base = icodec->time_base;
codec->time_base.num *= icodec->ticks_per_frame;
+ av_reduce(&codec->time_base.num, &codec->time_base.den,
+ codec->time_base.num, codec->time_base.den, INT_MAX);
}else
codec->time_base = ist->st->time_base;
switch(codec->codec_type) {
for(i=0;i<nb_ostreams;i++) {
ost = ost_table[i];
if (ost) {
+ if (ost->st->stream_copy)
+ av_freep(&ost->st->codec->extradata);
if (ost->logfile) {
fclose(ost->logfile);
ost->logfile = NULL;
fprintf(stderr, "Vertical crop dimensions are outside the range of the original image.\nRemember to crop first and scale second.\n");
av_exit(1);
}
+ fprintf(stderr, "-crop* is deprecated in favor of the crop avfilter\n");
frame_height -= frame_topBand;
}
fprintf(stderr, "Vertical crop dimensions are outside the range of the original image.\nRemember to crop first and scale second.\n");
av_exit(1);
}
+ fprintf(stderr, "-crop* is deprecated in favor of the crop avfilter\n");
frame_height -= frame_bottomBand;
}
fprintf(stderr, "Horizontal crop dimensions are outside the range of the original image.\nRemember to crop first and scale second.\n");
av_exit(1);
}
+ fprintf(stderr, "-crop* is deprecated in favor of the crop avfilter\n");
frame_width -= frame_leftBand;
}
fprintf(stderr, "Horizontal crop dimensions are outside the range of the original image.\nRemember to crop first and scale second.\n");
av_exit(1);
}
+ fprintf(stderr, "-crop* is deprecated in favor of the crop avfilter\n");
frame_width -= frame_rightBand;
}
}
}
-static void opt_pad(const char *arg) {
- fprintf(stderr, "Please use vf=pad\n");
- av_exit(1);
+static int opt_pad(const char *opt, const char *arg) {
+ fprintf(stderr, "Option '%s' has been removed, use the pad filter instead\n", opt);
+ return -1;
}
static void opt_frame_pix_fmt(const char *arg)
return 0;
}
-static int opt_rec_timestamp(const char *opt, const char *arg)
+static int opt_recording_timestamp(const char *opt, const char *arg)
{
- rec_timestamp = parse_time_or_die(opt, arg, 0) / 1000000;
+ recording_timestamp = parse_time_or_die(opt, arg, 0) / 1000000;
return 0;
}
ret = av_find_stream_info(ic);
if (ret < 0 && verbose >= 0) {
fprintf(stderr, "%s: could not find codec parameters\n", filename);
+ av_close_input_file(ic);
av_exit(1);
}
AVCodecContext *video_enc;
enum CodecID codec_id;
- st = av_new_stream(oc, oc->nb_streams);
+ st = av_new_stream(oc, streamid_map[oc->nb_streams]);
if (!st) {
fprintf(stderr, "Could not alloc stream\n");
av_exit(1);
AVCodecContext *audio_enc;
enum CodecID codec_id;
- st = av_new_stream(oc, oc->nb_streams);
+ st = av_new_stream(oc, streamid_map[oc->nb_streams]);
if (!st) {
fprintf(stderr, "Could not alloc stream\n");
av_exit(1);
AVStream *st;
AVCodecContext *subtitle_enc;
- st = av_new_stream(oc, oc->nb_streams);
+ st = av_new_stream(oc, streamid_map[oc->nb_streams]);
if (!st) {
fprintf(stderr, "Could not alloc stream\n");
av_exit(1);
new_subtitle_stream(oc);
}
+/* arg format is "output-stream-index:streamid-value". */
+static void opt_streamid(const char *opt, const char *arg)
+{
+ int idx;
+ char *p;
+ char idx_str[16];
+
+ strncpy(idx_str, arg, sizeof(idx_str));
+ idx_str[sizeof(idx_str)-1] = '\0';
+ p = strchr(idx_str, ':');
+ if (!p) {
+ fprintf(stderr,
+ "Invalid value '%s' for option '%s', required syntax is 'index:value'\n",
+ arg, opt);
+ av_exit(1);
+ }
+ *p++ = '\0';
+ idx = parse_number_or_die(opt, idx_str, OPT_INT, 0, MAX_STREAMS-1);
+ streamid_map[idx] = parse_number_or_die(opt, p, OPT_INT, 0, INT_MAX);
+}
+
static void opt_output_file(const char *filename)
{
AVFormatContext *oc;
new_subtitle_stream(oc);
}
- oc->timestamp = rec_timestamp;
+ oc->timestamp = recording_timestamp;
for(; metadata_count>0; metadata_count--){
av_metadata_set2(&oc->metadata, metadata[metadata_count-1].key,
oc->flags |= AVFMT_FLAG_NONBLOCK;
set_context_opts(oc, avformat_opts, AV_OPT_FLAG_ENCODING_PARAM);
+
+ memset(streamid_map, 0, sizeof(streamid_map));
}
/* same option as mencoder */
{ "ss", OPT_FUNC2 | HAS_ARG, {(void*)opt_start_time}, "set the start time offset", "time_off" },
{ "itsoffset", OPT_FUNC2 | HAS_ARG, {(void*)opt_input_ts_offset}, "set the input ts offset", "time_off" },
{ "itsscale", HAS_ARG, {(void*)opt_input_ts_scale}, "set the input ts scale", "stream:scale" },
- { "timestamp", OPT_FUNC2 | HAS_ARG, {(void*)opt_rec_timestamp}, "set the timestamp ('now' to set the current time)", "time" },
+ { "timestamp", OPT_FUNC2 | HAS_ARG, {(void*)opt_recording_timestamp}, "set the recording timestamp ('now' to set the current time)", "time" },
{ "metadata", OPT_FUNC2 | HAS_ARG, {(void*)opt_metadata}, "add metadata", "string=string" },
{ "dframes", OPT_INT | HAS_ARG, {(void*)&max_frames[AVMEDIA_TYPE_DATA]}, "set the number of data frames to record", "number" },
{ "benchmark", OPT_BOOL | OPT_EXPERT, {(void*)&do_benchmark},
{ "s", HAS_ARG | OPT_VIDEO, {(void*)opt_frame_size}, "set frame size (WxH or abbreviation)", "size" },
{ "aspect", HAS_ARG | OPT_VIDEO, {(void*)opt_frame_aspect_ratio}, "set aspect ratio (4:3, 16:9 or 1.3333, 1.7777)", "aspect" },
{ "pix_fmt", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_frame_pix_fmt}, "set pixel format, 'list' as argument shows all the pixel formats supported", "format" },
- { "croptop", HAS_ARG | OPT_VIDEO, {(void*)opt_frame_crop_top}, "set top crop band size (in pixels)", "size" },
- { "cropbottom", HAS_ARG | OPT_VIDEO, {(void*)opt_frame_crop_bottom}, "set bottom crop band size (in pixels)", "size" },
- { "cropleft", HAS_ARG | OPT_VIDEO, {(void*)opt_frame_crop_left}, "set left crop band size (in pixels)", "size" },
- { "cropright", HAS_ARG | OPT_VIDEO, {(void*)opt_frame_crop_right}, "set right crop band size (in pixels)", "size" },
- { "padtop", HAS_ARG | OPT_VIDEO, {(void*)opt_pad}, "set top pad band size (in pixels)", "size" },
- { "padbottom", HAS_ARG | OPT_VIDEO, {(void*)opt_pad}, "set bottom pad band size (in pixels)", "size" },
- { "padleft", HAS_ARG | OPT_VIDEO, {(void*)opt_pad}, "set left pad band size (in pixels)", "size" },
- { "padright", HAS_ARG | OPT_VIDEO, {(void*)opt_pad}, "set right pad band size (in pixels)", "size" },
- { "padcolor", HAS_ARG | OPT_VIDEO, {(void*)opt_pad}, "set color of pad bands (Hex 000000 thru FFFFFF)", "color" },
+ { "croptop", HAS_ARG | OPT_VIDEO, {(void*)opt_frame_crop_top}, "Deprecated, please use the crop avfilter", "size" },
+ { "cropbottom", HAS_ARG | OPT_VIDEO, {(void*)opt_frame_crop_bottom}, "Deprecated, please use the crop avfilter", "size" },
+ { "cropleft", HAS_ARG | OPT_VIDEO, {(void*)opt_frame_crop_left}, "Deprecated, please use the crop avfilter", "size" },
+ { "cropright", HAS_ARG | OPT_VIDEO, {(void*)opt_frame_crop_right}, "Deprecated, please use the crop avfilter", "size" },
+ { "padtop", OPT_FUNC2 | HAS_ARG | OPT_VIDEO, {(void*)opt_pad}, "Removed, use the pad filter instead", "size" },
+ { "padbottom", OPT_FUNC2 | HAS_ARG | OPT_VIDEO, {(void*)opt_pad}, "Removed, use the pad filter instead", "size" },
+ { "padleft", OPT_FUNC2 | HAS_ARG | OPT_VIDEO, {(void*)opt_pad}, "Removed, use the pad filter instead", "size" },
+ { "padright", OPT_FUNC2 | HAS_ARG | OPT_VIDEO, {(void*)opt_pad}, "Removed, use the pad filter instead", "size" },
+ { "padcolor", OPT_FUNC2 | HAS_ARG | OPT_VIDEO, {(void*)opt_pad}, "Removed, use the pad filter instead", "color" },
{ "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" },
{ "vlang", HAS_ARG | OPT_STRING | OPT_VIDEO, {(void *)&video_language}, "set the ISO 639 language code (3 letters) of the current video stream" , "code" },
{ "qphist", OPT_BOOL | OPT_EXPERT | OPT_VIDEO, { (void *)&qp_hist }, "show QP histogram" },
{ "force_fps", OPT_BOOL | OPT_EXPERT | OPT_VIDEO, {(void*)&force_fps}, "force the selected framerate, disable the best supported framerate selection" },
+ { "streamid", OPT_FUNC2 | HAS_ARG | OPT_EXPERT, {(void*)opt_streamid}, "set the value of an outfile streamid", "streamIndex:value" },
/* audio options */
{ "ab", OPT_FUNC2 | HAS_ARG | OPT_AUDIO, {(void*)opt_bitrate}, "set bitrate (in bits/s)", "bitrate" },