|
|
|
@ -27,6 +27,7 @@ |
|
|
|
|
#include "libavcodec/internal.h" |
|
|
|
|
#include "libavutil/opt.h" |
|
|
|
|
#include "libavutil/dict.h" |
|
|
|
|
#include "libavutil/pixdesc.h" |
|
|
|
|
#include "metadata.h" |
|
|
|
|
#include "id3v2.h" |
|
|
|
|
#include "libavutil/avstring.h" |
|
|
|
@ -388,6 +389,47 @@ static int set_codec_from_probe_data(AVFormatContext *s, AVStream *st, AVProbeDa |
|
|
|
|
/************************************************************/ |
|
|
|
|
/* input media file */ |
|
|
|
|
|
|
|
|
|
#if FF_API_FORMAT_PARAMETERS |
|
|
|
|
static AVDictionary *convert_format_parameters(AVFormatParameters *ap) |
|
|
|
|
{ |
|
|
|
|
char buf[1024]; |
|
|
|
|
AVDictionary *opts = NULL; |
|
|
|
|
|
|
|
|
|
if (ap->time_base.num) { |
|
|
|
|
snprintf(buf, sizeof(buf), "%d/%d", ap->time_base.den, ap->time_base.num); |
|
|
|
|
av_dict_set(&opts, "framerate", buf, 0); |
|
|
|
|
} |
|
|
|
|
if (ap->sample_rate) { |
|
|
|
|
snprintf(buf, sizeof(buf), "%d", ap->sample_rate); |
|
|
|
|
av_dict_set(&opts, "sample_rate", buf, 0); |
|
|
|
|
} |
|
|
|
|
if (ap->channels) { |
|
|
|
|
snprintf(buf, sizeof(buf), "%d", ap->channels); |
|
|
|
|
av_dict_set(&opts, "channels", buf, 0); |
|
|
|
|
} |
|
|
|
|
if (ap->width || ap->height) { |
|
|
|
|
snprintf(buf, sizeof(buf), "%dx%d", ap->width, ap->height); |
|
|
|
|
av_dict_set(&opts, "video_size", buf, 0); |
|
|
|
|
} |
|
|
|
|
if (ap->pix_fmt != PIX_FMT_NONE) { |
|
|
|
|
av_dict_set(&opts, "pixel_format", av_get_pix_fmt_name(ap->pix_fmt), 0); |
|
|
|
|
} |
|
|
|
|
if (ap->channel) { |
|
|
|
|
snprintf(buf, sizeof(buf), "%d", ap->channel); |
|
|
|
|
av_dict_set(&opts, "channel", buf, 0); |
|
|
|
|
} |
|
|
|
|
if (ap->standard) { |
|
|
|
|
av_dict_set(&opts, "standard", ap->standard, 0); |
|
|
|
|
} |
|
|
|
|
if (ap->mpeg2ts_compute_pcr) { |
|
|
|
|
av_dict_set(&opts, "mpeg2ts_compute_pcr", "1", 0); |
|
|
|
|
} |
|
|
|
|
if (ap->initial_pause) { |
|
|
|
|
av_dict_set(&opts, "initial_pause", "1", 0); |
|
|
|
|
} |
|
|
|
|
return opts; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Open a media file from an IO stream. 'fmt' must be specified. |
|
|
|
|
*/ |
|
|
|
@ -396,6 +438,7 @@ int av_open_input_stream(AVFormatContext **ic_ptr, |
|
|
|
|
AVInputFormat *fmt, AVFormatParameters *ap) |
|
|
|
|
{ |
|
|
|
|
int err; |
|
|
|
|
AVDictionary *opts; |
|
|
|
|
AVFormatContext *ic; |
|
|
|
|
AVFormatParameters default_ap; |
|
|
|
|
|
|
|
|
@ -403,6 +446,7 @@ int av_open_input_stream(AVFormatContext **ic_ptr, |
|
|
|
|
ap=&default_ap; |
|
|
|
|
memset(ap, 0, sizeof(default_ap)); |
|
|
|
|
} |
|
|
|
|
opts = convert_format_parameters(ap); |
|
|
|
|
|
|
|
|
|
if(!ap->prealloced_context) |
|
|
|
|
ic = avformat_alloc_context(); |
|
|
|
@ -412,63 +456,15 @@ int av_open_input_stream(AVFormatContext **ic_ptr, |
|
|
|
|
err = AVERROR(ENOMEM); |
|
|
|
|
goto fail; |
|
|
|
|
} |
|
|
|
|
ic->iformat = fmt; |
|
|
|
|
ic->pb = pb; |
|
|
|
|
ic->duration = AV_NOPTS_VALUE; |
|
|
|
|
ic->start_time = AV_NOPTS_VALUE; |
|
|
|
|
av_strlcpy(ic->filename, filename, sizeof(ic->filename)); |
|
|
|
|
|
|
|
|
|
/* allocate private data */ |
|
|
|
|
if (fmt->priv_data_size > 0) { |
|
|
|
|
ic->priv_data = av_mallocz(fmt->priv_data_size); |
|
|
|
|
if (!ic->priv_data) { |
|
|
|
|
err = AVERROR(ENOMEM); |
|
|
|
|
goto fail; |
|
|
|
|
} |
|
|
|
|
if (fmt->priv_class) { |
|
|
|
|
*(const AVClass**)ic->priv_data = fmt->priv_class; |
|
|
|
|
av_opt_set_defaults(ic->priv_data); |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
ic->priv_data = NULL; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// e.g. AVFMT_NOFILE formats will not have a AVIOContext
|
|
|
|
|
if (ic->pb) |
|
|
|
|
ff_id3v2_read(ic, ID3v2_DEFAULT_MAGIC); |
|
|
|
|
err = avformat_open_input(ic_ptr, filename, fmt, &opts); |
|
|
|
|
|
|
|
|
|
if (ic->iformat->read_header) { |
|
|
|
|
err = ic->iformat->read_header(ic, ap); |
|
|
|
|
if (err < 0) |
|
|
|
|
goto fail; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (pb && !ic->data_offset) |
|
|
|
|
ic->data_offset = avio_tell(ic->pb); |
|
|
|
|
|
|
|
|
|
ic->raw_packet_buffer_remaining_size = RAW_PACKET_BUFFER_SIZE; |
|
|
|
|
|
|
|
|
|
*ic_ptr = ic; |
|
|
|
|
return 0; |
|
|
|
|
fail: |
|
|
|
|
if (ic) { |
|
|
|
|
int i; |
|
|
|
|
av_freep(&ic->priv_data); |
|
|
|
|
for(i=0;i<ic->nb_streams;i++) { |
|
|
|
|
AVStream *st = ic->streams[i]; |
|
|
|
|
if (st) { |
|
|
|
|
av_free(st->priv_data); |
|
|
|
|
av_free(st->codec->extradata); |
|
|
|
|
av_free(st->codec); |
|
|
|
|
av_free(st->info); |
|
|
|
|
} |
|
|
|
|
av_free(st); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
av_free(ic); |
|
|
|
|
*ic_ptr = NULL; |
|
|
|
|
fail: |
|
|
|
|
av_dict_free(&opts); |
|
|
|
|
return err; |
|
|
|
|
} |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
/** size of probe buffer, for guessing file type from file contents */ |
|
|
|
|
#define PROBE_BUF_MIN 2048 |
|
|
|
@ -541,69 +537,24 @@ int av_probe_input_buffer(AVIOContext *pb, AVInputFormat **fmt, |
|
|
|
|
return ret; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#if FF_API_FORMAT_PARAMETERS |
|
|
|
|
int av_open_input_file(AVFormatContext **ic_ptr, const char *filename, |
|
|
|
|
AVInputFormat *fmt, |
|
|
|
|
int buf_size, |
|
|
|
|
AVFormatParameters *ap) |
|
|
|
|
{ |
|
|
|
|
int err; |
|
|
|
|
AVProbeData probe_data, *pd = &probe_data; |
|
|
|
|
AVIOContext *pb = NULL; |
|
|
|
|
void *logctx= ap && ap->prealloced_context ? *ic_ptr : NULL; |
|
|
|
|
|
|
|
|
|
pd->filename = ""; |
|
|
|
|
if (filename) |
|
|
|
|
pd->filename = filename; |
|
|
|
|
pd->buf = NULL; |
|
|
|
|
pd->buf_size = 0; |
|
|
|
|
|
|
|
|
|
if (!fmt) { |
|
|
|
|
/* guess format if no file can be opened */ |
|
|
|
|
fmt = av_probe_input_format(pd, 0); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* Do not open file if the format does not need it. XXX: specific
|
|
|
|
|
hack needed to handle RTSP/TCP */ |
|
|
|
|
if (!fmt || !(fmt->flags & AVFMT_NOFILE)) { |
|
|
|
|
/* if no file needed do not try to open one */ |
|
|
|
|
if ((err=avio_open(&pb, filename, AVIO_FLAG_READ)) < 0) { |
|
|
|
|
goto fail; |
|
|
|
|
} |
|
|
|
|
if (buf_size > 0) { |
|
|
|
|
ffio_set_buf_size(pb, buf_size); |
|
|
|
|
} |
|
|
|
|
if (!fmt && (err = av_probe_input_buffer(pb, &fmt, filename, logctx, 0, logctx ? (*ic_ptr)->probesize : 0)) < 0) { |
|
|
|
|
goto fail; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
AVDictionary *opts = convert_format_parameters(ap); |
|
|
|
|
|
|
|
|
|
/* if still no format found, error */ |
|
|
|
|
if (!fmt) { |
|
|
|
|
err = AVERROR_INVALIDDATA; |
|
|
|
|
goto fail; |
|
|
|
|
} |
|
|
|
|
if (!ap->prealloced_context) |
|
|
|
|
*ic_ptr = NULL; |
|
|
|
|
|
|
|
|
|
/* check filename in case an image number is expected */ |
|
|
|
|
if (fmt->flags & AVFMT_NEEDNUMBER) { |
|
|
|
|
if (!av_filename_number_test(filename)) { |
|
|
|
|
err = AVERROR(EINVAL); |
|
|
|
|
goto fail; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
err = av_open_input_stream(ic_ptr, pb, filename, fmt, ap); |
|
|
|
|
if (err) |
|
|
|
|
goto fail; |
|
|
|
|
return 0; |
|
|
|
|
fail: |
|
|
|
|
av_freep(&pd->buf); |
|
|
|
|
if (pb) |
|
|
|
|
avio_close(pb); |
|
|
|
|
if (ap && ap->prealloced_context) |
|
|
|
|
av_free(*ic_ptr); |
|
|
|
|
*ic_ptr = NULL; |
|
|
|
|
return err; |
|
|
|
|
err = avformat_open_input(ic_ptr, filename, fmt, &opts); |
|
|
|
|
|
|
|
|
|
av_dict_free(&opts); |
|
|
|
|
return err; |
|
|
|
|
} |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
/* open input file and probe the format if necessary */ |
|
|
|
|
static int init_input(AVFormatContext *s, const char *filename) |
|
|
|
|