summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorarpi <arpi@b3059339-0415-0410-9bf9-f77b7e298cf2>2001-08-11 20:37:33 +0000
committerarpi <arpi@b3059339-0415-0410-9bf9-f77b7e298cf2>2001-08-11 20:37:33 +0000
commit610912b8b54129d84685247c1fd03346a7c71260 (patch)
tree8a06f15745ef39d4b2ebe093fd0183cecfa5d8db
parent5a0968079511913417e54a0aaf11ef60aa0e01fa (diff)
downloadmpv-610912b8b54129d84685247c1fd03346a7c71260.tar.bz2
mpv-610912b8b54129d84685247c1fd03346a7c71260.tar.xz
AVI demuxer cleanups, fileformat-dependent stuff moved to priv_t
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@1486 b3059339-0415-0410-9bf9-f77b7e298cf2
-rw-r--r--asf.h24
-rw-r--r--asfheader.c2
-rw-r--r--aviheader.c47
-rw-r--r--aviheader.h23
-rw-r--r--aviprint.c13
-rw-r--r--dec_audio.c1
-rw-r--r--demux_asf.c7
-rw-r--r--demux_avi.c286
-rw-r--r--demuxer.c105
-rw-r--r--demuxer.h29
-rw-r--r--mplayer.c7
-rw-r--r--seek.c13
12 files changed, 304 insertions, 253 deletions
diff --git a/asf.h b/asf.h
index b1bc0e2782..8d35563cda 100644
--- a/asf.h
+++ b/asf.h
@@ -156,12 +156,36 @@ typedef enum {
(h)->comment_size = le2me_16((h)->comment_size); \
(h)->rating_size = le2me_16((h)->rating_size); \
}
+#define le2me_BITMAPINFOHEADER(h) { \
+ (h)->biSize = le2me_32((h)->biSize); \
+ (h)->biWidth = le2me_32((h)->biWidth); \
+ (h)->biHeight = le2me_32((h)->biHeight); \
+ (h)->biPlanes = le2me_16((h)->biPlanes); \
+ (h)->biBitCount = le2me_16((h)->biBitCount); \
+ (h)->biCompression = le2me_32((h)->biCompression); \
+ (h)->biSizeImage = le2me_32((h)->biSizeImage); \
+ (h)->biXPelsPerMeter = le2me_32((h)->biXPelsPerMeter); \
+ (h)->biYPelsPerMeter = le2me_32((h)->biYPelsPerMeter); \
+ (h)->biClrUsed = le2me_32((h)->biClrUsed); \
+ (h)->biClrImportant = le2me_32((h)->biClrImportant); \
+}
+#define le2me_WAVEFORMATEX(h) { \
+ (h)->wFormatTag = le2me_16((h)->wFormatTag); \
+ (h)->nChannels = le2me_16((h)->nChannels); \
+ (h)->nSamplesPerSec = le2me_32((h)->nSamplesPerSec); \
+ (h)->nAvgBytesPerSec = le2me_32((h)->nAvgBytesPerSec); \
+ (h)->nBlockAlign = le2me_16((h)->nBlockAlign); \
+ (h)->wBitsPerSample = le2me_16((h)->wBitsPerSample); \
+ (h)->cbSize = le2me_16((h)->cbSize); \
+}
#else
#define le2me_ASF_obj_header_t(h) /**/
#define le2me_ASF_header_t(h) /**/
#define le2me_ASF_stream_header_t(h) /**/
#define le2me_ASF_file_header_t(h) /**/
#define le2me_ASF_content_description_t(h) /**/
+#define le2me_BITMAPINFOHEADER(h) /**/
+#define le2me_WAVEFORMATEX(h) /**/
#endif
diff --git a/asfheader.c b/asfheader.c
index 469aa98370..a2a51115b9 100644
--- a/asfheader.c
+++ b/asfheader.c
@@ -16,7 +16,7 @@ extern int verbose; // defined in mplayer.c
#include "codec-cfg.h"
#include "stheader.h"
-#include "aviheader.h"
+//#include "aviheader.h"
#include "asf.h"
#ifdef ARCH_X86
diff --git a/aviheader.c b/aviheader.c
index e9ca704fa4..b73b4a1935 100644
--- a/aviheader.c
+++ b/aviheader.c
@@ -1,9 +1,10 @@
-#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
+#include "config.h"
+
extern int verbose; // defined in mplayer.c
#include "stream.h"
@@ -35,9 +36,10 @@ sh_video_t *sh_video=NULL;
int stream_id=-1;
int idxfix_videostream=0;
int idxfix_divx=0;
+avi_priv_t* priv=demuxer->priv;
//---- AVI header:
-demuxer->idx_size=0;
+priv->idx_size=0;
while(1){
int id=stream_read_dword_le(demuxer->stream);
int chunksize,size2;
@@ -137,15 +139,15 @@ while(1){
}
case ckidAVINEWINDEX: if(index_mode){
int i;
- demuxer->idx_size=size2>>4;
+ priv->idx_size=size2>>4;
if(verbose>=1) printf("Reading INDEX block, %d chunks for %ld frames\n",
- demuxer->idx_size,avih.dwTotalFrames);
- demuxer->idx=malloc(demuxer->idx_size<<4);
- stream_read(demuxer->stream,(char*)demuxer->idx,demuxer->idx_size<<4);
- for (i = 0; i < demuxer->idx_size; i++) // swap index to machine endian
- le2me_AVIINDEXENTRY((AVIINDEXENTRY*)demuxer->idx + i);
- chunksize-=demuxer->idx_size<<4;
- if(verbose>=2) print_index(demuxer->idx,demuxer->idx_size);
+ priv->idx_size,avih.dwTotalFrames);
+ priv->idx=malloc(priv->idx_size<<4);
+ stream_read(demuxer->stream,(char*)priv->idx,priv->idx_size<<4);
+ for (i = 0; i < priv->idx_size; i++) // swap index to machine endian
+ le2me_AVIINDEXENTRY((AVIINDEXENTRY*)priv->idx + i);
+ chunksize-=priv->idx_size<<4;
+ if(verbose>=2) print_index(priv->idx,priv->idx_size);
break;
}
}
@@ -154,14 +156,14 @@ while(1){
}
-if(index_mode>=2 || (demuxer->idx_size==0 && index_mode==1)){
+if(index_mode>=2 || (priv->idx_size==0 && index_mode==1)){
// build index for file:
stream_reset(demuxer->stream);
stream_seek(demuxer->stream,demuxer->movi_start);
- demuxer->idx_pos=0;
- demuxer->idx_size=0;
- demuxer->idx=NULL;
+ priv->idx_pos=0;
+ priv->idx_size=0;
+ priv->idx=NULL;
while(1){
int id,len,skip;
@@ -178,13 +180,13 @@ if(index_mode>=2 || (demuxer->idx_size==0 && index_mode==1)){
if(stream_eof(demuxer->stream)) break;
if(!id || avi_stream_id(id)==100) goto skip_chunk; // bad ID (or padding?)
- if(demuxer->idx_pos<=demuxer->idx_size){
-// demuxer->idx_size+=32;
- demuxer->idx_size+=1024; // +16kB
- demuxer->idx=realloc(demuxer->idx,demuxer->idx_size*sizeof(AVIINDEXENTRY));
- if(!demuxer->idx){demuxer->idx_pos=0; break;} // error!
+ if(priv->idx_pos<=priv->idx_size){
+// priv->idx_size+=32;
+ priv->idx_size+=1024; // +16kB
+ priv->idx=realloc(priv->idx,priv->idx_size*sizeof(AVIINDEXENTRY));
+ if(!priv->idx){priv->idx_pos=0; break;} // error!
}
- idx=&((AVIINDEXENTRY *)demuxer->idx)[demuxer->idx_pos++];
+ idx=&((AVIINDEXENTRY *)priv->idx)[priv->idx_pos++];
idx->ckid=id;
idx->dwFlags=AVIIF_KEYFRAME; // FIXME
idx->dwChunkOffset=demuxer->filepos;
@@ -212,11 +214,12 @@ skip_chunk:
skip=(len+1)&(~1); // total bytes in this chunk
stream_seek(demuxer->stream,8+demuxer->filepos+skip);
}
- demuxer->idx_size=demuxer->idx_pos;
- printf("AVI: Generated index table for %d chunks!\n",demuxer->idx_size);
+ priv->idx_size=priv->idx_pos;
+ printf("AVI: Generated index table for %d chunks!\n",priv->idx_size);
}
}
#undef MIN
+
diff --git a/aviheader.h b/aviheader.h
index 9f234911c2..d3d129b691 100644
--- a/aviheader.h
+++ b/aviheader.h
@@ -1,7 +1,7 @@
#ifndef _aviheader_h
#define _aviheader_h
-#include "config.h" /* get correct definition WORDS_BIGENDIAN */
+//#include "config.h" /* get correct definition WORDS_BIGENDIAN */
#include "bswap.h"
/*
@@ -83,3 +83,24 @@
#endif
+
+
+typedef struct {
+ // index stuff:
+ void* idx;
+ int idx_size;
+ int idx_pos;
+ int idx_pos_a;
+ int idx_pos_v;
+ int idx_offset; // ennyit kell hozzaadni az index offset ertekekhez
+ // interleaved PTS stuff:
+ int skip_video_frames;
+ float avi_audio_pts;
+ float avi_video_pts;
+ float pts_correction;
+ unsigned int pts_corr_bytes;
+ unsigned char pts_corrected;
+ unsigned char pts_has_video;
+} avi_priv_t;
+
+#define AVI_PRIV ((avi_priv_t*)(demuxer->priv))
diff --git a/aviprint.c b/aviprint.c
index 29ae39c667..c8fdceea15 100644
--- a/aviprint.c
+++ b/aviprint.c
@@ -79,14 +79,23 @@ void print_video_header(BITMAPINFOHEADER *h){
void print_index(AVIINDEXENTRY *idx,int idx_size){
int i;
+ unsigned int pos[256];
+ unsigned int num[256];
+ for(i=0;i<256;i++) num[i]=pos[i]=0;
for(i=0;i<idx_size;i++){
- printf("%5d: %.4s %4X %08X %ld\n",i,
+ int id=avi_stream_id(idx[i].ckid);
+ if(id<0 || id>255) id=255;
+ printf("%5d: %.4s %4X %08X len:%6ld pos:%7d->%7.3f %7d->%7.3f\n",i,
(char *)&idx[i].ckid,
(unsigned int)idx[i].dwFlags,
(unsigned int)idx[i].dwChunkOffset,
// idx[i].dwChunkOffset+demuxer->movi_start,
- idx[i].dwChunkLength
+ idx[i].dwChunkLength,
+ pos[id],(float)pos[id]/18747.0f,
+ num[id],(float)num[id]/23.976f
);
+ pos[id]+=idx[i].dwChunkLength;
+ ++num[id];
}
}
diff --git a/dec_audio.c b/dec_audio.c
index 681ca1004d..1cc9bd083b 100644
--- a/dec_audio.c
+++ b/dec_audio.c
@@ -282,6 +282,7 @@ int decode_audio(sh_audio_t *sh_audio,unsigned char *buf,int minlen,int maxlen){
switch(sh_audio->codec->driver){
case AFM_MPEG: // MPEG layer 2 or 3
len=MP3_DecodeFrame(buf,-1);
+// len=MP3_DecodeFrame(buf,3);
break;
case AFM_PCM: // AVI PCM
len=demux_read_data(sh_audio->ds,buf,minlen);
diff --git a/demux_asf.c b/demux_asf.c
index 9c5c84171d..e7d4ac3f3e 100644
--- a/demux_asf.c
+++ b/demux_asf.c
@@ -37,13 +37,6 @@ extern int asf_packetsize;
// based on asf file-format doc by Eugene [http://divx.euro.ru]
-//static float avi_pts_frametime=1.0f/25.0f;
-//static float avi_audio_pts=0;
-//static float avi_video_pts=0;
-
-//static int skip_video_frames=0;
-
-
static void asf_descrambling(unsigned char *src,int len){
unsigned char *dst=malloc(len);
unsigned char *s2=src;
diff --git a/demux_avi.c b/demux_avi.c
index fa7b18acd4..2a52e7bad5 100644
--- a/demux_avi.c
+++ b/demux_avi.c
@@ -1,4 +1,4 @@
-// AVI file parser for DEMUXER v2.6 by A'rpi/ESP-team
+// AVI file parser for DEMUXER v2.9 by A'rpi/ESP-team
#include <stdio.h>
#include <stdlib.h>
@@ -16,11 +16,7 @@ extern int verbose; // defined in mplayer.c
#include "codec-cfg.h"
#include "stheader.h"
-//static float avi_pts_frametime=1.0f/25.0f;
-float avi_audio_pts=0;
-float avi_video_pts=0;
-//float avi_video_ftime=0.04;
-int skip_video_frames=0;
+#include "aviheader.h"
// Select ds from ID
demux_stream_t* demux_avi_select_stream(demuxer_t *demux,unsigned int id){
@@ -58,12 +54,9 @@ demux_stream_t* demux_avi_select_stream(demuxer_t *demux,unsigned int id){
return NULL;
}
-static float pts_correction=0.0;
-static int pts_corrected=0;
-static int pts_has_video=0;
-static unsigned int pts_corr_bytes=0;
static int demux_avi_read_packet(demuxer_t *demux,unsigned int id,unsigned int len,int idxpos,int flags){
+ avi_priv_t *priv=demux->priv;
int skip;
float pts=0;
demux_stream_t *ds=demux_avi_select_stream(demux,id);
@@ -72,50 +65,50 @@ static int demux_avi_read_packet(demuxer_t *demux,unsigned int id,unsigned int l
if(ds==demux->audio){
- if(pts_corrected==0){
-// printf("\rYYY-A A: %5.3f V: %5.3f \n",avi_audio_pts,avi_video_pts);
- if(pts_has_video){
+ if(priv->pts_corrected==0){
+// printf("\rYYY-A A: %5.3f V: %5.3f \n",priv->avi_audio_pts,priv->avi_video_pts);
+ if(priv->pts_has_video){
// we have video pts now
- float delay=(float)pts_corr_bytes/((sh_audio_t*)(ds->sh))->wf->nAvgBytesPerSec;
- printf("XXX initial v_pts=%5.3f a_pos=%d (%5.3f) \n",avi_audio_pts,pts_corr_bytes,delay);
- //pts_correction=-avi_audio_pts+delay;
- pts_correction=delay-avi_audio_pts;
- avi_audio_pts+=pts_correction;
- pts_corrected=1;
+ float delay=(float)priv->pts_corr_bytes/((sh_audio_t*)(ds->sh))->wf->nAvgBytesPerSec;
+ printf("XXX initial v_pts=%5.3f a_pos=%d (%5.3f) \n",priv->avi_audio_pts,priv->pts_corr_bytes,delay);
+ //priv->pts_correction=-priv->avi_audio_pts+delay;
+ priv->pts_correction=delay-priv->avi_audio_pts;
+ priv->avi_audio_pts+=priv->pts_correction;
+ priv->pts_corrected=1;
} else
- pts_corr_bytes+=len;
+ priv->pts_corr_bytes+=len;
}
- pts=avi_audio_pts; //+pts_correction;
- avi_audio_pts=0;
+ pts=priv->avi_audio_pts; //+priv->pts_correction;
+ priv->avi_audio_pts=0;
} else
if(ds==demux->video){
// video
- if(skip_video_frames>0){
+ if(priv->skip_video_frames>0){
// drop frame (seeking)
- --skip_video_frames;
+ --priv->skip_video_frames;
ds=NULL;
} else {
- pts=avi_video_pts;
+ pts=priv->avi_video_pts;
}
// ezt a 2 sort lehet hogy fell kell majd cserelni:
- //avi_video_pts+=avi_pts_frametime;
- //avi_video_pts+=(float)avi_header.video.dwScale/(float)avi_header.video.dwRate;
- //avi_video_pts+=((sh_video_t*)ds->sh)->frametime;
+ //priv->avi_video_pts+=avi_pts_frametime;
+ //priv->avi_video_pts+=(float)avi_header.video.dwScale/(float)avi_header.video.dwRate;
+ //priv->avi_video_pts+=((sh_video_t*)ds->sh)->frametime;
// FIXME!!!
#if 1
// printf("ds=0x%X\n",ds);
// printf("packno=%d\n",ds->pack_no);
// printf("### pack_no=%d\n",demux->video->pack_no+demux->video->packs);
- avi_video_pts = (demux->video->pack_no+demux->video->packs) *
+ priv->avi_video_pts = (demux->video->pack_no+demux->video->packs) *
(float)((sh_video_t*)demux->video->sh)->video.dwScale /
(float)((sh_video_t*)demux->video->sh)->video.dwRate;
#else
- avi_video_pts+=(float)((sh_video_t*)(demux->video->sh))->video.dwScale/(float)((sh_video_t*)(demux->video->sh))->video.dwRate;
-// avi_video_pts+=avi_video_ftime;
+ priv->avi_video_pts+=(float)((sh_video_t*)(demux->video->sh))->video.dwScale/(float)((sh_video_t*)(demux->video->sh))->video.dwRate;
+// priv->avi_video_pts+=avi_video_ftime;
#endif
-// printf("\rYYY-V A: %5.3f V: %5.3f \n",avi_audio_pts,avi_video_pts);
- avi_audio_pts=avi_video_pts+pts_correction;
- pts_has_video=1;
+// printf("\rYYY-V A: %5.3f V: %5.3f \n",priv->avi_audio_pts,priv->avi_video_pts);
+ priv->avi_audio_pts=priv->avi_video_pts+priv->pts_correction;
+ priv->pts_has_video=1;
}
@@ -134,13 +127,11 @@ static int demux_avi_read_packet(demuxer_t *demux,unsigned int id,unsigned int l
return ds?1:0;
}
-//static int num_elementary_packets100=0;
-//static int num_elementary_packets101=0;
-
// return value:
// 0 = EOF or no stream found
// 1 = successfully read a packet
int demux_avi_fill_buffer(demuxer_t *demux){
+avi_priv_t *priv=demux->priv;
unsigned int id=0;
unsigned int len;
int max_packs=128;
@@ -157,14 +148,14 @@ do{
}
if(stream_eof(demux->stream)) return 0;
#endif
- if(demux->idx_size>0 && demux->idx_pos<demux->idx_size){
+ if(priv->idx_size>0 && priv->idx_pos<priv->idx_size){
unsigned int pos;
- //if(demux->idx_pos<0) printf("Fatal! idx_pos=%d\n",demux->idx_pos);
+ //if(priv->idx_pos<0) printf("Fatal! idx_pos=%d\n",priv->idx_pos);
- idx=&((AVIINDEXENTRY *)demux->idx)[demux->idx_pos++];
+ idx=&((AVIINDEXENTRY *)priv->idx)[priv->idx_pos++];
- //printf("[%d]",demux->idx_pos);fflush(stdout);
+ //printf("[%d]",priv->idx_pos);fflush(stdout);
//stream_seek(demux->stream,idx.dwChunkOffset);
//printf("IDX pos=%X idx.pos=%X idx.size=%X idx.flags=%X\n",demux->filepos,
@@ -178,7 +169,7 @@ do{
continue; // skip this chunk
}
- pos=idx->dwChunkOffset+demux->idx_offset;
+ pos=idx->dwChunkOffset+priv->idx_offset;
if(pos<demux->movi_start || pos>=demux->movi_end){
printf("ChunkOffset out of range! idx=0x%X \n",pos);
continue;
@@ -222,8 +213,8 @@ do{
continue;
}
}
- ret=demux_avi_read_packet(demux,id,len,demux->idx_pos-1,flags);
- if(!ret && skip_video_frames<=0)
+ ret=demux_avi_read_packet(demux,id,len,priv->idx_pos-1,flags);
+ if(!ret && priv->skip_video_frames<=0)
if(--max_packs==0){
demux->stream->eof=1;
printf("demux: file doesn't contain the selected audio or video stream\n");
@@ -238,6 +229,7 @@ do{
// 0 = EOF or no stream found
// 1 = successfully read a packet
int demux_avi_fill_buffer_ni(demuxer_t *demux,demux_stream_t* ds){
+avi_priv_t *priv=demux->priv;
unsigned int id=0;
unsigned int len;
int max_packs=128;
@@ -249,14 +241,14 @@ do{
int idx_pos=0;
demux->filepos=stream_tell(demux->stream);
- if(ds==demux->video) idx_pos=demux->idx_pos_v++; else
- if(ds==demux->audio) idx_pos=demux->idx_pos_a++; else
- idx_pos=demux->idx_pos++;
+ if(ds==demux->video) idx_pos=priv->idx_pos_v++; else
+ if(ds==demux->audio) idx_pos=priv->idx_pos_a++; else
+ idx_pos=priv->idx_pos++;
- if(demux->idx_size>0 && idx_pos<demux->idx_size){
+ if(priv->idx_size>0 && idx_pos<priv->idx_size){
unsigned int pos;
- idx=&((AVIINDEXENTRY *)demux->idx)[idx_pos];
-// idx=&demux->idx[idx_pos];
+ idx=&((AVIINDEXENTRY *)priv->idx)[idx_pos];
+// idx=&priv->idx[idx_pos];
if(idx->dwFlags&AVIIF_LIST){
// LIST
@@ -267,7 +259,7 @@ do{
continue; // skip this chunk
}
- pos=idx->dwChunkOffset+demux->idx_offset;
+ pos=idx->dwChunkOffset+priv->idx_offset;
if(pos<demux->movi_start || pos>=demux->movi_end){
printf("ChunkOffset out of range! current=0x%X idx=0x%X \n",demux->filepos,pos);
continue;
@@ -299,7 +291,7 @@ do{
if(idx->dwFlags&AVIIF_KEYFRAME) flags=1;
} else return 0;
ret=demux_avi_read_packet(demux,id,len,idx_pos,flags);
- if(!ret && skip_video_frames<=0)
+ if(!ret && priv->skip_video_frames<=0)
if(--max_packs==0){
demux->stream->eof=1;
printf("demux: file doesn't contain the selected audio or video stream\n");
@@ -314,13 +306,14 @@ do{
// 0 = EOF or no stream found
// 1 = successfully read a packet
int demux_avi_fill_buffer_nini(demuxer_t *demux,demux_stream_t* ds){
+avi_priv_t *priv=demux->priv;
unsigned int id=0;
unsigned int len;
int ret=0;
int *fpos=NULL;
- if(ds==demux->video) fpos=&demux->idx_pos_v; else
- if(ds==demux->audio) fpos=&demux->idx_pos_a; else
+ if(ds==demux->video) fpos=&priv->idx_pos_v; else
+ if(ds==demux->audio) fpos=&priv->idx_pos_a; else
return 0;
stream_seek(demux->stream,fpos[0]);
@@ -343,7 +336,7 @@ do{
if(ds==demux_avi_select_stream(demux,id)){
// read it!
- ret=demux_avi_read_packet(demux,id,len,demux->idx_pos-1,0);
+ ret=demux_avi_read_packet(demux,id,len,priv->idx_pos-1,0);
} else {
// skip it!
int skip=(len+1)&(~1); // total bytes in this chunk
@@ -355,9 +348,130 @@ do{
return 1;
}
-extern float initial_pts_delay;
+extern int audio_id;
+extern int video_id;
+extern int index_mode; // -1=untouched 0=don't use index 1=use (geneate) index
+extern int force_ni;
+extern int pts_from_bps;
+
+demuxer_t* demux_open_avi(demuxer_t* demuxer){
+ demux_stream_t *d_audio=demuxer->audio;
+ demux_stream_t *d_video=demuxer->video;
+ sh_audio_t *sh_audio=NULL;
+ sh_video_t *sh_video=NULL;
+ avi_priv_t* priv=malloc(sizeof(avi_priv_t));
+
+ // priv struct:
+ priv->avi_audio_pts=priv->avi_video_pts=0.0f;
+ priv->pts_correction=0.0f;
+ priv->skip_video_frames=0;
+ priv->pts_corr_bytes=0;
+ priv->pts_has_video=priv->pts_corrected=0;
+ demuxer->priv=(void*)priv;
+
+ //---- AVI header:
+ read_avi_header(demuxer,(demuxer->stream->type!=STREAMTYPE_STREAM)?index_mode:-2);
+ stream_reset(demuxer->stream);
+ stream_seek(demuxer->stream,demuxer->movi_start);
+ priv->idx_pos=0;
+ priv->idx_pos_a=0;
+ priv->idx_pos_v=0;
+ if(priv->idx_size>0){
+ // decide index format:
+ if(((AVIINDEXENTRY *)priv->idx)[0].dwChunkOffset<demuxer->movi_start)
+ priv->idx_offset=demuxer->movi_start-4;
+ else
+ priv->idx_offset=0;
+ if(verbose) printf("AVI index offset: %d\n",priv->idx_offset);
+ }
+// demuxer->endpos=avi_header.movi_end;
+
+ if(priv->idx_size>0){
+ // check that file is non-interleaved:
+ int i;
+ int a_pos=-1;
+ int v_pos=-1;
+ for(i=0;i<priv->idx_size;i++){
+ AVIINDEXENTRY* idx=&((AVIINDEXENTRY *)priv->idx)[i];
+ demux_stream_t* ds=demux_avi_select_stream(demuxer,idx->ckid);
+ int pos=idx->dwChunkOffset+priv->idx_offset;
+ if(a_pos==-1 && ds==demuxer->audio){
+ a_pos=pos;
+ if(v_pos!=-1) break;
+ }
+ if(v_pos==-1 && ds==demuxer->video){
+ v_pos=pos;
+ if(a_pos!=-1) break;
+ }
+ }
+ if(v_pos==-1){
+ fprintf(stderr,"AVI_NI: missing video stream!? contact the author, it may be a bug :(\n");
+ return NULL;
+// GUI_MSG( mplErrorAVINI )
+// exit(1);
+ }
+ if(a_pos==-1){
+ printf("AVI_NI: No audio stream found -> nosound\n");
+ sh_audio=NULL;
+ } else {
+ if(force_ni || abs(a_pos-v_pos)>0x100000){ // distance > 1MB
+ printf("%s NON-INTERLEAVED AVI file-format!\n",force_ni?"Forced":"Detected");
+ demuxer->type=DEMUXER_TYPE_AVI_NI; // HACK!!!!
+ pts_from_bps=1; // force BPS sync!
+ }
+ }
+ } else {
+ // no index
+ if(force_ni){
+ printf("Using NON-INTERLEAVED Broken AVI file-format!\n");
+ demuxer->type=DEMUXER_TYPE_AVI_NINI; // HACK!!!!
+ priv->idx_pos_a=
+ priv->idx_pos_v=demuxer->movi_start;
+ pts_from_bps=1; // force BPS sync!
+ }
+ }
+ if(!ds_fill_buffer(d_video)){
+ fprintf(stderr,"AVI: missing video stream!? contact the author, it may be a bug :(\n");
+ return NULL;
+// GUI_MSG( mplAVIErrorMissingVideoStream )
+// exit(1);
+ }
+ sh_video=d_video->sh;sh_video->ds=d_video;
+ if(audio_id!=-2){
+ if(verbose) printf("AVI: Searching for audio stream (id:%d)\n",d_audio->id);
+ if(!ds_fill_buffer(d_audio)){
+ printf("AVI: No Audio stream found... ->nosound\n");
+ sh_audio=NULL;
+ } else {
+ sh_audio=d_audio->sh;sh_audio->ds=d_audio;
+ sh_audio->format=sh_audio->wf->wFormatTag;
+ }
+ }
+ // calc. FPS:
+ sh_video->fps=(float)sh_video->video.dwRate/(float)sh_video->video.dwScale;
+ sh_video->frametime=(float)sh_video->video.dwScale/(float)sh_video->video.dwRate;
+ // calculating video bitrate:
+ sh_video->i_bps=demuxer->movi_end-demuxer->movi_start-priv->idx_size*8;
+ if(sh_audio) sh_video->i_bps-=sh_audio->audio.dwLength;
+ if(verbose) printf("AVI video length=%d\n",sh_video->i_bps);
+ sh_video->i_bps=((float)sh_video->i_bps/(float)sh_video->video.dwLength)*sh_video->fps;
+ printf("VIDEO: [%.4s] %ldx%ld %dbpp %4.2f fps %5.1f kbps (%4.1f kbyte/s)\n",
+ (char *)&sh_video->bih->biCompression,
+ sh_video->bih->biWidth,
+ sh_video->bih->biHeight,
+ sh_video->bih->biBitCount,
+ sh_video->fps,
+ sh_video->i_bps*0.008f,
+ sh_video->i_bps/1024.0f );
+
+ return demuxer;
+
+}
+
+//extern float initial_pts_delay;
void demux_seek_avi(demuxer_t *demuxer,float rel_seek_secs,int flags){
+ avi_priv_t *priv=demuxer->priv;
demux_stream_t *d_audio=demuxer->audio;
demux_stream_t *d_video=demuxer->video;
sh_audio_t *sh_audio=d_audio->sh;
@@ -370,40 +484,40 @@ void demux_seek_avi(demuxer_t *demuxer,float rel_seek_secs,int flags){
int video_chunk_pos=d_video->pos;
int i;
- skip_video_frames=0;
- avi_audio_pts=0;
+ priv->skip_video_frames=0;
+ priv->avi_audio_pts=0;
// ------------ STEP 1: find nearest video keyframe chunk ------------
// find nearest video keyframe chunk pos:
if(rel_seek_frames>0){
// seek forward
- while(video_chunk_pos<demuxer->idx_size){
- int id=((AVIINDEXENTRY *)demuxer->idx)[video_chunk_pos].ckid;
+ while(video_chunk_pos<priv->idx_size){
+ int id=((AVIINDEXENTRY *)priv->idx)[video_chunk_pos].ckid;
if(avi_stream_id(id)==d_video->id){ // video frame
- if((--rel_seek_frames)<0 && ((AVIINDEXENTRY *)demuxer->idx)[video_chunk_pos].dwFlags&AVIIF_KEYFRAME) break;
+ if((--rel_seek_frames)<0 && ((AVIINDEXENTRY *)priv->idx)[video_chunk_pos].dwFlags&AVIIF_KEYFRAME) break;
}
++video_chunk_pos;
}
} else {
// seek backward
while(video_chunk_pos>=0){
- int id=((AVIINDEXENTRY *)demuxer->idx)[video_chunk_pos].ckid;
+ int id=((AVIINDEXENTRY *)priv->idx)[video_chunk_pos].ckid;
if(avi_stream_id(id)==d_video->id){ // video frame
- if((++rel_seek_frames)>0 && ((AVIINDEXENTRY *)demuxer->idx)[video_chunk_pos].dwFlags&AVIIF_KEYFRAME) break;
+ if((++rel_seek_frames)>0 && ((AVIINDEXENTRY *)priv->idx)[video_chunk_pos].dwFlags&AVIIF_KEYFRAME) break;
}
--video_chunk_pos;
}
}
- demuxer->idx_pos_a=demuxer->idx_pos_v=demuxer->idx_pos=video_chunk_pos;
+ priv->idx_pos_a=priv->idx_pos_v=priv->idx_pos=video_chunk_pos;
// re-calc video pts:
d_video->pack_no=0;
for(i=0;i<video_chunk_pos;i++){
- int id=((AVIINDEXENTRY *)demuxer->idx)[i].ckid;
+ int id=((AVIINDEXENTRY *)priv->idx)[i].ckid;
if(avi_stream_id(id)==d_video->id) ++d_video->pack_no;
}
sh_video->num_frames=d_video->pack_no;
- avi_video_pts=d_video->pack_no*(float)sh_video->video.dwScale/(float)sh_video->video.dwRate;
+ priv->avi_video_pts=d_video->pack_no*(float)sh_video->video.dwScale/(float)sh_video->video.dwRate;
d_video->pos=video_chunk_pos;
// ------------ STEP 2: seek audio, find the right chunk & pos ------------
@@ -419,28 +533,28 @@ void demux_seek_avi(demuxer_t *demuxer,float rel_seek_secs,int flags){
int skip_audio_bytes=0;
int curr_audio_pos=-1;
int audio_chunk_pos=-1;
- int chunk_max=(demuxer->type==DEMUXER_TYPE_AVI)?video_chunk_pos:demuxer->idx_size;
+ int chunk_max=(demuxer->type==DEMUXER_TYPE_AVI)?video_chunk_pos:priv->idx_size;
if(sh_audio->audio.dwSampleSize){
// constant rate audio stream
#if 0
int align;
- curr_audio_pos=(avi_video_pts) * sh_audio->wf->nAvgBytesPerSec;
+ curr_audio_pos=(priv->avi_video_pts) * sh_audio->wf->nAvgBytesPerSec;
if(curr_audio_pos<0)curr_audio_pos=0;
align=sh_audio->audio.dwSampleSize;
if(sh_audio->wf->nBlockAlign>align) align=sh_audio->wf->nBlockAlign;
curr_audio_pos/=align;
curr_audio_pos*=align;
#else
- curr_audio_pos=(avi_video_pts)*(float)sh_audio->audio.dwRate/(float)sh_audio->audio.dwScale;
+ curr_audio_pos=(priv->avi_video_pts)*(float)sh_audio->audio.dwRate/(float)sh_audio->audio.dwScale;
curr_audio_pos*=sh_audio->audio.dwSampleSize;
#endif
// find audio chunk pos:
for(i=0;i<chunk_max;i++){
- int id=((AVIINDEXENTRY *)demuxer->idx)[i].ckid;
+ int id=((AVIINDEXENTRY *)priv->idx)[i].ckid;
if(avi_stream_id(id)==d_audio->id){
- len=((AVIINDEXENTRY *)demuxer->idx)[i].dwChunkLength;
+ len=((AVIINDEXENTRY *)priv->idx)[i].dwChunkLength;
audio_chunk_pos=i; ++d_audio->pack_no;
if(d_audio->dpos<=curr_audio_pos && curr_audio_pos<(d_audio->dpos+len)){
//if(verbose)printf("break;\n");
@@ -453,14 +567,14 @@ void demux_seek_avi(demuxer_t *demuxer,float rel_seek_secs,int flags){
} else {
// VBR audio
- int chunks=(avi_video_pts)*(float)sh_audio->audio.dwRate/(float)sh_audio->audio.dwScale;
+ int chunks=(priv->avi_video_pts)*(float)sh_audio->audio.dwRate/(float)sh_audio->audio.dwScale;
audio_chunk_pos=0;
// find audio chunk pos:
- for(i=0;i<demuxer->idx_size && chunks>0;i++){
- int id=((AVIINDEXENTRY *)demuxer->idx)[i].ckid;
+ for(i=0;i<priv->idx_size && chunks>0;i++){
+ int id=((AVIINDEXENTRY *)priv->idx)[i].ckid;
if(avi_stream_id(id)==d_audio->id){
- len=((AVIINDEXENTRY *)demuxer->idx)[i].dwChunkLength;
+ len=((AVIINDEXENTRY *)priv->idx)[i].dwChunkLength;
if(i>chunk_max){
skip_audio_bytes+=len;
} else {
@@ -474,7 +588,7 @@ void demux_seek_avi(demuxer_t *demuxer,float rel_seek_secs,int flags){
//if(audio_chunk_pos>chunk_max) audio_chunk_pos=chunk_max;
// printf("VBR seek: %5.3f -> chunk_no %d -> chunk_idx %d + skip %d \n",
-// avi_video_pts, audio_chunk_pos, );
+// priv->avi_video_pts, audio_chunk_pos, );
}
@@ -493,25 +607,25 @@ void demux_seek_avi(demuxer_t *demuxer,float rel_seek_secs,int flags){
if(demuxer->type==DEMUXER_TYPE_AVI){
// interleaved stream:
if(audio_chunk_pos<video_chunk_pos){
- // calc skip_video_frames & adjust video pts counter:
+ // calc priv->skip_video_frames & adjust video pts counter:
for(i=audio_chunk_pos;i<video_chunk_pos;i++){
- int id=((AVIINDEXENTRY *)demuxer->idx)[i].ckid;
- if(avi_stream_id(id)==d_video->id) ++skip_video_frames;
+ int id=((AVIINDEXENTRY *)priv->idx)[i].ckid;
+ if(avi_stream_id(id)==d_video->id) ++priv->skip_video_frames;
}
// requires for correct audio pts calculation (demuxer):
- avi_video_pts-=skip_video_frames*(float)sh_video->video.dwScale/(float)sh_video->video.dwRate;
- demuxer->idx_pos_a=demuxer->idx_pos_v=demuxer->idx_pos=audio_chunk_pos;
+ priv->avi_video_pts-=priv->skip_video_frames*(float)sh_video->video.dwScale/(float)sh_video->video.dwRate;
+ priv->idx_pos_a=priv->idx_pos_v=priv->idx_pos=audio_chunk_pos;
}
} else {
// non-interleaved stream:
- demuxer->idx_pos_a=audio_chunk_pos;
- demuxer->idx_pos_v=video_chunk_pos;
- demuxer->idx_pos=(audio_chunk_pos<video_chunk_pos)?audio_chunk_pos:video_chunk_pos;
+ priv->idx_pos_a=audio_chunk_pos;
+ priv->idx_pos_v=video_chunk_pos;
+ priv->idx_pos=(audio_chunk_pos<video_chunk_pos)?audio_chunk_pos:video_chunk_pos;
}
if(verbose) printf("SEEK: idx=%d (a:%d v:%d) v.skip=%d a.skip=%d/%4.3f \n",
- demuxer->idx_pos,audio_chunk_pos,video_chunk_pos,
- skip_video_frames,skip_audio_bytes,skip_audio_secs);
+ priv->idx_pos,audio_chunk_pos,video_chunk_pos,
+ priv->skip_video_frames,skip_audio_bytes,skip_audio_secs);
if(skip_audio_bytes){
demux_read_data(d_audio,NULL,skip_audio_bytes);
diff --git a/demuxer.c b/demuxer.c
index 12f236cdaa..7e5e83e6f1 100644
--- a/demuxer.c
+++ b/demuxer.c
@@ -294,7 +294,6 @@ extern int num_elementary_packetsPES;
// commandline options, flags:
extern int seek_to_byte;
-extern int index_mode; // -1=untouched 0=don't use index 1=use (geneate) index
extern int force_ni;
extern int pts_from_bps;
@@ -391,8 +390,8 @@ if(file_format==DEMUXER_TYPE_MPEG_ES){ // little hack, see above!
printf("Detected MPEG-ES file format!\n");
}
}
-#ifdef MOV
//=============== Try to open as MOV file: =================
+#if 0
if(file_format==DEMUXER_TYPE_UNKNOWN || file_format==DEMUXER_TYPE_MOV){
stream_reset(stream);
demuxer=new_demuxer(stream,DEMUXER_TYPE_MOV,audio_id,video_id,dvdsub_id);
@@ -416,110 +415,19 @@ d_audio=demuxer->audio;
d_video=demuxer->video;
//d_dvdsub=demuxer->sub;
+demuxer->file_format=file_format;
+
switch(file_format){
case DEMUXER_TYPE_AVI: {
- //---- AVI header:
- read_avi_header(demuxer,(stream->type!=STREAMTYPE_STREAM)?index_mode:-2);
- stream_reset(demuxer->stream);
- stream_seek(demuxer->stream,demuxer->movi_start);
- demuxer->idx_pos=0;
- demuxer->idx_pos_a=0;
- demuxer->idx_pos_v=0;
- if(demuxer->idx_size>0){
- // decide index format:
- if(((AVIINDEXENTRY *)demuxer->idx)[0].dwChunkOffset<demuxer->movi_start)
- demuxer->idx_offset=demuxer->movi_start-4;
- else
- demuxer->idx_offset=0;
- if(verbose) printf("AVI index offset: %d\n",demuxer->idx_offset);
- }
-// demuxer->endpos=avi_header.movi_end;
-
- if(demuxer->idx_size>0){
- // check that file is non-interleaved:
- int i;
- int a_pos=-1;
- int v_pos=-1;
- for(i=0;i<demuxer->idx_size;i++){
- AVIINDEXENTRY* idx=&((AVIINDEXENTRY *)demuxer->idx)[i];
- demux_stream_t* ds=demux_avi_select_stream(demuxer,idx->ckid);
- int pos=idx->dwChunkOffset+demuxer->idx_offset;
- if(a_pos==-1 && ds==demuxer->audio){
- a_pos=pos;
- if(v_pos!=-1) break;
- }
- if(v_pos==-1 && ds==demuxer->video){
- v_pos=pos;
- if(a_pos!=-1) break;
- }
- }
- if(v_pos==-1){
- fprintf(stderr,"AVI_NI: missing video stream!? contact the author, it may be a bug :(\n");
- return NULL;
-// GUI_MSG( mplErrorAVINI )
-// exit(1);
- }
- if(a_pos==-1){
- printf("AVI_NI: No audio stream found -> nosound\n");
- sh_audio=NULL;
- } else {
- if(force_ni || abs(a_pos-v_pos)>0x100000){ // distance > 1MB
- printf("%s NON-INTERLEAVED AVI file-format!\n",force_ni?"Forced":"Detected");