p = extensions;
for(;;) {
q = ext1;
- while (*p != '\0' && *p != ',')
+ while (*p != '\0' && *p != ',' && q-ext1<sizeof(ext1)-1)
*q++ = *p++;
*q = '\0';
if (!strcasecmp(ext1, ext))
*/
int av_new_packet(AVPacket *pkt, int size)
{
- void *data = av_malloc(size + FF_INPUT_BUFFER_PADDING_SIZE);
+ void *data;
+ if((unsigned)size > (unsigned)size + FF_INPUT_BUFFER_PADDING_SIZE)
+ return AVERROR_NOMEM;
+ data = av_malloc(size + FF_INPUT_BUFFER_PADDING_SIZE);
if (!data)
return AVERROR_NOMEM;
memset(data + size, 0, FF_INPUT_BUFFER_PADDING_SIZE);
uint8_t *data;
/* we duplicate the packet and don't forget to put the padding
again */
+ if((unsigned)pkt->size > (unsigned)pkt->size + FF_INPUT_BUFFER_PADDING_SIZE)
+ return AVERROR_NOMEM;
data = av_malloc(pkt->size + FF_INPUT_BUFFER_PADDING_SIZE);
if (!data) {
return AVERROR_NOMEM;
return 0;
}
-void fifo_realloc(FifoBuffer *f, int new_size){
- int old_size= f->end - f->buffer;
+void fifo_realloc(FifoBuffer *f, unsigned int new_size){
+ unsigned int old_size= f->end - f->buffer;
if(old_size < new_size){
uint8_t *old= f->buffer;
st->last_IP_pts= pkt->pts;
/* cannot compute PTS if not present (we can compute it only
by knowing the futur */
- } else {
+ } else if(pkt->pts != AV_NOPTS_VALUE || pkt->dts != AV_NOPTS_VALUE || pkt->duration){
+ if(pkt->pts != AV_NOPTS_VALUE && pkt->duration){
+ int64_t old_diff= ABS(st->cur_dts - pkt->duration - pkt->pts);
+ int64_t new_diff= ABS(st->cur_dts - pkt->pts);
+ if(old_diff < new_diff && old_diff < (pkt->duration>>3)){
+ pkt->pts += pkt->duration;
+// av_log(NULL, AV_LOG_DEBUG, "id:%d old:%Ld new:%Ld dur:%d cur:%Ld size:%d\n", pkt->stream_index, old_diff, new_diff, pkt->duration, st->cur_dts, pkt->size);
+ }
+ }
+
/* presentation is not delayed : PTS and DTS are the same */
if (pkt->pts == AV_NOPTS_VALUE) {
if (pkt->dts == AV_NOPTS_VALUE) {
compute_pkt_fields(s, st, NULL, pkt);
s->cur_st = NULL;
return 0;
- } else if (s->cur_len > 0) {
+ } else if (s->cur_len > 0 && st->discard < AVDISCARD_ALL) {
len = av_parser_parse(st->parser, &st->codec, &pkt->data, &pkt->size,
s->cur_ptr, s->cur_len,
s->cur_pkt.pts, s->cur_pkt.dts);
AVIndexEntry *entries, *ie;
int index;
+ if((unsigned)st->nb_index_entries + 1 >= UINT_MAX / sizeof(AVIndexEntry))
+ return -1;
+
entries = av_fast_realloc(st->index_entries,
&st->index_entries_allocated_size,
(st->nb_index_entries + 1) *
sizeof(AVIndexEntry));
+ if(!entries)
+ return -1;
+
st->index_entries= entries;
- index= av_index_search_timestamp(st, timestamp, 0);
+ index= av_index_search_timestamp(st, timestamp, AVSEEK_FLAG_ANY);
if(index<0){
index= st->nb_index_entries++;
/**
* gets the index for a specific timestamp.
- * @param backward if non zero then the returned index will correspond to
+ * @param flags if AVSEEK_FLAG_BACKWARD then the returned index will correspond to
* the timestamp which is <= the requested one, if backward is 0
* then it will be >=
+ * if AVSEEK_FLAG_ANY seek to any frame, only keyframes otherwise
* @return < 0 if no such timestamp could be found
*/
int av_index_search_timestamp(AVStream *st, int64_t wanted_timestamp,
- int backward)
+ int flags)
{
AVIndexEntry *entries= st->index_entries;
int nb_entries= st->nb_index_entries;
if(timestamp <= wanted_timestamp)
a = m;
}
- m= backward ? a : b;
+ m= (flags & AVSEEK_FLAG_BACKWARD) ? a : b;
+
+ if(!(flags & AVSEEK_FLAG_ANY)){
+ while(m>=0 && m<nb_entries && !(entries[m].flags & AVINDEX_KEYFRAME)){
+ m += (flags & AVSEEK_FLAG_BACKWARD) ? -1 : 1;
+ }
+ }
if(m == nb_entries)
return -1;
if(st->index_entries){
AVIndexEntry *e;
- index= av_index_search_timestamp(st, target_ts, 1);
+ index= av_index_search_timestamp(st, target_ts, flags | AVSEEK_FLAG_BACKWARD); //FIXME whole func must be checked for non keyframe entries in index case, especially read_timestamp()
index= FFMAX(index, 0);
e= &st->index_entries[index];
}else{
assert(index==0);
}
- index++;
- if(index < st->nb_index_entries){
+
+ index= av_index_search_timestamp(st, target_ts, flags & ~AVSEEK_FLAG_BACKWARD);
+ assert(index < st->nb_index_entries);
+ if(index >= 0){
e= &st->index_entries[index];
assert(e->timestamp >= target_ts);
pos_max= e->pos;
}
static int av_seek_frame_byte(AVFormatContext *s, int stream_index, int64_t pos, int flags){
- AVInputFormat *avif= s->iformat;
int64_t pos_min, pos_max;
#if 0
AVStream *st;
}
st = s->streams[stream_index];
- index = av_index_search_timestamp(st, timestamp, flags & AVSEEK_FLAG_BACKWARD);
+ index = av_index_search_timestamp(st, timestamp, flags);
if (index < 0)
return -1;
AVStream *st;
AVPacket pkt1, *pkt;
AVPacketList *pktl=NULL, **ppktl;
+ int64_t last_dts[MAX_STREAMS];
+ int64_t best_duration[MAX_STREAMS];
+ for(i=0;i<MAX_STREAMS;i++){
+ last_dts[i]= AV_NOPTS_VALUE;
+ best_duration[i]= INT64_MAX;
+ }
+
count = 0;
read_size = 0;
ppktl = &ic->packet_buffer;
st = ic->streams[i];
if (!has_codec_parameters(&st->codec))
break;
+ /* variable fps and no guess at the real fps */
+ if( st->codec.frame_rate >= 1000LL*st->codec.frame_rate_base
+ && best_duration[i]== INT64_MAX)
+ break;
}
if (i == ic->nb_streams) {
/* NOTE: if the format has no header, then we need to read
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++) {
+ st = ic->streams[i];
+ if (!has_codec_parameters(&st->codec))
+ break;
+ }
if ((ic->ctx_flags & AVFMTCTX_NOHEADER) &&
i == ic->nb_streams)
ret = 0;
if (pkt->duration != 0)
st->codec_info_nb_frames++;
+ if(st->codec.codec_type == CODEC_TYPE_VIDEO){
+ int64_t last= last_dts[pkt->stream_index];
+
+ if(pkt->dts != AV_NOPTS_VALUE && last != AV_NOPTS_VALUE && last < pkt->dts &&
+ best_duration[pkt->stream_index] > pkt->dts - last){
+ best_duration[pkt->stream_index] = pkt->dts - last;
+ }
+ last_dts[pkt->stream_index]= pkt->dts;
+ }
/* 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 MPEG4, we need to
st->codec.codec_id == CODEC_ID_PGMYUV ||
st->codec.codec_id == CODEC_ID_PBM ||
st->codec.codec_id == CODEC_ID_PPM ||
+ st->codec.codec_id == CODEC_ID_SHORTEN ||
(st->codec.codec_id == CODEC_ID_MPEG4 && !st->need_parsing)))
try_decode_frame(st, pkt->data, pkt->size);
if (st->codec.codec_type == CODEC_TYPE_VIDEO) {
if(st->codec.codec_id == CODEC_ID_RAWVIDEO && !st->codec.codec_tag && !st->codec.bits_per_sample)
st->codec.codec_tag= avcodec_pix_fmt_to_codec_tag(st->codec.pix_fmt);
+
+ if(best_duration[i] < INT64_MAX && st->codec.frame_rate_base*1000 <= st->codec.frame_rate){
+ int int_fps;
+
+ st->r_frame_rate= st->codec.frame_rate;
+ st->r_frame_rate_base= av_rescale(best_duration[i], st->codec.frame_rate, AV_TIME_BASE);
+ av_reduce(&st->r_frame_rate, &st->r_frame_rate_base, st->r_frame_rate, st->r_frame_rate_base, 1<<15);
+
+ int_fps= av_rescale(st->r_frame_rate, 1, st->r_frame_rate_base);
+
+ if(int_fps>0 && av_rescale(st->r_frame_rate, 1, int_fps) == st->r_frame_rate_base){
+ st->r_frame_rate= int_fps;
+ st->r_frame_rate_base= 1;
+ }
+ }
+
/* set real frame rate info */
/* compute the real frame rate for telecine */
if ((st->codec.codec_id == CODEC_ID_MPEG1VIDEO ||
higher level as it can change in a film */
if (coded_frame_rate >= 24.97 &&
(est_frame_rate >= 23.5 && est_frame_rate < 24.5)) {
- st->r_frame_rate = 24024;
+ st->r_frame_rate = 24000;
st->r_frame_rate_base = 1001;
}
}
int av_interleaved_write_frame(AVFormatContext *s, AVPacket *pkt){
AVStream *st= s->streams[ pkt->stream_index];
- if(compute_pkt_fields2(st, pkt) < 0)
- return -1;
-
//FIXME/XXX/HACK drop zero sized packets
if(st->codec.codec_type == CODEC_TYPE_AUDIO && pkt->size==0)
return 0;
+
+//av_log(NULL, AV_LOG_DEBUG, "av_interleaved_write_frame %d %Ld %Ld\n", pkt->size, pkt->dts, pkt->pts);
+ if(compute_pkt_fields2(st, pkt) < 0)
+ return -1;
if(pkt->dts == AV_NOPTS_VALUE)
return -1;
/* Then, we try to parse it as fraction */
cp = strchr(arg, '/');
+ if (!cp)
+ cp = strchr(arg, ':');
if (cp) {
char* cpp;
*frame_rate = strtol(arg, &cpp, 10);