#include "id3v2.h"
#include "libavutil/avstring.h"
#include "libavutil/mathematics.h"
+#include "libavutil/parseutils.h"
#include "riff.h"
#include "audiointerleave.h"
#include "url.h"
#include <sys/time.h>
#include <time.h>
-#include <strings.h>
#include <stdarg.h>
#if CONFIG_NETWORK
#include "network.h"
while (*p != '\0' && *p != ',' && q-ext1<sizeof(ext1)-1)
*q++ = *p++;
*q = '\0';
- if (!strcasecmp(ext1, ext))
+ if (!av_strcasecmp(ext1, ext))
return 1;
if (*p == '\0')
break;
namelen = strlen(name);
while ((p = strchr(names, ','))) {
len = FFMAX(p - names, namelen);
- if (!strncasecmp(name, names, len))
+ if (!av_strncasecmp(name, names, len))
return 1;
names = p+1;
}
- return !strcasecmp(name, names);
+ return !av_strcasecmp(name, names);
}
AVOutputFormat *av_guess_format(const char *short_name, const char *filename,
fmt = NULL;
}
*score_ret= score_max;
+
return fmt;
}
#endif
/* open input file and probe the format if necessary */
-static int init_input(AVFormatContext *s, const char *filename)
+static int init_input(AVFormatContext *s, const char *filename, AVDictionary **options)
{
int ret;
AVProbeData pd = {filename, NULL, 0};
+ if(s->iformat && !strlen(filename))
+ return 0;
+
if (s->pb) {
s->flags |= AVFMT_FLAG_CUSTOM_IO;
if (!s->iformat)
(!s->iformat && (s->iformat = av_probe_input_format(&pd, 0))))
return 0;
- if ((ret = avio_open(&s->pb, filename, AVIO_FLAG_READ)) < 0)
+ if ((ret = avio_open2(&s->pb, filename, AVIO_FLAG_READ,
+ &s->interrupt_callback, options)) < 0)
return ret;
if (s->iformat)
return 0;
if ((ret = av_opt_set_dict(s, &tmp)) < 0)
goto fail;
- if ((ret = init_input(s, filename)) < 0)
+ if ((ret = init_input(s, filename, &tmp)) < 0)
goto fail;
/* check filename in case an image number is expected */
delay= st->codec->has_b_frames;
presentation_delayed = 0;
- // ignore delay caused by frame threading so that the mpeg2-without-dts
- // warning will not trigger
- if (delay && st->codec->active_thread_type&FF_THREAD_FRAME)
- delay -= st->codec->thread_count-1;
-
/* XXX: need has_b_frame, but cannot get it if the codec is
not initialized */
if (delay &&
// Note, if this is misbehaving for a H.264 file then possibly presentation_delayed is not set correctly.
if(delay==1 && pkt->dts == pkt->pts && pkt->dts != AV_NOPTS_VALUE && presentation_delayed){
av_log(s, AV_LOG_DEBUG, "invalid dts/pts combination %"PRIi64"\n", pkt->dts);
- pkt->dts= pkt->pts= AV_NOPTS_VALUE;
+ pkt->dts= AV_NOPTS_VALUE;
}
if (pkt->duration == 0) {
av_free_packet(&st->cur_pkt);
}
st->last_IP_pts = AV_NOPTS_VALUE;
- st->cur_dts = AV_NOPTS_VALUE; /* we set the current DTS to an unspecified origin */
+ if(st->first_dts == AV_NOPTS_VALUE) st->cur_dts = 0;
+ else st->cur_dts = AV_NOPTS_VALUE; /* we set the current DTS to an unspecified origin */
st->reference_dts = AV_NOPTS_VALUE;
/* fail safe */
st->cur_ptr = NULL;
}
}
-void av_update_cur_dts(AVFormatContext *s, AVStream *ref_st, int64_t timestamp){
+#if FF_API_SEEK_PUBLIC
+void av_update_cur_dts(AVFormatContext *s, AVStream *ref_st, int64_t timestamp)
+{
+ ff_update_cur_dts(s, ref_st, timestamp);
+}
+#endif
+
+void ff_update_cur_dts(AVFormatContext *s, AVStream *ref_st, int64_t timestamp)
+{
int i;
for(i = 0; i < s->nb_streams; i++) {
wanted_timestamp, flags);
}
+#if FF_API_SEEK_PUBLIC
int av_seek_frame_binary(AVFormatContext *s, int stream_index, int64_t target_ts, int flags){
+ return ff_seek_frame_binary(s, stream_index, target_ts, flags);
+}
+#endif
+
+int ff_seek_frame_binary(AVFormatContext *s, int stream_index, int64_t target_ts, int flags)
+{
AVInputFormat *avif= s->iformat;
int64_t av_uninit(pos_min), av_uninit(pos_max), pos, pos_limit;
int64_t ts_min, ts_max, ts;
}
}
- pos= av_gen_search(s, stream_index, target_ts, pos_min, pos_max, pos_limit, ts_min, ts_max, flags, &ts, avif->read_timestamp);
+ pos= ff_gen_search(s, stream_index, target_ts, pos_min, pos_max, pos_limit, ts_min, ts_max, flags, &ts, avif->read_timestamp);
if(pos<0)
return -1;
return ret;
ff_read_frame_flush(s);
- av_update_cur_dts(s, st, ts);
+ ff_update_cur_dts(s, st, ts);
return 0;
}
-int64_t av_gen_search(AVFormatContext *s, int stream_index, int64_t target_ts, int64_t pos_min, int64_t pos_max, int64_t pos_limit, int64_t ts_min, int64_t ts_max, int flags, int64_t *ts_ret, int64_t (*read_timestamp)(struct AVFormatContext *, int , int64_t *, int64_t )){
+#if FF_API_SEEK_PUBLIC
+int64_t av_gen_search(AVFormatContext *s, int stream_index, int64_t target_ts,
+ int64_t pos_min, int64_t pos_max, int64_t pos_limit,
+ int64_t ts_min, int64_t ts_max, int flags, int64_t *ts_ret,
+ int64_t (*read_timestamp)(struct AVFormatContext *, int , int64_t *, int64_t ))
+{
+ return ff_gen_search(s, stream_index, target_ts, pos_min, pos_max,
+ pos_limit, ts_min, ts_max, flags, ts_ret,
+ read_timestamp);
+}
+#endif
+
+int64_t ff_gen_search(AVFormatContext *s, int stream_index, int64_t target_ts,
+ int64_t pos_min, int64_t pos_max, int64_t pos_limit,
+ int64_t ts_min, int64_t ts_max, int flags, int64_t *ts_ret,
+ int64_t (*read_timestamp)(struct AVFormatContext *, int , int64_t *, int64_t ))
+{
int64_t pos, ts;
int64_t start_pos, filesize;
int no_change;
ie= &st->index_entries[st->nb_index_entries-1];
if ((ret = avio_seek(s->pb, ie->pos, SEEK_SET)) < 0)
return ret;
- av_update_cur_dts(s, st, ie->timestamp);
+ ff_update_cur_dts(s, st, ie->timestamp);
}else{
if ((ret = avio_seek(s->pb, s->data_offset, SEEK_SET)) < 0)
return ret;
if(stream_index == pkt.stream_index && pkt.dts > timestamp){
if(pkt.flags & AV_PKT_FLAG_KEY)
break;
- if(nonkey++ > 1000){
+ if(nonkey++ > 1000 && st->codec->codec_id != CODEC_ID_CDGRAPHICS){
av_log(s, AV_LOG_ERROR,"seek_frame_generic failed as this stream seems to contain no keyframes after the target timestamp, %d non keyframes found\n", nonkey);
break;
}
ie = &st->index_entries[index];
if ((ret = avio_seek(s->pb, ie->pos, SEEK_SET)) < 0)
return ret;
- av_update_cur_dts(s, st, ie->timestamp);
+ ff_update_cur_dts(s, st, ie->timestamp);
return 0;
}
if (s->iformat->read_timestamp && !(s->iformat->flags & AVFMT_NOBINSEARCH)) {
ff_read_frame_flush(s);
- return av_seek_frame_binary(s, stream_index, timestamp, flags);
+ return ff_seek_frame_binary(s, stream_index, timestamp, flags);
} else if (!(s->iformat->flags & AVFMT_NOGENSEARCH)) {
ff_read_frame_flush(s);
return seek_frame_generic(s, stream_index, timestamp, flags);
if (start_time1 < start_time_text)
start_time_text = start_time1;
} else
- if (start_time1 < start_time)
- start_time = start_time1;
+ start_time = FFMIN(start_time, start_time1);
if (st->duration != AV_NOPTS_VALUE) {
end_time1 = start_time1
+ av_rescale_q(st->duration, st->time_base, AV_TIME_BASE_Q);
- if (end_time1 > end_time)
- end_time = end_time1;
+ end_time = FFMAX(end_time, end_time1);
}
}
if (st->duration != AV_NOPTS_VALUE) {
duration1 = av_rescale_q(st->duration, st->time_base, AV_TIME_BASE_Q);
- if (duration1 > duration)
- duration = duration1;
+ duration = FFMAX(duration, duration1);
}
}
if (start_time == INT64_MAX || (start_time > start_time_text && start_time - start_time_text < AV_TIME_BASE))
start_time = start_time_text;
if (start_time != INT64_MAX) {
ic->start_time = start_time;
- if (end_time != INT64_MIN) {
- if (end_time - start_time > duration)
- duration = end_time - start_time;
- }
+ if (end_time != INT64_MIN)
+ duration = FFMAX(duration, end_time - start_time);
}
if (duration != INT64_MIN && ic->duration == AV_NOPTS_VALUE) {
ic->duration = duration;
file_size = 0;
} else {
file_size = avio_size(ic->pb);
- if (file_size < 0)
- file_size = 0;
+ file_size = FFMAX(0, file_size);
}
if ((!strcmp(ic->iformat->name, "mpeg") ||
static int has_decode_delay_been_guessed(AVStream *st)
{
return st->codec->codec_id != CODEC_ID_H264 ||
- st->codec_info_nb_frames >= 6 + st->codec->has_b_frames;
+ st->info->nb_decoded_frames >= 6;
}
static int try_decode_frame(AVStream *st, AVPacket *avpkt, AVDictionary **options)
avcodec_get_frame_defaults(&picture);
ret = avcodec_decode_video2(st->codec, &picture,
&got_picture, avpkt);
+ if (got_picture)
+ st->info->nb_decoded_frames++;
break;
case AVMEDIA_TYPE_AUDIO:
data_size = FFMAX(avpkt->size, AVCODEC_MAX_AUDIO_FRAME_SIZE);
count = 0;
read_size = 0;
for(;;) {
- if(url_interrupt_cb()){
+ if (ff_check_interrupt(&ic->interrupt_callback)){
ret= AVERROR_EXIT;
av_log(ic, AV_LOG_DEBUG, "interrupted\n");
break;
av_dlog(s, "compute_pkt_fields2: pts:%"PRId64" dts:%"PRId64" cur_dts:%"PRId64" b:%d size:%d st:%d\n",
pkt->pts, pkt->dts, st->cur_dts, delay, pkt->size, pkt->stream_index);
-/* if(pkt->pts == AV_NOPTS_VALUE && pkt->dts == AV_NOPTS_VALUE)
- return AVERROR(EINVAL);*/
-
/* duration field */
if (pkt->duration == 0) {
compute_frame_duration(&num, &den, st, NULL, pkt);
return ret;
}
-void ff_interleave_add_packet(AVFormatContext *s, AVPacket *pkt,
+int ff_interleave_add_packet(AVFormatContext *s, AVPacket *pkt,
int (*compare)(AVFormatContext *, AVPacket *, AVPacket *))
{
AVPacketList **next_point, *this_pktl;
this_pktl = av_mallocz(sizeof(AVPacketList));
+ if (!this_pktl)
+ return AVERROR(ENOMEM);
this_pktl->pkt= *pkt;
pkt->destruct= NULL; // do not free original but only the copy
av_dup_packet(&this_pktl->pkt); // duplicate the packet if it uses non-alloced memory
s->streams[pkt->stream_index]->last_in_packet_buffer=
*next_point= this_pktl;
+ return 0;
}
static int ff_interleave_compare_dts(AVFormatContext *s, AVPacket *next, AVPacket *pkt)
AVPacketList *pktl;
int stream_count=0, noninterleaved_count=0;
int64_t delta_dts_max = 0;
- int i;
+ int i, ret;
if(pkt){
- ff_interleave_add_packet(s, pkt, ff_interleave_compare_dts);
+ ret = ff_interleave_add_packet(s, pkt, ff_interleave_compare_dts);
+ if (ret < 0)
+ return ret;
}
for(i=0; i < s->nb_streams; i++) {
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);
+ struct tm time1 = {0}, time2 = {0};
+ char *ret1, *ret2;
+ ret1 = strptime(datestr, "%Y - %m - %d %T", &time1);
+ ret2 = strptime(datestr, "%Y - %m - %dT%T", &time2);
+ if (ret2 && !ret1)
+ return av_timegm(&time2);
+ else
+ return av_timegm(&time1);
#else
av_log(NULL, AV_LOG_WARNING, "strptime() unavailable on this system, cannot convert "
"the date string.\n");
}
return AVERROR_PATCHWELCOME;
}
+
+int avformat_network_init(void)
+{
+#if CONFIG_NETWORK
+ int ret;
+ ff_network_inited_globally = 1;
+ if ((ret = ff_network_init()) < 0)
+ return ret;
+ ff_tls_init();
+#endif
+ return 0;
+}
+
+int avformat_network_deinit(void)
+{
+#if CONFIG_NETWORK
+ ff_network_close();
+ ff_tls_deinit();
+#endif
+ return 0;
+}