diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2011-08-05 12:39:51 +0200 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2011-08-05 13:02:20 +0200 |
commit | 22d841becd89f21fcd88a76bcafb675fd051ce86 (patch) | |
tree | 04f910119420fabb5557217eb8c7cd6c1a0d24ea /libavformat/utils.c | |
parent | 25c2f13d00fcfdb81c33a459795c33d29f8690e8 (diff) | |
parent | 6e19cfb083eda83aaf4b49ae765ab2b3e578d32d (diff) | |
download | ffmpeg-22d841becd89f21fcd88a76bcafb675fd051ce86.tar.gz |
Merge branch 'master' into oldabi
* master: (780 commits)
ffmpeg: Fix doxygen comments for MetadataMap
filters.texi: fix wrong references in the "Filtergraph syntax" section
yadif: correct documentation on the parity parameter
mpegvideo.h: remove the 1 line difference to qatar
applehttp: fix variant discard logic
Fix possible crash when decoding mpeg streams.
h263dec: Fix asserts broken by the elimination of FF_COMMON_FRAME.
avidec: skip seek pos adjustment for non interleaved files. Fixes Ticket327
lsws: remove deprecated and unused stuff after the 0->1 major bump
cosmetics: remove some stray comments from AVCodec declarations
cosmetics: fix indentation/alignment in AVCodec declarations
Abort if command offset decreases, avoids potential endless loop.
Warn when falling back to unreliable UMF fps tag.
Detect NI-avi at playtime like mplayer. Fixes Ticket333
avidec: Fix XAN DPCM demuxing.
Fix a possible miscompilation of cabac with old (broken) compilers.
Fix -loop_input.
Set bits_per_coded_sample when encoding ADPCM.
vf_boxblur: call avfilter_draw_slice() at the end of draw_slice()
vf_boxblur: fix out-of-buffer access when h > w
...
Conflicts:
ffmpeg.c
libavcodec/avcodec.h
libavcodec/opt.h
libavcodec/version.h
libavdevice/avdevice.h
libavfilter/avfilter.h
libavformat/avformat.h
libavformat/aviobuf.c
libavformat/rtsp.c
libavformat/udp.c
libavformat/utils.c
libavformat/version.h
libavutil/avutil.h
Merged-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavformat/utils.c')
-rw-r--r-- | libavformat/utils.c | 203 |
1 files changed, 130 insertions, 73 deletions
diff --git a/libavformat/utils.c b/libavformat/utils.c index b610276844..8dd76f3e25 100644 --- a/libavformat/utils.c +++ b/libavformat/utils.c @@ -32,6 +32,7 @@ #include "metadata.h" #include "id3v2.h" #include "libavutil/avstring.h" +#include "libavutil/mathematics.h" #include "riff.h" #include "audiointerleave.h" #include "url.h" @@ -79,7 +80,7 @@ const char *avformat_license(void) * @param num must be >= 0 * @param den must be >= 1 */ -static void av_frac_init(AVFrac *f, int64_t val, int64_t num, int64_t den) +static void frac_init(AVFrac *f, int64_t val, int64_t num, int64_t den) { num += (den >> 1); if (num >= den) { @@ -97,7 +98,7 @@ static void av_frac_init(AVFrac *f, int64_t val, int64_t num, int64_t den) * @param f fractional number * @param incr increment, can be positive or negative */ -static void av_frac_add(AVFrac *f, int64_t incr) +static void frac_add(AVFrac *f, int64_t incr) { int64_t num, den; @@ -524,20 +525,27 @@ int av_open_input_stream(AVFormatContext **ic_ptr, opts = convert_format_parameters(ap); if(!ap->prealloced_context) - ic = avformat_alloc_context(); + *ic_ptr = ic = avformat_alloc_context(); else ic = *ic_ptr; if (!ic) { err = AVERROR(ENOMEM); goto fail; } - ic->pb = pb; + if (pb && fmt && fmt->flags & AVFMT_NOFILE) + av_log(ic, AV_LOG_WARNING, "Custom AVIOContext makes no sense and " + "will be ignored with AVFMT_NOFILE format.\n"); + else + ic->pb = pb; - err = avformat_open_input(ic_ptr, filename, fmt, &opts); + if ((err = avformat_open_input(&ic, filename, fmt, &opts)) < 0) + goto fail; + ic->pb = ic->pb ? ic->pb : pb; // don't leak custom pb if it wasn't set above #if FF_API_OLD_METADATA ff_metadata_demux_compat(ic); #endif + *ic_ptr = ic; fail: av_dict_free(&opts); return err; @@ -584,9 +592,9 @@ int av_probe_input_buffer(AVIOContext *pb, AVInputFormat **fmt, return AVERROR(EINVAL); } - for(probe_size= PROBE_BUF_MIN; probe_size<=max_probe_size && !*fmt && ret >= 0; + for(probe_size= PROBE_BUF_MIN; probe_size<=max_probe_size && !*fmt; probe_size = FFMIN(probe_size<<1, FFMAX(max_probe_size, probe_size+1))) { - int ret, score = probe_size < max_probe_size ? AVPROBE_SCORE_MAX/4 : 0; + int score = probe_size < max_probe_size ? AVPROBE_SCORE_MAX/4 : 0; int buf_offset = (probe_size == PROBE_BUF_MIN) ? 0 : probe_size>>1; if (probe_size < offset) { @@ -681,7 +689,7 @@ int avformat_open_input(AVFormatContext **ps, const char *filename, AVInputForma { AVFormatContext *s = *ps; int ret = 0; - AVFormatParameters ap = { 0 }; + AVFormatParameters ap = { { 0 } }; AVDictionary *tmp = NULL; if (!s && !(s = avformat_alloc_context())) @@ -800,6 +808,14 @@ int av_read_packet(AVFormatContext *s, AVPacket *pkt) continue; } + if ((s->flags & AVFMT_FLAG_DISCARD_CORRUPT) && + (pkt->flags & AV_PKT_FLAG_CORRUPT)) { + av_log(s, AV_LOG_WARNING, + "Dropped corrupted packet (stream = %d)\n", + pkt->stream_index); + continue; + } + st= s->streams[pkt->stream_index]; switch(st->codec->codec_type){ @@ -1176,7 +1192,7 @@ static void compute_pkt_fields(AVFormatContext *s, AVStream *st, } -static int av_read_frame_internal(AVFormatContext *s, AVPacket *pkt) +static int read_frame_internal(AVFormatContext *s, AVPacket *pkt) { AVStream *st; int len, ret, i; @@ -1307,7 +1323,7 @@ static int av_read_frame_internal(AVFormatContext *s, AVPacket *pkt) } } if(s->debug & FF_FDEBUG_TS) - av_log(s, AV_LOG_DEBUG, "av_read_frame_internal stream=%d, pts=%"PRId64", dts=%"PRId64", size=%d, duration=%d, flags=%d\n", + av_log(s, AV_LOG_DEBUG, "read_frame_internal stream=%d, pts=%"PRId64", dts=%"PRId64", size=%d, duration=%d, flags=%d\n", pkt->stream_index, pkt->pts, pkt->dts, @@ -1353,7 +1369,7 @@ int av_read_frame(AVFormatContext *s, AVPacket *pkt) } } if(genpts){ - int ret= av_read_frame_internal(s, pkt); + int ret= read_frame_internal(s, pkt); if(ret<0){ if(pktl && ret != AVERROR(EAGAIN)){ eof=1; @@ -1367,7 +1383,7 @@ int av_read_frame(AVFormatContext *s, AVPacket *pkt) return AVERROR(ENOMEM); }else{ assert(!s->packet_buffer); - return av_read_frame_internal(s, pkt); + return read_frame_internal(s, pkt); } } } @@ -1739,7 +1755,7 @@ int64_t av_gen_search(AVFormatContext *s, int stream_index, int64_t target_ts, i return pos; } -static int av_seek_frame_byte(AVFormatContext *s, int stream_index, int64_t pos, int flags){ +static int seek_frame_byte(AVFormatContext *s, int stream_index, int64_t pos, int flags){ int64_t pos_min, pos_max; #if 0 AVStream *st; @@ -1764,7 +1780,7 @@ static int av_seek_frame_byte(AVFormatContext *s, int stream_index, int64_t pos, return 0; } -static int av_seek_frame_generic(AVFormatContext *s, +static int seek_frame_generic(AVFormatContext *s, int stream_index, int64_t timestamp, int flags) { int index; @@ -1832,7 +1848,7 @@ int av_seek_frame(AVFormatContext *s, int stream_index, int64_t timestamp, int f ff_read_frame_flush(s); if(flags & AVSEEK_FLAG_BYTE) - return av_seek_frame_byte(s, stream_index, timestamp, flags); + return seek_frame_byte(s, stream_index, timestamp, flags); if(stream_index < 0){ stream_index= av_find_default_stream_index(s); @@ -1856,7 +1872,7 @@ int av_seek_frame(AVFormatContext *s, int stream_index, int64_t timestamp, int f if(s->iformat->read_timestamp && !(s->iformat->flags & AVFMT_NOBINSEARCH)) return av_seek_frame_binary(s, stream_index, timestamp, flags); else if (!(s->iformat->flags & AVFMT_NOGENSEARCH)) - return av_seek_frame_generic(s, stream_index, timestamp, flags); + return seek_frame_generic(s, stream_index, timestamp, flags); else return -1; } @@ -1880,7 +1896,7 @@ int avformat_seek_file(AVFormatContext *s, int stream_index, int64_t min_ts, int if(s->iformat->read_seek || 1) return av_seek_frame(s, stream_index, ts, flags | (ts - min_ts > (uint64_t)(max_ts - ts) ? AVSEEK_FLAG_BACKWARD : 0)); - // try some generic seek like av_seek_frame_generic() but with new ts semantics + // try some generic seek like seek_frame_generic() but with new ts semantics } /*******************************************************/ @@ -1890,7 +1906,7 @@ int avformat_seek_file(AVFormatContext *s, int stream_index, int64_t min_ts, int * * @return TRUE if the stream has accurate duration for at least one component. */ -static int av_has_duration(AVFormatContext *ic) +static int has_duration(AVFormatContext *ic) { int i; AVStream *st; @@ -1908,7 +1924,7 @@ static int av_has_duration(AVFormatContext *ic) * * Also computes the global bitrate if possible. */ -static void av_update_stream_timings(AVFormatContext *ic) +static void update_stream_timings(AVFormatContext *ic) { int64_t start_time, start_time1, start_time_text, end_time, end_time1; int64_t duration, duration1; @@ -1966,7 +1982,7 @@ static void fill_all_stream_timings(AVFormatContext *ic) int i; AVStream *st; - av_update_stream_timings(ic); + update_stream_timings(ic); for(i = 0;i < ic->nb_streams; i++) { st = ic->streams[i]; if (st->start_time == AV_NOPTS_VALUE) { @@ -1978,7 +1994,7 @@ static void fill_all_stream_timings(AVFormatContext *ic) } } -static void av_estimate_timings_from_bit_rate(AVFormatContext *ic) +static void estimate_timings_from_bit_rate(AVFormatContext *ic) { int64_t filesize, duration; int bit_rate, i; @@ -2015,7 +2031,7 @@ static void av_estimate_timings_from_bit_rate(AVFormatContext *ic) #define DURATION_MAX_RETRY 3 /* only usable for MPEG-PS streams */ -static void av_estimate_timings_from_pts(AVFormatContext *ic, int64_t old_offset) +static void estimate_timings_from_pts(AVFormatContext *ic, int64_t old_offset) { AVPacket pkt1, *pkt = &pkt1; AVStream *st; @@ -2032,7 +2048,7 @@ static void av_estimate_timings_from_pts(AVFormatContext *ic, int64_t old_offset for (i=0; i<ic->nb_streams; i++) { st = ic->streams[i]; if (st->start_time == AV_NOPTS_VALUE && st->first_dts == AV_NOPTS_VALUE) - av_log(st->codec, AV_LOG_WARNING, "start time is not set in av_estimate_timings_from_pts\n"); + av_log(st->codec, AV_LOG_WARNING, "start time is not set in estimate_timings_from_pts\n"); if (st->parser) { av_parser_close(st->parser); @@ -2094,7 +2110,7 @@ static void av_estimate_timings_from_pts(AVFormatContext *ic, int64_t old_offset } } -static void av_estimate_timings(AVFormatContext *ic, int64_t old_offset) +static void estimate_timings(AVFormatContext *ic, int64_t old_offset) { int64_t file_size; @@ -2112,17 +2128,17 @@ static void av_estimate_timings(AVFormatContext *ic, int64_t old_offset) !strcmp(ic->iformat->name, "mpegts")) && file_size && ic->pb->seekable) { /* get accurate estimate from the PTSes */ - av_estimate_timings_from_pts(ic, old_offset); - } else if (av_has_duration(ic)) { + estimate_timings_from_pts(ic, old_offset); + } else if (has_duration(ic)) { /* at least one component has timings - we use them for all the components */ fill_all_stream_timings(ic); } else { av_log(ic, AV_LOG_WARNING, "Estimating duration from bitrate, this may be inaccurate\n"); /* less precise: use bitrate info */ - av_estimate_timings_from_bit_rate(ic); + estimate_timings_from_bit_rate(ic); } - av_update_stream_timings(ic); + update_stream_timings(ic); #if 0 { @@ -2142,30 +2158,30 @@ static void av_estimate_timings(AVFormatContext *ic, int64_t old_offset) #endif } -static int has_codec_parameters(AVCodecContext *enc) +static int has_codec_parameters(AVCodecContext *avctx) { int val; - switch(enc->codec_type) { + switch (avctx->codec_type) { case AVMEDIA_TYPE_AUDIO: - val = enc->sample_rate && enc->channels && enc->sample_fmt != AV_SAMPLE_FMT_NONE; - if(!enc->frame_size && - (enc->codec_id == CODEC_ID_VORBIS || - enc->codec_id == CODEC_ID_AAC || - enc->codec_id == CODEC_ID_MP1 || - enc->codec_id == CODEC_ID_MP2 || - enc->codec_id == CODEC_ID_MP3 || - enc->codec_id == CODEC_ID_SPEEX || - enc->codec_id == CODEC_ID_CELT)) + val = avctx->sample_rate && avctx->channels && avctx->sample_fmt != AV_SAMPLE_FMT_NONE; + if(!avctx->frame_size && + (avctx->codec_id == CODEC_ID_VORBIS || + avctx->codec_id == CODEC_ID_AAC || + avctx->codec_id == CODEC_ID_MP1 || + avctx->codec_id == CODEC_ID_MP2 || + avctx->codec_id == CODEC_ID_MP3 || + avctx->codec_id == CODEC_ID_SPEEX || + avctx->codec_id == CODEC_ID_CELT)) return 0; break; case AVMEDIA_TYPE_VIDEO: - val = enc->width && enc->pix_fmt != PIX_FMT_NONE; + val = avctx->width && avctx->pix_fmt != PIX_FMT_NONE; break; default: val = 1; break; } - return enc->codec_id != CODEC_ID_NONE && val != 0; + return avctx->codec_id != CODEC_ID_NONE && val != 0; } static int has_decode_delay_been_guessed(AVStream *st) @@ -2174,7 +2190,7 @@ static int has_decode_delay_been_guessed(AVStream *st) st->codec_info_nb_frames >= 6 + st->codec->has_b_frames; } -static int try_decode_frame(AVStream *st, AVPacket *avpkt) +static int try_decode_frame(AVStream *st, AVPacket *avpkt, AVDictionary **options) { int16_t *samples; AVCodec *codec; @@ -2185,12 +2201,13 @@ static int try_decode_frame(AVStream *st, AVPacket *avpkt) codec = avcodec_find_decoder(st->codec->codec_id); if (!codec) return -1; - ret = avcodec_open(st->codec, codec); + ret = avcodec_open2(st->codec, codec, options); if (ret < 0) return ret; } - if(!has_codec_parameters(st->codec) || !has_decode_delay_been_guessed(st)){ + if(!has_codec_parameters(st->codec) || !has_decode_delay_been_guessed(st) || + (!st->codec_info_nb_frames && st->codec->codec->capabilities & CODEC_CAP_CHANNEL_CONF)) { switch(st->codec->codec_type) { case AVMEDIA_TYPE_VIDEO: avcodec_get_frame_defaults(&picture); @@ -2304,21 +2321,34 @@ static int tb_unreliable(AVCodecContext *c){ return 0; } +#if FF_API_FORMAT_PARAMETERS int av_find_stream_info(AVFormatContext *ic) { + return avformat_find_stream_info(ic, NULL); +} +#endif + +int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options) +{ int i, count, ret, read_size, j; AVStream *st; AVPacket pkt1, *pkt; int64_t old_offset = avio_tell(ic->pb); + int orig_nb_streams = ic->nb_streams; // new streams might appear, no options for those for(i=0;i<ic->nb_streams;i++) { AVCodec *codec; st = ic->streams[i]; - if (st->codec->codec_id == CODEC_ID_AAC) { + if (st->codec->codec_id == CODEC_ID_AAC && st->codec->extradata_size) { + // We need to discard these since they can be plain wrong for + // backwards compatible HE-AAC signaling. + // But when we have no extradata we need to keep them or we can't + // play anything at all. st->codec->sample_rate = 0; st->codec->frame_size = 0; st->codec->channels = 0; } + if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO || st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE) { /* if(!st->time_base.num) @@ -2336,22 +2366,15 @@ int av_find_stream_info(AVFormatContext *ic) assert(!st->codec->codec); codec = avcodec_find_decoder(st->codec->codec_id); - /* Force decoding of at least one frame of codec data - * this makes sure the codec initializes the channel configuration - * and does not trust the values from the container. - */ - if (codec && codec->capabilities & CODEC_CAP_CHANNEL_CONF) - st->codec->channels = 0; - /* Ensure that subtitle_header is properly set. */ if (st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE && codec && !st->codec->codec) - avcodec_open(st->codec, codec); + avcodec_open2(st->codec, codec, options ? &options[i] : NULL); //try to just open decoders, in case this is enough to get parameters if(!has_codec_parameters(st->codec)){ if (codec && !st->codec->codec) - avcodec_open(st->codec, codec); + avcodec_open2(st->codec, codec, options ? &options[i] : NULL); } } @@ -2412,8 +2435,11 @@ int av_find_stream_info(AVFormatContext *ic) /* NOTE: a new stream can be added there if no header in file (AVFMTCTX_NOHEADER) */ - ret = av_read_frame_internal(ic, &pkt1); - if (ret < 0 && ret != AVERROR(EAGAIN)) { + ret = read_frame_internal(ic, &pkt1); + if (ret == AVERROR(EAGAIN)) + continue; + + if (ret < 0) { /* EOF or error */ ret = -1; /* we could not have all the codec parameters before EOF */ for(i=0;i<ic->nb_streams;i++) { @@ -2429,9 +2455,6 @@ int av_find_stream_info(AVFormatContext *ic) break; } - if (ret == AVERROR(EAGAIN)) - continue; - pkt= add_to_pktbuf(&ic->packet_buffer, &pkt1, &ic->packet_buffer_end); if ((ret = av_dup_packet(pkt)) < 0) goto find_stream_info_err; @@ -2485,9 +2508,13 @@ int av_find_stream_info(AVFormatContext *ic) /* if still no information, we try to open the codec and to decompress the frame. We try to avoid that in most cases as it takes longer and uses more memory. For MPEG-4, we need to - decompress for QuickTime. */ - if (!has_codec_parameters(st->codec) || !has_decode_delay_been_guessed(st)) - try_decode_frame(st, pkt); + decompress for QuickTime. + + If CODEC_CAP_CHANNEL_CONF is set this will force decoding of at + least one frame of codec data, this makes sure the codec initializes + the channel configuration and does not only trust the values from the container. + */ + try_decode_frame(st, pkt, (options && i < orig_nb_streams )? &options[i] : NULL); st->codec_info_nb_frames++; count++; @@ -2568,7 +2595,7 @@ int av_find_stream_info(AVFormatContext *ic) } } - av_estimate_timings(ic, old_offset); + estimate_timings(ic, old_offset); compute_chapters_end(ic); @@ -2785,7 +2812,7 @@ AVStream *av_new_stream(AVFormatContext *s, int id) return NULL; } - st->codec= avcodec_alloc_context(); + st->codec = avcodec_alloc_context3(NULL); if (s->iformat) { /* no default bitrate if decoding */ st->codec->bit_rate = 0; @@ -2999,6 +3026,9 @@ int avformat_write_header(AVFormatContext *s, AVDictionary **options) av_dict_copy(&tmp, *options, 0); if ((ret = av_opt_set_dict(s, &tmp)) < 0) goto fail; + if (s->priv_data && s->oformat->priv_class && *(const AVClass**)s->priv_data==s->oformat->priv_class && + (ret = av_opt_set_dict(s->priv_data, &tmp)) < 0) + goto fail; // some sanity checks if (s->nb_streams == 0 && !(s->oformat->flags & AVFMT_NOSTREAMS)) { @@ -3113,7 +3143,7 @@ int avformat_write_header(AVFormatContext *s, AVDictionary **options) ret = AVERROR_INVALIDDATA; goto fail; } - av_frac_init(&st->pts, 0, 0, den); + frac_init(&st->pts, 0, 0, den); } } @@ -3191,11 +3221,11 @@ static int compute_pkt_fields2(AVFormatContext *s, AVStream *st, AVPacket *pkt){ likely equal to the encoder delay, but it would be better if we had the real timestamps from the encoder */ if (frame_size >= 0 && (pkt->size || st->pts.num!=st->pts.den>>1 || st->pts.val)) { - av_frac_add(&st->pts, (int64_t)st->time_base.den * frame_size); + frac_add(&st->pts, (int64_t)st->time_base.den * frame_size); } break; case AVMEDIA_TYPE_VIDEO: - av_frac_add(&st->pts, (int64_t)st->time_base.den * st->codec->time_base.num); + frac_add(&st->pts, (int64_t)st->time_base.den * st->codec->time_base.num); break; default: break; @@ -3211,8 +3241,9 @@ int av_write_frame(AVFormatContext *s, AVPacket *pkt) return ret; ret= s->oformat->write_packet(s, pkt); - if(!ret) - ret= url_ferror(s->pb); + + if (ret >= 0) + s->streams[pkt->stream_index]->nb_frames++; return ret; } @@ -3303,7 +3334,7 @@ int av_interleave_packet_per_dts(AVFormatContext *s, AVPacket *out, AVPacket *pk * @return 1 if a packet was output, 0 if no packet could be output, * < 0 if an error occurred */ -static int av_interleave_packet(AVFormatContext *s, AVPacket *out, AVPacket *in, int flush){ +static int interleave_packet(AVFormatContext *s, AVPacket *out, AVPacket *in, int flush){ if(s->oformat->interleave_packet) return s->oformat->interleave_packet(s, out, in, flush); else @@ -3328,11 +3359,13 @@ int av_interleaved_write_frame(AVFormatContext *s, AVPacket *pkt){ for(;;){ AVPacket opkt; - int ret= av_interleave_packet(s, &opkt, pkt, 0); + int ret= interleave_packet(s, &opkt, pkt, 0); if(ret<=0) //FIXME cleanup needed for ret<0 ? return ret; ret= s->oformat->write_packet(s, &opkt); + if (ret >= 0) + s->streams[opkt.stream_index]->nb_frames++; av_free_packet(&opkt); pkt= NULL; @@ -3350,13 +3383,15 @@ int av_write_trailer(AVFormatContext *s) for(;;){ AVPacket pkt; - ret= av_interleave_packet(s, &pkt, NULL, 1); + ret= interleave_packet(s, &pkt, NULL, 1); if(ret<0) //FIXME cleanup needed for ret<0 ? goto fail; if(!ret) break; ret= s->oformat->write_packet(s, &pkt); + if (ret >= 0) + s->streams[pkt.stream_index]->nb_frames++; av_free_packet(&pkt); @@ -3381,6 +3416,15 @@ fail: return ret; } +int av_get_output_timestamp(struct AVFormatContext *s, int stream, + int64_t *dts, int64_t *wall) +{ + if (!s->oformat || !s->oformat->get_output_timestamp) + return AVERROR(ENOSYS); + s->oformat->get_output_timestamp(s, stream, dts, wall); + return 0; +} + void ff_program_add_stream_index(AVFormatContext *ac, int progid, unsigned int idx) { int i, j; @@ -3459,7 +3503,7 @@ static void dump_stream_format(AVFormatContext *ic, int i, int index, int is_out st->codec->width*st->sample_aspect_ratio.num, st->codec->height*st->sample_aspect_ratio.den, 1024*1024); - av_log(NULL, AV_LOG_INFO, ", PAR %d:%d DAR %d:%d", + av_log(NULL, AV_LOG_INFO, ", SAR %d:%d DAR %d:%d", st->sample_aspect_ratio.num, st->sample_aspect_ratio.den, display_aspect_ratio.num, display_aspect_ratio.den); } @@ -4106,3 +4150,16 @@ void ff_make_absolute_url(char *buf, int size, const char *base, } av_strlcat(buf, rel, size); } + +int64_t ff_iso8601_to_unix_time(const char *datestr) +{ +#if HAVE_STRPTIME + struct tm time = {0}; + strptime(datestr, "%Y - %m - %dT%T", &time); + return mktime(&time); +#else + av_log(NULL, AV_LOG_WARNING, "strptime() unavailable on this system, cannot convert " + "the date string.\n"); + return 0; +#endif +} |