|
|
|
@ -605,6 +605,107 @@ int av_open_input_file(AVFormatContext **ic_ptr, const char *filename, |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* open input file and probe the format if necessary */ |
|
|
|
|
static int init_input(AVFormatContext *s, const char *filename) |
|
|
|
|
{ |
|
|
|
|
int ret; |
|
|
|
|
AVProbeData pd = {filename, NULL, 0}; |
|
|
|
|
|
|
|
|
|
if (s->pb) { |
|
|
|
|
s->flags |= AVFMT_FLAG_CUSTOM_IO; |
|
|
|
|
if (!s->iformat) |
|
|
|
|
return av_probe_input_buffer(s->pb, &s->iformat, filename, s, 0, 0); |
|
|
|
|
else if (s->iformat->flags & AVFMT_NOFILE) |
|
|
|
|
return AVERROR(EINVAL); |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if ( (s->iformat && s->iformat->flags & AVFMT_NOFILE) || |
|
|
|
|
(!s->iformat && (s->iformat = av_probe_input_format(&pd, 0)))) |
|
|
|
|
return 0; |
|
|
|
|
|
|
|
|
|
if ((ret = avio_open(&s->pb, filename, AVIO_FLAG_READ)) < 0) |
|
|
|
|
return ret; |
|
|
|
|
if (s->iformat) |
|
|
|
|
return 0; |
|
|
|
|
return av_probe_input_buffer(s->pb, &s->iformat, filename, s, 0, 0); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
int avformat_open_input(AVFormatContext **ps, const char *filename, AVInputFormat *fmt, AVDictionary **options) |
|
|
|
|
{ |
|
|
|
|
AVFormatContext *s = *ps; |
|
|
|
|
int ret = 0; |
|
|
|
|
AVFormatParameters ap = { 0 }; |
|
|
|
|
AVDictionary *tmp = NULL; |
|
|
|
|
|
|
|
|
|
if (!s && !(s = avformat_alloc_context())) |
|
|
|
|
return AVERROR(ENOMEM); |
|
|
|
|
if (fmt) |
|
|
|
|
s->iformat = fmt; |
|
|
|
|
|
|
|
|
|
if (options) |
|
|
|
|
av_dict_copy(&tmp, *options, 0); |
|
|
|
|
|
|
|
|
|
if ((ret = av_opt_set_dict(s, &tmp)) < 0) |
|
|
|
|
goto fail; |
|
|
|
|
|
|
|
|
|
if ((ret = init_input(s, filename)) < 0) |
|
|
|
|
goto fail; |
|
|
|
|
|
|
|
|
|
/* check filename in case an image number is expected */ |
|
|
|
|
if (s->iformat->flags & AVFMT_NEEDNUMBER) { |
|
|
|
|
if (!av_filename_number_test(filename)) { |
|
|
|
|
ret = AVERROR(EINVAL); |
|
|
|
|
goto fail; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
s->duration = s->start_time = AV_NOPTS_VALUE; |
|
|
|
|
av_strlcpy(s->filename, filename, sizeof(s->filename)); |
|
|
|
|
|
|
|
|
|
/* allocate private data */ |
|
|
|
|
if (s->iformat->priv_data_size > 0) { |
|
|
|
|
if (!(s->priv_data = av_mallocz(s->iformat->priv_data_size))) { |
|
|
|
|
ret = AVERROR(ENOMEM); |
|
|
|
|
goto fail; |
|
|
|
|
} |
|
|
|
|
if (s->iformat->priv_class) { |
|
|
|
|
*(const AVClass**)s->priv_data = s->iformat->priv_class; |
|
|
|
|
av_opt_set_defaults(s->priv_data); |
|
|
|
|
if ((ret = av_opt_set_dict(s->priv_data, &tmp)) < 0) |
|
|
|
|
goto fail; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* e.g. AVFMT_NOFILE formats will not have a AVIOContext */ |
|
|
|
|
if (s->pb) |
|
|
|
|
ff_id3v2_read(s, ID3v2_DEFAULT_MAGIC); |
|
|
|
|
|
|
|
|
|
if (s->iformat->read_header) |
|
|
|
|
if ((ret = s->iformat->read_header(s, &ap)) < 0) |
|
|
|
|
goto fail; |
|
|
|
|
|
|
|
|
|
if (s->pb && !s->data_offset) |
|
|
|
|
s->data_offset = avio_tell(s->pb); |
|
|
|
|
|
|
|
|
|
s->raw_packet_buffer_remaining_size = RAW_PACKET_BUFFER_SIZE; |
|
|
|
|
|
|
|
|
|
if (options) { |
|
|
|
|
av_dict_free(options); |
|
|
|
|
*options = tmp; |
|
|
|
|
} |
|
|
|
|
*ps = s; |
|
|
|
|
return 0; |
|
|
|
|
|
|
|
|
|
fail: |
|
|
|
|
av_dict_free(&tmp); |
|
|
|
|
if (s->pb && !(s->flags & AVFMT_FLAG_CUSTOM_IO)) |
|
|
|
|
avio_close(s->pb); |
|
|
|
|
avformat_free_context(s); |
|
|
|
|
*ps = NULL; |
|
|
|
|
return ret; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/*******************************************************/ |
|
|
|
|
|
|
|
|
|
static AVPacket *add_to_pktbuf(AVPacketList **packet_buffer, AVPacket *pkt, |
|
|
|
@ -2573,7 +2674,8 @@ void avformat_free_context(AVFormatContext *s) |
|
|
|
|
|
|
|
|
|
void av_close_input_file(AVFormatContext *s) |
|
|
|
|
{ |
|
|
|
|
AVIOContext *pb = s->iformat->flags & AVFMT_NOFILE ? NULL : s->pb; |
|
|
|
|
AVIOContext *pb = (s->iformat->flags & AVFMT_NOFILE) || (s->flags & AVFMT_FLAG_CUSTOM_IO) ? |
|
|
|
|
NULL : s->pb; |
|
|
|
|
av_close_input_stream(s); |
|
|
|
|
if (pb) |
|
|
|
|
avio_close(pb); |
|
|
|
|