Mercurial > mplayer.hg
annotate libmpdemux/aviwrite.c @ 5850:1b1943b3d987
input/lirc/slavemode doc by Albeu
author | arpi |
---|---|
date | Fri, 26 Apr 2002 20:49:18 +0000 |
parents | 8cd761968f35 |
children | 62ac2cac100d |
rev | line source |
---|---|
587
8511095c5283
stage#1 completed: c files no more included from mplayer.c
arpi_esp
parents:
1
diff
changeset
|
1 |
8511095c5283
stage#1 completed: c files no more included from mplayer.c
arpi_esp
parents:
1
diff
changeset
|
2 #include <stdio.h> |
8511095c5283
stage#1 completed: c files no more included from mplayer.c
arpi_esp
parents:
1
diff
changeset
|
3 #include <stdlib.h> |
2529 | 4 #include <string.h> |
5572
8cd761968f35
BSD-BT848 TV update patch by Charles Henrich <henrich@sigbus.com>
arpi
parents:
2652
diff
changeset
|
5 #include <sys/types.h> |
2529 | 6 |
2555
66837325b929
config.h cleanup, few things added to steram/demuxer headers
arpi
parents:
2529
diff
changeset
|
7 #include "config.h" |
66837325b929
config.h cleanup, few things added to steram/demuxer headers
arpi
parents:
2529
diff
changeset
|
8 |
2529 | 9 //#include "stream.h" |
10 //#include "demuxer.h" | |
11 //#include "stheader.h" | |
587
8511095c5283
stage#1 completed: c files no more included from mplayer.c
arpi_esp
parents:
1
diff
changeset
|
12 |
8511095c5283
stage#1 completed: c files no more included from mplayer.c
arpi_esp
parents:
1
diff
changeset
|
13 #include "wine/mmreg.h" |
8511095c5283
stage#1 completed: c files no more included from mplayer.c
arpi_esp
parents:
1
diff
changeset
|
14 #include "wine/avifmt.h" |
8511095c5283
stage#1 completed: c files no more included from mplayer.c
arpi_esp
parents:
1
diff
changeset
|
15 #include "wine/vfw.h" |
8511095c5283
stage#1 completed: c files no more included from mplayer.c
arpi_esp
parents:
1
diff
changeset
|
16 |
2529 | 17 #include "aviwrite.h" |
1 | 18 |
2529 | 19 aviwrite_stream_t* aviwrite_new_stream(aviwrite_t *muxer,int type){ |
20 aviwrite_stream_t* s; | |
21 if(muxer->avih.dwStreams>=AVIWRITE_MAX_STREAMS){ | |
22 printf("Too many streams! increase AVIWRITE_MAX_STREAMS !\n"); | |
23 return NULL; | |
24 } | |
25 s=malloc(sizeof(aviwrite_stream_t)); | |
26 memset(s,0,sizeof(aviwrite_stream_t)); | |
27 if(!s) return NULL; // no mem!? | |
28 muxer->streams[muxer->avih.dwStreams]=s; | |
29 s->type=type; | |
30 s->id=muxer->avih.dwStreams; | |
31 s->timer=0.0; | |
2652 | 32 s->size=0; |
2529 | 33 switch(type){ |
34 case AVIWRITE_TYPE_VIDEO: | |
35 s->ckid=mmioFOURCC(('0'+s->id/10),('0'+(s->id%10)),'d','c'); | |
36 s->h.fccType=streamtypeVIDEO; | |
37 if(!muxer->def_v) muxer->def_v=s; | |
38 break; | |
39 case AVIWRITE_TYPE_AUDIO: | |
40 s->ckid=mmioFOURCC(('0'+s->id/10),('0'+(s->id%10)),'w','b'); | |
41 s->h.fccType=streamtypeAUDIO; | |
42 break; | |
43 default: | |
44 printf("WarninG! unknown stream type: %d\n",type); | |
45 return NULL; | |
46 } | |
47 muxer->avih.dwStreams++; | |
48 return s; | |
49 } | |
1 | 50 |
2529 | 51 aviwrite_t* aviwrite_new_muxer(){ |
52 aviwrite_t* muxer=malloc(sizeof(aviwrite_t)); | |
53 memset(muxer,0,sizeof(aviwrite_t)); | |
54 return muxer; | |
55 } | |
56 | |
57 static void write_avi_chunk(FILE *f,unsigned int id,int len,void* data){ | |
1 | 58 fwrite(&id,4,1,f); |
59 fwrite(&len,4,1,f); | |
60 if(len>0){ | |
61 if(data){ | |
62 // DATA | |
63 fwrite(data,len,1,f); | |
64 if(len&1){ // padding | |
65 unsigned char zerobyte=0; | |
66 fwrite(&zerobyte,1,1,f); | |
67 } | |
68 } else { | |
69 // JUNK | |
70 char *avi_junk_data="[= MPlayer junk data! =]"; | |
71 if(len&1) ++len; // padding | |
72 while(len>0){ | |
73 int l=strlen(avi_junk_data); | |
74 if(l>len) l=len; | |
75 fwrite(avi_junk_data,l,1,f); | |
76 len-=l; | |
77 } | |
78 } | |
79 } | |
2529 | 80 } |
81 | |
82 void aviwrite_write_chunk(aviwrite_t *muxer,aviwrite_stream_t *s, FILE *f,int len,unsigned int flags){ | |
83 | |
84 // add to the index: | |
85 if(muxer->idx_pos>=muxer->idx_size){ | |
86 muxer->idx_size+=256; // 4kB | |
87 muxer->idx=realloc(muxer->idx,16*muxer->idx_size); | |
88 } | |
89 muxer->idx[muxer->idx_pos].ckid=s->ckid; | |
90 muxer->idx[muxer->idx_pos].dwFlags=flags; // keyframe? | |
91 muxer->idx[muxer->idx_pos].dwChunkOffset=ftell(f)-(muxer->movi_start-4); | |
92 muxer->idx[muxer->idx_pos].dwChunkLength=len; | |
93 ++muxer->idx_pos; | |
94 | |
95 // write out the chunk: | |
96 write_avi_chunk(f,s->ckid,len,s->buffer); | |
97 | |
98 // alter counters: | |
99 if(s->h.dwSampleSize){ | |
100 // CBR | |
101 s->h.dwLength+=len/s->h.dwSampleSize; | |
102 if(len%s->h.dwSampleSize) printf("Warning! len isn't divisable by samplesize!\n"); | |
103 } else { | |
104 // VBR | |
105 s->h.dwLength++; | |
106 } | |
107 s->timer=(double)s->h.dwLength*s->h.dwScale/s->h.dwRate; | |
2652 | 108 s->size+=len; |
2529 | 109 if(len>s->h.dwSuggestedBufferSize) s->h.dwSuggestedBufferSize=len; |
1 | 110 |
111 } | |
112 | |
2529 | 113 static void write_avi_list(FILE *f,unsigned int id,int len){ |
1 | 114 unsigned int list_id=FOURCC_LIST; |
115 len+=4; // list fix | |
116 fwrite(&list_id,4,1,f); | |
117 fwrite(&len,4,1,f); | |
118 fwrite(&id,4,1,f); | |
119 } | |
120 | |
2635
c1e24e01601b
fixed AVI header creation - now should be compatible with NaNdub
arpi
parents:
2555
diff
changeset
|
121 // muxer->streams[i]->wf->cbSize |
c1e24e01601b
fixed AVI header creation - now should be compatible with NaNdub
arpi
parents:
2555
diff
changeset
|
122 #define WFSIZE(wf) (sizeof(WAVEFORMATEX)+(((wf)->cbSize)?((wf)->cbSize-2):0)) |
c1e24e01601b
fixed AVI header creation - now should be compatible with NaNdub
arpi
parents:
2555
diff
changeset
|
123 |
2529 | 124 void aviwrite_write_header(aviwrite_t *muxer,FILE *f){ |
1 | 125 unsigned int riff[3]; |
2529 | 126 int i; |
127 unsigned int hdrsize; | |
1 | 128 // RIFF header: |
129 riff[0]=mmioFOURCC('R','I','F','F'); | |
2529 | 130 riff[1]=muxer->file_end; // filesize |
1 | 131 riff[2]=formtypeAVI; // 'AVI ' |
132 fwrite(&riff,12,1,f); | |
2529 | 133 |
134 // update AVI header: | |
135 if(muxer->def_v){ | |
136 muxer->avih.dwMicroSecPerFrame=1000000.0*muxer->def_v->h.dwScale/muxer->def_v->h.dwRate; | |
2635
c1e24e01601b
fixed AVI header creation - now should be compatible with NaNdub
arpi
parents:
2555
diff
changeset
|
137 // muxer->avih.dwMaxBytesPerSec=1000000; // dummy!!!!! FIXME |
c1e24e01601b
fixed AVI header creation - now should be compatible with NaNdub
arpi
parents:
2555
diff
changeset
|
138 // muxer->avih.dwPaddingGranularity=2; // ??? |
2529 | 139 muxer->avih.dwFlags|=AVIF_ISINTERLEAVED|AVIF_TRUSTCKTYPE; |
140 muxer->avih.dwTotalFrames=muxer->def_v->h.dwLength; | |
2635
c1e24e01601b
fixed AVI header creation - now should be compatible with NaNdub
arpi
parents:
2555
diff
changeset
|
141 // muxer->avih.dwSuggestedBufferSize=muxer->def_v->h.dwSuggestedBufferSize; |
2529 | 142 muxer->avih.dwWidth=muxer->def_v->bih->biWidth; |
143 muxer->avih.dwHeight=muxer->def_v->bih->biHeight; | |
144 } | |
145 | |
1 | 146 // AVI header: |
2529 | 147 hdrsize=sizeof(muxer->avih)+8; |
148 // calc total header size: | |
149 for(i=0;i<muxer->avih.dwStreams;i++){ | |
150 hdrsize+=12; // LIST | |
151 hdrsize+=sizeof(muxer->streams[i]->h)+8; // strh | |
152 switch(muxer->streams[i]->type){ | |
153 case AVIWRITE_TYPE_VIDEO: | |
154 hdrsize+=muxer->streams[i]->bih->biSize+8; // strf | |
155 break; | |
156 case AVIWRITE_TYPE_AUDIO: | |
2635
c1e24e01601b
fixed AVI header creation - now should be compatible with NaNdub
arpi
parents:
2555
diff
changeset
|
157 hdrsize+=WFSIZE(muxer->streams[i]->wf)+8; // strf |
2529 | 158 break; |
159 } | |
160 } | |
161 write_avi_list(f,listtypeAVIHEADER,hdrsize); | |
162 write_avi_chunk(f,ckidAVIMAINHDR,sizeof(muxer->avih),&muxer->avih); | |
163 | |
164 // stream headers: | |
165 for(i=0;i<muxer->avih.dwStreams;i++){ | |
166 hdrsize=sizeof(muxer->streams[i]->h)+8; // strh | |
167 switch(muxer->streams[i]->type){ | |
168 case AVIWRITE_TYPE_VIDEO: | |
169 hdrsize+=muxer->streams[i]->bih->biSize+8; // strf | |
170 break; | |
171 case AVIWRITE_TYPE_AUDIO: | |
2635
c1e24e01601b
fixed AVI header creation - now should be compatible with NaNdub
arpi
parents:
2555
diff
changeset
|
172 hdrsize+=WFSIZE(muxer->streams[i]->wf)+8; // strf |
2529 | 173 break; |
174 } | |
175 write_avi_list(f,listtypeSTREAMHEADER,hdrsize); | |
176 write_avi_chunk(f,ckidSTREAMHEADER,sizeof(muxer->streams[i]->h),&muxer->streams[i]->h); // strh | |
177 switch(muxer->streams[i]->type){ | |
178 case AVIWRITE_TYPE_VIDEO: | |
179 write_avi_chunk(f,ckidSTREAMFORMAT,muxer->streams[i]->bih->biSize,muxer->streams[i]->bih); | |
180 break; | |
181 case AVIWRITE_TYPE_AUDIO: | |
2635
c1e24e01601b
fixed AVI header creation - now should be compatible with NaNdub
arpi
parents:
2555
diff
changeset
|
182 write_avi_chunk(f,ckidSTREAMFORMAT,WFSIZE(muxer->streams[i]->wf),muxer->streams[i]->wf); |
2529 | 183 break; |
184 } | |
185 } | |
186 | |
187 // JUNK: | |
1 | 188 write_avi_chunk(f,ckidAVIPADDING,2048-(ftell(f)&2047)-8,NULL); |
189 // 'movi' header: | |
2529 | 190 write_avi_list(f,listtypeAVIMOVIE,muxer->movi_end-ftell(f)-12); |
191 muxer->movi_start=ftell(f); | |
1 | 192 } |
193 | |
2529 | 194 void aviwrite_write_index(aviwrite_t *muxer,FILE *f){ |
195 muxer->movi_end=ftell(f); | |
196 if(muxer->idx && muxer->idx_pos>0){ | |
197 // fixup index entries: | |
198 // int i; | |
199 // for(i=0;i<muxer->idx_pos;i++) muxer->idx[i].dwChunkOffset-=muxer->movi_start-4; | |
200 // write index chunk: | |
201 write_avi_chunk(f,ckidAVINEWINDEX,16*muxer->idx_pos,muxer->idx); | |
202 muxer->avih.dwFlags|=AVIF_HASINDEX; | |
203 } | |
204 muxer->file_end=ftell(f); | |
1 | 205 } |
206 |