ODML index parsing support
Originally committed as revision 5081 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
@@ -37,7 +37,7 @@ typedef struct AVIStream {
|
|||||||
int sample_size; /* audio only data */
|
int sample_size; /* audio only data */
|
||||||
int start;
|
int start;
|
||||||
|
|
||||||
int cum_len; /* temporary storage (used during seek) */
|
int64_t cum_len; /* temporary storage (used during seek) */
|
||||||
|
|
||||||
int prefix; ///< normally 'd'<<8 + 'c' or 'w'<<8 + 'b'
|
int prefix; ///< normally 'd'<<8 + 'c' or 'w'<<8 + 'b'
|
||||||
int prefix_count;
|
int prefix_count;
|
||||||
@@ -85,6 +85,65 @@ static int get_riff(AVIContext *avi, ByteIOContext *pb)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int read_braindead_odml_indx(AVFormatContext *s, int frame_num){
|
||||||
|
ByteIOContext *pb = &s->pb;
|
||||||
|
int longs_pre_entry= get_le16(pb);
|
||||||
|
int index_sub_type = get_byte(pb);
|
||||||
|
int index_type = get_byte(pb);
|
||||||
|
int entries_in_use = get_le32(pb);
|
||||||
|
int chunk_id = get_le32(pb);
|
||||||
|
int64_t base = get_le64(pb);
|
||||||
|
int stream_id= 10*((chunk_id&0xFF) - '0') + (((chunk_id>>8)&0xFF) - '0');
|
||||||
|
AVStream *st;
|
||||||
|
AVIStream *ast;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
// av_log(s, AV_LOG_ERROR, "longs_pre_entry:%d index_type:%d entries_in_use:%d chunk_id:%X base:%Ld\n",
|
||||||
|
// longs_pre_entry,index_type, entries_in_use, chunk_id, base);
|
||||||
|
|
||||||
|
if(stream_id > s->nb_streams || stream_id < 0)
|
||||||
|
return -1;
|
||||||
|
st= s->streams[stream_id];
|
||||||
|
ast = st->priv_data;
|
||||||
|
|
||||||
|
if(index_sub_type)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
get_le32(pb);
|
||||||
|
|
||||||
|
if(index_type && longs_pre_entry != 2)
|
||||||
|
return -1;
|
||||||
|
if(index_type>1)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
for(i=0; i<entries_in_use; i++){
|
||||||
|
if(index_type){
|
||||||
|
int64_t pos= get_le32(pb) + base;
|
||||||
|
int len = get_le32(pb);
|
||||||
|
|
||||||
|
av_add_index_entry(st, pos, ast->cum_len, 0, (len<0) ? 0 : AVINDEX_KEYFRAME);
|
||||||
|
len &= 0x7FFFFFFF;
|
||||||
|
|
||||||
|
if(ast->sample_size)
|
||||||
|
ast->cum_len += len / ast->sample_size;
|
||||||
|
else
|
||||||
|
ast->cum_len ++;
|
||||||
|
}else{
|
||||||
|
int64_t offset= get_le64(pb);
|
||||||
|
int size = get_le32(pb);
|
||||||
|
int duration = get_le32(pb);
|
||||||
|
int64_t pos= url_ftell(pb);
|
||||||
|
|
||||||
|
url_fseek(pb, offset+8, SEEK_SET);
|
||||||
|
read_braindead_odml_indx(s, frame_num);
|
||||||
|
frame_num += duration;
|
||||||
|
|
||||||
|
url_fseek(pb, pos, SEEK_SET);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int avi_read_header(AVFormatContext *s, AVFormatParameters *ap)
|
static int avi_read_header(AVFormatContext *s, AVFormatParameters *ap)
|
||||||
{
|
{
|
||||||
AVIContext *avi = s->priv_data;
|
AVIContext *avi = s->priv_data;
|
||||||
@@ -326,6 +385,12 @@ static int avi_read_header(AVFormatContext *s, AVFormatParameters *ap)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case MKTAG('i', 'n', 'd', 'x'):
|
||||||
|
i= url_ftell(pb);
|
||||||
|
read_braindead_odml_indx(s, 0);
|
||||||
|
avi->index_loaded=1;
|
||||||
|
url_fseek(pb, i+size, SEEK_SET);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
/* skip tag */
|
/* skip tag */
|
||||||
size += (size & 1);
|
size += (size & 1);
|
||||||
@@ -344,8 +409,8 @@ static int avi_read_header(AVFormatContext *s, AVFormatParameters *ap)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(!avi->index_loaded);
|
if(!avi->index_loaded)
|
||||||
avi_load_index(s);
|
avi_load_index(s);
|
||||||
avi->index_loaded = 1;
|
avi->index_loaded = 1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
Reference in New Issue
Block a user