mirror of
https://github.com/mpv-player/mpv
synced 2025-01-09 01:36:25 +01:00
optimized demuxer for fixed samplesize (raw audio)
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@2116 b3059339-0415-0410-9bf9-f77b7e298cf2
This commit is contained in:
parent
3a55d08b34
commit
c39912c759
86
demux_mov.c
86
demux_mov.c
@ -26,8 +26,9 @@ typedef struct {
|
|||||||
} mov_sample_t;
|
} mov_sample_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
unsigned int size; // samples/chunk
|
unsigned int sample; // number of the first sample in teh chunk
|
||||||
int desc; // for multiple codecs mode - not used
|
unsigned int size; // number of samples in the chunk
|
||||||
|
int desc; // for multiple codecs mode - not used
|
||||||
off_t pos;
|
off_t pos;
|
||||||
} mov_chunk_t;
|
} mov_chunk_t;
|
||||||
|
|
||||||
@ -37,6 +38,11 @@ typedef struct {
|
|||||||
unsigned int sdid;
|
unsigned int sdid;
|
||||||
} mov_chunkmap_t;
|
} mov_chunkmap_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
unsigned int num;
|
||||||
|
unsigned int dur;
|
||||||
|
} mov_durmap_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int id;
|
int id;
|
||||||
int type;
|
int type;
|
||||||
@ -44,8 +50,11 @@ typedef struct {
|
|||||||
//
|
//
|
||||||
int timescale;
|
int timescale;
|
||||||
unsigned int length;
|
unsigned int length;
|
||||||
|
int samplesize; // 0 = variable
|
||||||
|
int duration; // 0 = variable
|
||||||
int width,height; // for video
|
int width,height; // for video
|
||||||
unsigned int fourcc;
|
unsigned int fourcc;
|
||||||
|
//
|
||||||
int tkdata_len; // track data
|
int tkdata_len; // track data
|
||||||
unsigned char* tkdata;
|
unsigned char* tkdata;
|
||||||
int stdata_len; // stream data
|
int stdata_len; // stream data
|
||||||
@ -56,11 +65,14 @@ typedef struct {
|
|||||||
mov_chunk_t* chunks;
|
mov_chunk_t* chunks;
|
||||||
int chunkmap_size;
|
int chunkmap_size;
|
||||||
mov_chunkmap_t* chunkmap;
|
mov_chunkmap_t* chunkmap;
|
||||||
|
int durmap_size;
|
||||||
|
mov_durmap_t* durmap;
|
||||||
} mov_track_t;
|
} mov_track_t;
|
||||||
|
|
||||||
void mov_build_index(mov_track_t* trak){
|
void mov_build_index(mov_track_t* trak){
|
||||||
int i,j,s;
|
int i,j,s;
|
||||||
int last=trak->chunks_size;
|
int last=trak->chunks_size;
|
||||||
|
unsigned int pts=0;
|
||||||
printf("MOV track: %d chunks, %d samples\n",trak->chunks_size,trak->samples_size);
|
printf("MOV track: %d chunks, %d samples\n",trak->chunks_size,trak->samples_size);
|
||||||
printf("pts=%d scale=%d time=%5.3f\n",trak->length,trak->timescale,(float)trak->length/(float)trak->timescale);
|
printf("pts=%d scale=%d time=%5.3f\n",trak->length,trak->timescale,(float)trak->length/(float)trak->timescale);
|
||||||
// process chunkmap:
|
// process chunkmap:
|
||||||
@ -73,6 +85,30 @@ void mov_build_index(mov_track_t* trak){
|
|||||||
}
|
}
|
||||||
last=trak->chunkmap[i].first;
|
last=trak->chunkmap[i].first;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// calc pts of chunks:
|
||||||
|
s=0;
|
||||||
|
for(j=0;j<trak->chunks_size;j++){
|
||||||
|
trak->chunks[j].sample=s;
|
||||||
|
s+=trak->chunks[j].size;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!trak->samples_size){
|
||||||
|
// constant sampesize
|
||||||
|
if(trak->durmap_size==1 || (trak->durmap_size==2 && trak->durmap[1].num==1)){
|
||||||
|
} else printf("*** constant samplesize & variable duration not yet supported! ***\nContact the author if you have such sample file!\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// calc pts:
|
||||||
|
s=0;
|
||||||
|
for(j=0;j<trak->durmap_size;j++){
|
||||||
|
for(i=0;i<trak->durmap[j].num;i++){
|
||||||
|
trak->samples[s].pts=pts;
|
||||||
|
++s;
|
||||||
|
pts+=trak->durmap[j].dur;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// calc sample offsets
|
// calc sample offsets
|
||||||
s=0;
|
s=0;
|
||||||
@ -242,22 +278,13 @@ static void lschunks(demuxer_t* demuxer,int level,off_t endpos,mov_track_t* trak
|
|||||||
int x=0;
|
int x=0;
|
||||||
unsigned int pts=0;
|
unsigned int pts=0;
|
||||||
mp_msg(MSGT_DEMUX,MSGL_V,"MOV: %*sSample duration table! (%d blocks)\n",level,"",len);
|
mp_msg(MSGT_DEMUX,MSGL_V,"MOV: %*sSample duration table! (%d blocks)\n",level,"",len);
|
||||||
|
trak->durmap=malloc(sizeof(mov_durmap_t)*len);
|
||||||
|
memset(trak->durmap,0,sizeof(mov_durmap_t)*len);
|
||||||
|
trak->durmap_size=len;
|
||||||
for(i=0;i<len;i++){
|
for(i=0;i<len;i++){
|
||||||
unsigned int num=stream_read_dword(demuxer->stream);
|
trak->durmap[i].num=stream_read_dword(demuxer->stream);
|
||||||
unsigned int dur=stream_read_dword(demuxer->stream);
|
trak->durmap[i].dur=stream_read_dword(demuxer->stream);
|
||||||
printf("num=%d dur=%d [%d] (%d)\n",num,dur,trak->samples_size,x);
|
pts+=trak->durmap[i].num*trak->durmap[i].dur;
|
||||||
num+=x;
|
|
||||||
// extend array if needed:
|
|
||||||
if(num>trak->samples_size){
|
|
||||||
trak->samples=realloc(trak->samples,sizeof(mov_sample_t)*num);
|
|
||||||
trak->samples_size=num;
|
|
||||||
}
|
|
||||||
// fill array:
|
|
||||||
while(x<num){
|
|
||||||
trak->samples[x].pts=pts;
|
|
||||||
pts+=dur;
|
|
||||||
++x;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if(trak->length!=pts) printf("Warning! pts=%d length=%d\n",pts,trak->length);
|
if(trak->length!=pts) printf("Warning! pts=%d length=%d\n",pts,trak->length);
|
||||||
break;
|
break;
|
||||||
@ -281,15 +308,15 @@ static void lschunks(demuxer_t* demuxer,int level,off_t endpos,mov_track_t* trak
|
|||||||
int temp=stream_read_dword(demuxer->stream);
|
int temp=stream_read_dword(demuxer->stream);
|
||||||
int ss=stream_read_dword(demuxer->stream);
|
int ss=stream_read_dword(demuxer->stream);
|
||||||
int len=stream_read_dword(demuxer->stream);
|
int len=stream_read_dword(demuxer->stream);
|
||||||
int i;
|
|
||||||
mp_msg(MSGT_DEMUX,MSGL_V,"MOV: %*sSample size table! len=%d ss=%d\n",level,"",len,ss);
|
mp_msg(MSGT_DEMUX,MSGL_V,"MOV: %*sSample size table! len=%d ss=%d\n",level,"",len,ss);
|
||||||
// extend array if needed:
|
trak->samplesize=ss;
|
||||||
if(len>trak->samples_size){
|
if(!ss){
|
||||||
|
// variable samplesize
|
||||||
|
int i;
|
||||||
trak->samples=realloc(trak->samples,sizeof(mov_sample_t)*len);
|
trak->samples=realloc(trak->samples,sizeof(mov_sample_t)*len);
|
||||||
trak->samples_size=len;
|
trak->samples_size=len;
|
||||||
}
|
for(i=0;i<len;i++)
|
||||||
for(i=0;i<len;i++){
|
trak->samples[i].size=stream_read_dword(demuxer->stream);
|
||||||
trak->samples[i].size=ss?ss:stream_read_dword(demuxer->stream);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -342,6 +369,7 @@ static void lschunks(demuxer_t* demuxer,int level,off_t endpos,mov_track_t* trak
|
|||||||
sh_audio_t* sh=new_sh_audio(demuxer,priv->track_db);
|
sh_audio_t* sh=new_sh_audio(demuxer,priv->track_db);
|
||||||
sh->format=trak->fourcc;
|
sh->format=trak->fourcc;
|
||||||
printf("!!! audio bits: %d chans: %d\n",trak->stdata[19],trak->stdata[17]);
|
printf("!!! audio bits: %d chans: %d\n",trak->stdata[19],trak->stdata[17]);
|
||||||
|
printf("Fourcc: %.4s\n",&trak->fourcc);
|
||||||
// Emulate WAVEFORMATEX struct:
|
// Emulate WAVEFORMATEX struct:
|
||||||
sh->wf=malloc(sizeof(WAVEFORMATEX));
|
sh->wf=malloc(sizeof(WAVEFORMATEX));
|
||||||
memset(sh->wf,0,sizeof(WAVEFORMATEX));
|
memset(sh->wf,0,sizeof(WAVEFORMATEX));
|
||||||
@ -377,6 +405,8 @@ static void lschunks(demuxer_t* demuxer,int level,off_t endpos,mov_track_t* trak
|
|||||||
sh->bih->biSizeImage=sh->bih->biWidth*sh->bih->biHeight;
|
sh->bih->biSizeImage=sh->bih->biWidth*sh->bih->biHeight;
|
||||||
|
|
||||||
printf("Image size: %d x %d\n",sh->disp_w,sh->disp_h);
|
printf("Image size: %d x %d\n",sh->disp_w,sh->disp_h);
|
||||||
|
printf("Fourcc: %.4s Codec: '%.*s'\n",&trak->fourcc,trak->stdata_len-43,trak->stdata+43);
|
||||||
|
|
||||||
if(demuxer->video->id==-1 || demuxer->video->id==priv->track_db){
|
if(demuxer->video->id==-1 || demuxer->video->id==priv->track_db){
|
||||||
// (auto)selected video track:
|
// (auto)selected video track:
|
||||||
demuxer->video->id=priv->track_db;
|
demuxer->video->id=priv->track_db;
|
||||||
@ -429,13 +459,21 @@ int demux_mov_fill_buffer(demuxer_t *demuxer,demux_stream_t* ds){
|
|||||||
if(ds->id<0 || ds->id>=priv->track_db) return 0;
|
if(ds->id<0 || ds->id>=priv->track_db) return 0;
|
||||||
trak=priv->tracks[ds->id];
|
trak=priv->tracks[ds->id];
|
||||||
|
|
||||||
|
if(trak->samplesize){
|
||||||
|
// read chunk:
|
||||||
|
if(trak->pos>=trak->chunks_size) return 0; // EOF
|
||||||
|
stream_seek(demuxer->stream,trak->chunks[trak->pos].pos);
|
||||||
|
pts=(float)(trak->chunks[trak->pos].sample*trak->duration)/(float)trak->timescale;
|
||||||
|
ds_read_packet(ds,demuxer->stream,trak->chunks[trak->pos].size*trak->samplesize,pts,trak->chunks[trak->pos].pos,0);
|
||||||
|
} else {
|
||||||
// read sample:
|
// read sample:
|
||||||
if(trak->pos>=trak->samples_size) return 0; // EOF
|
if(trak->pos>=trak->samples_size) return 0; // EOF
|
||||||
|
|
||||||
stream_seek(demuxer->stream,trak->samples[trak->pos].pos);
|
stream_seek(demuxer->stream,trak->samples[trak->pos].pos);
|
||||||
pts=(float)trak->samples[trak->pos].pts/(float)trak->timescale;
|
pts=(float)trak->samples[trak->pos].pts/(float)trak->timescale;
|
||||||
ds_read_packet(ds,demuxer->stream,trak->samples[trak->pos].size,pts,trak->samples[trak->pos].pos,0);
|
ds_read_packet(ds,demuxer->stream,trak->samples[trak->pos].size,pts,trak->samples[trak->pos].pos,0);
|
||||||
|
}
|
||||||
++trak->pos;
|
++trak->pos;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user