diff --git a/cfg-common.h b/cfg-common.h index 6dd9cfdb83..7d8c87cbcd 100644 --- a/cfg-common.h +++ b/cfg-common.h @@ -77,6 +77,8 @@ {"noidx", &index_mode, CONF_TYPE_FLAG, 0, -1, 0, NULL}, {"idx", &index_mode, CONF_TYPE_FLAG, 0, -1, 1, NULL}, {"forceidx", &index_mode, CONF_TYPE_FLAG, 0, -1, 2, NULL}, + {"saveidx", &index_file_save, CONF_TYPE_STRING, 0, 0, 0, NULL}, + {"loadidx", &index_file_load, CONF_TYPE_STRING, 0, 0, 0, NULL}, // select audio/videosubtitle stream {"aid", &audio_id, CONF_TYPE_INT, CONF_RANGE, 0, 8190, NULL}, diff --git a/libmpdemux/aviheader.c b/libmpdemux/aviheader.c index 40ec3f9841..332b9d9b16 100644 --- a/libmpdemux/aviheader.c +++ b/libmpdemux/aviheader.c @@ -2,6 +2,7 @@ #include #include #include +#include #include "config.h" #include "mp_msg.h" @@ -44,6 +45,9 @@ while(1){ char* hdr=NULL; // if(stream_eof(demuxer->stream)) break; + // Imply -forceidx if -saveidx is specified + if (index_file_save) + index_mode = 2; // if(id==mmioFOURCC('L','I','S','T')){ unsigned len=stream_read_dword_le(demuxer->stream); // list size @@ -299,6 +303,44 @@ while(1){ } +/* Read a saved index file */ +if (index_file_load) { + FILE *fp; + char magic[7]; + unsigned int i; + + if ((fp = fopen(index_file_load, "r")) == NULL) { + mp_msg(MSGT_HEADER,MSGL_ERR, "Can't read index file %s: %s\n", index_file_load, strerror(errno)); + goto gen_index; + } + fread(&magic, 6, 1, fp); + if (strncmp(magic, "MPIDX1", 6)) { + mp_msg(MSGT_HEADER,MSGL_ERR, "%s is not a valid MPlayer index file\n", index_file_load); + goto gen_index; + } + fread(&priv->idx_size, sizeof(priv->idx_size), 1, fp); + priv->idx=malloc(priv->idx_size*sizeof(AVIINDEXENTRY)); + if (!priv->idx) { + mp_msg(MSGT_HEADER,MSGL_ERR, "Could not allocate memory for index data from %s\n", index_file_load); + priv->idx_size = 0; + goto gen_index; + } + + for (i=0; iidx_size;i++) { + AVIINDEXENTRY *idx; + idx=&((AVIINDEXENTRY *)priv->idx)[i]; + fread(idx, sizeof(AVIINDEXENTRY), 1, fp); + if (feof(fp)) { + mp_msg(MSGT_HEADER,MSGL_ERR, "Premature end of index file %s\n", index_file_load); + free(priv->idx); + priv->idx_size = 0; + goto gen_index; + } + } + fclose(fp); + mp_msg(MSGT_HEADER,MSGL_INFO, "Loaded index file: %s\n", index_file_load); +} +gen_index: if(index_mode>=2 || (priv->idx_size==0 && index_mode==1)){ // build index for file: stream_reset(demuxer->stream); @@ -381,8 +423,26 @@ skip_chunk: priv->idx_size=priv->idx_pos; mp_msg(MSGT_HEADER,MSGL_INFO,"AVI: Generated index table for %d chunks!\n",priv->idx_size); if(verbose>=2) print_index(priv->idx,priv->idx_size); -} + /* Write generated index to a file */ + if (index_file_save) { + FILE *fp; + unsigned int i; + + if ((fp=fopen(index_file_save, "w")) == NULL) { + mp_msg(MSGT_HEADER,MSGL_ERR, "Couldn't write index file %s: %s\n", index_file_save, strerror(errno)); + return; + } + fwrite("MPIDX1", 6, 1, fp); + fwrite(&priv->idx_size, sizeof(priv->idx_size), 1, fp); + for (i=0; iidx_size; i++) { + AVIINDEXENTRY *idx = &((AVIINDEXENTRY *)priv->idx)[i]; + fwrite(idx, sizeof(AVIINDEXENTRY), 1, fp); + } + fclose(fp); + mp_msg(MSGT_HEADER,MSGL_INFO, "Saved index file: %s\n", index_file_save); + } +} } #undef MIN diff --git a/libmpdemux/demux_avi.c b/libmpdemux/demux_avi.c index 8bec06712b..9f0be39285 100644 --- a/libmpdemux/demux_avi.c +++ b/libmpdemux/demux_avi.c @@ -425,6 +425,7 @@ do{ // AVI demuxer parameters: int index_mode=-1; // -1=untouched 0=don't use index 1=use (geneate) index +char *index_file_save = NULL, *index_file_load = NULL; int force_ni=0; // force non-interleaved AVI parsing void read_avi_header(demuxer_t *demuxer,int index_mode); diff --git a/libmpdemux/demuxer.h b/libmpdemux/demuxer.h index 5024443776..0e08ee02cf 100644 --- a/libmpdemux/demuxer.h +++ b/libmpdemux/demuxer.h @@ -265,6 +265,7 @@ demuxer_t* new_demuxers_demuxer(demuxer_t* vd, demuxer_t* ad, demuxer_t* sd); // AVI demuxer params: extern int index_mode; // -1=untouched 0=don't use index 1=use (geneate) index +extern char *index_file_save, *index_file_load; extern int force_ni; extern int pts_from_bps;