* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-//#define DEBUG
-//#define DEBUG_SEEK
-
#include <strings.h>
#include "libavutil/intreadwrite.h"
#include "libavutil/bswap.h"
#include "libavutil/opt.h"
+#include "libavutil/dict.h"
#include "avformat.h"
#include "avi.h"
#include "dv.h"
int64_t last_pos= -1;
int64_t filesize= avio_size(s->pb);
-#ifdef DEBUG_SEEK
- av_log(s, AV_LOG_ERROR, "longs_pre_entry:%d index_type:%d entries_in_use:%d chunk_id:%X base:%16"PRIX64"\n",
- longs_pre_entry,index_type, entries_in_use, chunk_id, base);
-#endif
+ av_dlog(s, "longs_pre_entry:%d index_type:%d entries_in_use:%d chunk_id:%X base:%16"PRIX64"\n",
+ longs_pre_entry,index_type, entries_in_use, chunk_id, base);
if(stream_id >= s->nb_streams || stream_id < 0)
return -1;
AV_WL32(key, tag);
- return av_metadata_set2(st ? &st->metadata : &s->metadata, key, value,
- AV_METADATA_DONT_STRDUP_VAL);
+ return av_dict_set(st ? &st->metadata : &s->metadata, key, value,
+ AV_DICT_DONT_STRDUP_VAL);
}
static void avi_read_info(AVFormatContext *s, uint64_t end)
static const char months[12][4] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
-static void avi_metadata_creation_time(AVMetadata **metadata, char *date)
+static void avi_metadata_creation_time(AVDictionary **metadata, char *date)
{
char month[4], time[9], buffer[64];
int i, day, year;
if (!strcasecmp(month, months[i])) {
snprintf(buffer, sizeof(buffer), "%.4d-%.2d-%.2d %s",
year, i+1, day, time);
- av_metadata_set2(metadata, "creation_time", buffer, 0);
+ av_dict_set(metadata, "creation_time", buffer, 0);
}
} else if (date[4] == '/' && date[7] == '/') {
date[4] = date[7] = '-';
- av_metadata_set2(metadata, "creation_time", date, 0);
+ av_dict_set(metadata, "creation_time", date, 0);
}
}
break;
}
if (name)
- av_metadata_set2(&s->metadata, name, buffer, 0);
+ av_dict_set(&s->metadata, name, buffer, 0);
avio_skip(s->pb, size);
}
break;
AVIContext *avi = s->priv_data;
AVIOContext *pb = s->pb;
unsigned int tag, tag1, handler;
- int codec_type, stream_index, frame_period, bit_rate;
+ int codec_type, stream_index, frame_period;
unsigned int size;
int i;
AVStream *st;
/* AVI header */
/* using frame_period is bad idea */
frame_period = avio_rl32(pb);
- bit_rate = avio_rl32(pb) * 8;
+ avio_rl32(pb); /* max. bytes per second */
avio_rl32(pb);
avi->non_interleaved |= avio_rl32(pb) & AVIF_MUSTUSEINDEX;
ret = avio_get_str16le(pb, desc_len, desc, sizeof(desc));
avio_skip(pb, desc_len - ret);
if (*desc)
- av_metadata_set2(&st->metadata, "title", desc, 0);
+ av_dict_set(&st->metadata, "title", desc, 0);
avio_rl16(pb); /* flags? */
avio_rl32(pb); /* data size */
e= &st->index_entries[index];
if(index >= 0 && e->timestamp == ast->frame_offset){
+ if (index == st->nb_index_entries-1){
+ int key=1;
+ int i;
+ uint32_t state=-1;
+ for(i=0; i<FFMIN(size,256); i++){
+ if(st->codec->codec_id == CODEC_ID_MPEG4){
+ if(state == 0x1B6){
+ key= !(pkt->data[i]&0xC0);
+ break;
+ }
+ }else
+ break;
+ state= (state<<8) + pkt->data[i];
+ }
+ if(!key)
+ e->flags &= ~AVINDEX_KEYFRAME;
+ }
if (e->flags & AVINDEX_KEYFRAME)
pkt->flags |= AV_PKT_FLAG_KEY;
}
flags = avio_rl32(pb);
pos = avio_rl32(pb);
len = avio_rl32(pb);
-#if defined(DEBUG_SEEK)
- av_log(s, AV_LOG_DEBUG, "%d: tag=0x%x flags=0x%x pos=0x%x len=%d/",
- i, tag, flags, pos, len);
-#endif
+ av_dlog(s, "%d: tag=0x%x flags=0x%x pos=0x%x len=%d/",
+ i, tag, flags, pos, len);
if(i==0 && pos > avi->movi_list)
avi->movi_list= 0; //FIXME better check
pos += avi->movi_list;
if (avio_seek(pb, avi->movi_end, SEEK_SET) < 0)
goto the_end; // maybe truncated file
-#ifdef DEBUG_SEEK
- printf("movi_end=0x%"PRIx64"\n", avi->movi_end);
-#endif
+ av_dlog(s, "movi_end=0x%"PRIx64"\n", avi->movi_end);
for(;;) {
if (url_feof(pb))
break;
tag = avio_rl32(pb);
size = avio_rl32(pb);
-#ifdef DEBUG_SEEK
- printf("tag=%c%c%c%c size=0x%x\n",
- tag & 0xff,
- (tag >> 8) & 0xff,
- (tag >> 16) & 0xff,
- (tag >> 24) & 0xff,
- size);
-#endif
+ av_dlog(s, "tag=%c%c%c%c size=0x%x\n",
+ tag & 0xff,
+ (tag >> 8) & 0xff,
+ (tag >> 16) & 0xff,
+ (tag >> 24) & 0xff,
+ size);
switch(tag) {
case MKTAG('i', 'd', 'x', '1'):
if (avi_read_idx1(s, size) < 0)
index=0;
ast2->seek_pos= st2->index_entries[index].pos;
pos_min= FFMIN(pos_min,ast2->seek_pos);
+ }
+ for(i = 0; i < s->nb_streams; i++) {
+ AVStream *st2 = s->streams[i];
+ AVIStream *ast2 = st2->priv_data;
+
+ if (ast2->sub_ctx || st2->nb_index_entries <= 0)
+ continue;
+
+ index = av_index_search_timestamp(
+ st2,
+ av_rescale_q(timestamp, st->time_base, st2->time_base) * FFMAX(ast2->sample_size, 1),
+ flags | AVSEEK_FLAG_BACKWARD);
+ if(index<0)
+ index=0;
+ while(index>0 && st2->index_entries[index-1].pos >= pos_min)
+ index--;
ast2->frame_offset = st2->index_entries[index].timestamp;
}