Mercurial > mplayer.hg
annotate libmpdemux/muxer_avi.c @ 18066:2ee39341b7a6
fix segfault in the skin browser when sbSelectedSkin gets dereferenced before setting, when no skin is selected in the skin list upon opening the browser,
and "Cancel" or "OK" buttons get clicked.
Noticed when runnig freshly compiled gmplayer on a system where the skins were still under the old location.
based on a combined patch by Stanislav Maslovski <stanislav POIS maslovski AH gmail POIS com>
author | gpoirier |
---|---|
date | Sun, 09 Apr 2006 13:52:45 +0000 |
parents | 92ac78a93625 |
children | 4928dd61f136 |
rev | line source |
---|---|
587
8511095c5283
stage#1 completed: c files no more included from mplayer.c
arpi_esp
parents:
1
diff
changeset
|
1 #include <stdio.h> |
8511095c5283
stage#1 completed: c files no more included from mplayer.c
arpi_esp
parents:
1
diff
changeset
|
2 #include <stdlib.h> |
2529 | 3 #include <string.h> |
8585 | 4 #include <inttypes.h> |
8591 | 5 #include <unistd.h> |
12036 | 6 #include <limits.h> |
2529 | 7 |
2555
66837325b929
config.h cleanup, few things added to steram/demuxer headers
arpi
parents:
2529
diff
changeset
|
8 #include "config.h" |
17012 | 9 #include "version.h" |
2555
66837325b929
config.h cleanup, few things added to steram/demuxer headers
arpi
parents:
2529
diff
changeset
|
10 |
12036 | 11 #include "stream.h" |
12 #include "demuxer.h" | |
13 #include "stheader.h" | |
587
8511095c5283
stage#1 completed: c files no more included from mplayer.c
arpi_esp
parents:
1
diff
changeset
|
14 |
6918 | 15 #include "bswap.h" |
587
8511095c5283
stage#1 completed: c files no more included from mplayer.c
arpi_esp
parents:
1
diff
changeset
|
16 |
8585 | 17 #include "muxer.h" |
6918 | 18 #include "aviheader.h" |
12341
0db4a3a5b01d
removed loader/ dependancy, imported some files from g2, also used patches from Dominik Mierzejewski
alex
parents:
12235
diff
changeset
|
19 #include "ms_hdr.h" |
12036 | 20 #include "mp_msg.h" |
17065
cf6bfdf41143
Clean up some muxer messages, patch by Corey Hickey bugfood-ml AT -fatooh/org- , small fixes by me
reynaldo
parents:
17023
diff
changeset
|
21 #include "help_mp.h" |
1 | 22 |
7145
3854945aefbb
new mencoder option -info, to store copyright, title, encoder version etc in AVI
arpi
parents:
7144
diff
changeset
|
23 extern char *info_name; |
3854945aefbb
new mencoder option -info, to store copyright, title, encoder version etc in AVI
arpi
parents:
7144
diff
changeset
|
24 extern char *info_artist; |
3854945aefbb
new mencoder option -info, to store copyright, title, encoder version etc in AVI
arpi
parents:
7144
diff
changeset
|
25 extern char *info_genre; |
3854945aefbb
new mencoder option -info, to store copyright, title, encoder version etc in AVI
arpi
parents:
7144
diff
changeset
|
26 extern char *info_subject; |
3854945aefbb
new mencoder option -info, to store copyright, title, encoder version etc in AVI
arpi
parents:
7144
diff
changeset
|
27 extern char *info_copyright; |
3854945aefbb
new mencoder option -info, to store copyright, title, encoder version etc in AVI
arpi
parents:
7144
diff
changeset
|
28 extern char *info_sourceform; |
3854945aefbb
new mencoder option -info, to store copyright, title, encoder version etc in AVI
arpi
parents:
7144
diff
changeset
|
29 extern char *info_comment; |
3854945aefbb
new mencoder option -info, to store copyright, title, encoder version etc in AVI
arpi
parents:
7144
diff
changeset
|
30 |
12036 | 31 /* #define ODML_CHUNKLEN 0x02000000 */ /* for testing purposes */ |
32 #define ODML_CHUNKLEN 0x40000000 | |
33 #define ODML_NOTKEYFRAME 0x80000000U | |
34 #define MOVIALIGN 0x00001000 | |
35 | |
12061 | 36 float avi_aspect_override = -1.0; |
12363 | 37 int write_odml = 1; |
12051 | 38 |
12036 | 39 struct avi_odmlidx_entry { |
40 uint64_t ofs; | |
41 uint32_t len; | |
42 uint32_t flags; | |
43 }; | |
44 | |
45 struct avi_odmlsuperidx_entry { | |
46 uint64_t ofs; | |
47 uint32_t len; | |
48 uint32_t duration; | |
49 }; | |
50 | |
51 struct avi_stream_info { | |
52 int idxsize; | |
53 int idxpos; | |
54 int superidxpos; | |
55 int superidxsize; | |
12235
ca5dc9c2cb51
Get rid of the 'RIFF chunks have to be aligned on ODML_CHUNKLEN'
ranma
parents:
12062
diff
changeset
|
56 int riffofspos; |
ca5dc9c2cb51
Get rid of the 'RIFF chunks have to be aligned on ODML_CHUNKLEN'
ranma
parents:
12062
diff
changeset
|
57 int riffofssize; |
ca5dc9c2cb51
Get rid of the 'RIFF chunks have to be aligned on ODML_CHUNKLEN'
ranma
parents:
12062
diff
changeset
|
58 off_t *riffofs; |
12036 | 59 struct avi_odmlidx_entry *idx; |
60 struct avi_odmlsuperidx_entry *superidx; | |
61 }; | |
62 | |
12061 | 63 static unsigned int avi_aspect(muxer_stream_t *vstream) |
64 { | |
65 int x,y; | |
66 float aspect = vstream->aspect; | |
67 | |
68 if (avi_aspect_override > 0.0) { | |
69 aspect = avi_aspect_override; | |
70 } | |
71 | |
72 if (aspect <= 0.0) return 0; | |
73 | |
74 if (aspect > 15.99/9.0 && aspect < 16.01/9.0) { | |
75 return MAKE_AVI_ASPECT(16, 9); | |
76 } | |
77 if (aspect > 3.99/3.0 && aspect < 4.01/3.0) { | |
78 return MAKE_AVI_ASPECT(4, 3); | |
79 } | |
80 | |
81 if (aspect >= 1.0) { | |
82 x = 16384; | |
83 y = (float)x / aspect; | |
84 } else { | |
85 y = 16384; | |
86 x = (float)y * aspect; | |
87 } | |
88 | |
89 return MAKE_AVI_ASPECT(x, y); | |
90 } | |
91 | |
8585 | 92 static muxer_stream_t* avifile_new_stream(muxer_t *muxer,int type){ |
12036 | 93 struct avi_stream_info *si; |
8585 | 94 muxer_stream_t* s; |
9007
12fc55eb3373
Cleanup of the muxer API, func parameters muxer & muxer_f eliminated.
arpi
parents:
8591
diff
changeset
|
95 if (!muxer) return NULL; |
8585 | 96 if(muxer->avih.dwStreams>=MUXER_MAX_STREAMS){ |
12036 | 97 mp_msg(MSGT_MUXER, MSGL_ERR, "Too many streams! increase MUXER_MAX_STREAMS !\n"); |
2529 | 98 return NULL; |
99 } | |
8585 | 100 s=malloc(sizeof(muxer_stream_t)); |
101 memset(s,0,sizeof(muxer_stream_t)); | |
2529 | 102 if(!s) return NULL; // no mem!? |
103 muxer->streams[muxer->avih.dwStreams]=s; | |
104 s->type=type; | |
105 s->id=muxer->avih.dwStreams; | |
106 s->timer=0.0; | |
2652 | 107 s->size=0; |
9007
12fc55eb3373
Cleanup of the muxer API, func parameters muxer & muxer_f eliminated.
arpi
parents:
8591
diff
changeset
|
108 s->muxer=muxer; |
12036 | 109 s->priv=si=malloc(sizeof(struct avi_stream_info)); |
110 memset(si,0,sizeof(struct avi_stream_info)); | |
111 si->idxsize=256; | |
112 si->idx=malloc(sizeof(struct avi_odmlidx_entry)*si->idxsize); | |
12235
ca5dc9c2cb51
Get rid of the 'RIFF chunks have to be aligned on ODML_CHUNKLEN'
ranma
parents:
12062
diff
changeset
|
113 si->riffofssize=16; |
ca5dc9c2cb51
Get rid of the 'RIFF chunks have to be aligned on ODML_CHUNKLEN'
ranma
parents:
12062
diff
changeset
|
114 si->riffofs=malloc(sizeof(off_t)*(si->riffofssize+1)); |
ca5dc9c2cb51
Get rid of the 'RIFF chunks have to be aligned on ODML_CHUNKLEN'
ranma
parents:
12062
diff
changeset
|
115 memset(si->riffofs, 0, sizeof(off_t)*si->riffofssize); |
12036 | 116 |
2529 | 117 switch(type){ |
8585 | 118 case MUXER_TYPE_VIDEO: |
2529 | 119 s->ckid=mmioFOURCC(('0'+s->id/10),('0'+(s->id%10)),'d','c'); |
120 s->h.fccType=streamtypeVIDEO; | |
121 if(!muxer->def_v) muxer->def_v=s; | |
122 break; | |
8585 | 123 case MUXER_TYPE_AUDIO: |
2529 | 124 s->ckid=mmioFOURCC(('0'+s->id/10),('0'+(s->id%10)),'w','b'); |
125 s->h.fccType=streamtypeAUDIO; | |
126 break; | |
127 default: | |
12036 | 128 mp_msg(MSGT_MUXER, MSGL_WARN, "Warning! unknown stream type: %d\n",type); |
2529 | 129 return NULL; |
130 } | |
131 muxer->avih.dwStreams++; | |
132 return s; | |
133 } | |
1 | 134 |
2529 | 135 static void write_avi_chunk(FILE *f,unsigned int id,int len,void* data){ |
6918 | 136 int le_len = le2me_32(len); |
137 int le_id = le2me_32(id); | |
138 fwrite(&le_id,4,1,f); | |
139 fwrite(&le_len,4,1,f); | |
140 | |
1 | 141 if(len>0){ |
142 if(data){ | |
143 // DATA | |
144 fwrite(data,len,1,f); | |
145 if(len&1){ // padding | |
146 unsigned char zerobyte=0; | |
147 fwrite(&zerobyte,1,1,f); | |
148 } | |
149 } else { | |
150 // JUNK | |
151 char *avi_junk_data="[= MPlayer junk data! =]"; | |
152 if(len&1) ++len; // padding | |
153 while(len>0){ | |
154 int l=strlen(avi_junk_data); | |
155 if(l>len) l=len; | |
156 fwrite(avi_junk_data,l,1,f); | |
157 len-=l; | |
158 } | |
159 } | |
160 } | |
2529 | 161 } |
162 | |
12036 | 163 static void write_avi_list(FILE *f,unsigned int id,int len); |
12363 | 164 static void avifile_write_standard_index(muxer_t *muxer); |
12036 | 165 |
166 static void avifile_odml_new_riff(muxer_t *muxer) | |
167 { | |
12235
ca5dc9c2cb51
Get rid of the 'RIFF chunks have to be aligned on ODML_CHUNKLEN'
ranma
parents:
12062
diff
changeset
|
168 struct avi_stream_info *vsi = muxer->def_v->priv; |
12036 | 169 FILE *f = muxer->file; |
170 uint32_t riff[3]; | |
171 | |
12497
da17b2c262de
no kabbe-bytes or men in black or any of that nonsense here...
rfelker
parents:
12363
diff
changeset
|
172 mp_msg(MSGT_MUXER, MSGL_INFO, "ODML: Starting new RIFF chunk at %dMB.\n", (int)(muxer->file_end/1024/1024)); |
12235
ca5dc9c2cb51
Get rid of the 'RIFF chunks have to be aligned on ODML_CHUNKLEN'
ranma
parents:
12062
diff
changeset
|
173 |
ca5dc9c2cb51
Get rid of the 'RIFF chunks have to be aligned on ODML_CHUNKLEN'
ranma
parents:
12062
diff
changeset
|
174 vsi->riffofspos++; |
ca5dc9c2cb51
Get rid of the 'RIFF chunks have to be aligned on ODML_CHUNKLEN'
ranma
parents:
12062
diff
changeset
|
175 if (vsi->riffofspos>=vsi->riffofssize) { |
ca5dc9c2cb51
Get rid of the 'RIFF chunks have to be aligned on ODML_CHUNKLEN'
ranma
parents:
12062
diff
changeset
|
176 vsi->riffofssize+=16; |
ca5dc9c2cb51
Get rid of the 'RIFF chunks have to be aligned on ODML_CHUNKLEN'
ranma
parents:
12062
diff
changeset
|
177 vsi->riffofs=realloc(vsi->riffofs,sizeof(off_t)*(vsi->riffofssize+1)); |
ca5dc9c2cb51
Get rid of the 'RIFF chunks have to be aligned on ODML_CHUNKLEN'
ranma
parents:
12062
diff
changeset
|
178 } |
ca5dc9c2cb51
Get rid of the 'RIFF chunks have to be aligned on ODML_CHUNKLEN'
ranma
parents:
12062
diff
changeset
|
179 vsi->riffofs[vsi->riffofspos] = ftello(f); |
12036 | 180 |
181 /* RIFF/AVIX chunk */ | |
182 riff[0]=le2me_32(mmioFOURCC('R','I','F','F')); | |
183 riff[1]=0; | |
184 riff[2]=le2me_32(mmioFOURCC('A','V','I','X')); | |
185 fwrite(riff,12,1,f); | |
186 | |
187 write_avi_list(f,listtypeAVIMOVIE,0); | |
12235
ca5dc9c2cb51
Get rid of the 'RIFF chunks have to be aligned on ODML_CHUNKLEN'
ranma
parents:
12062
diff
changeset
|
188 |
ca5dc9c2cb51
Get rid of the 'RIFF chunks have to be aligned on ODML_CHUNKLEN'
ranma
parents:
12062
diff
changeset
|
189 muxer->file_end = ftello(f); |
12036 | 190 } |
191 | |
13250 | 192 static void avifile_write_header(muxer_t *muxer); |
193 | |
17487
fa17424b4c7b
change muxer_write_chunk() so that pts/dts _could_ be passed from encoder to muxer
michael
parents:
17366
diff
changeset
|
194 static void avifile_write_chunk(muxer_stream_t *s,size_t len,unsigned int flags, double dts, double pts){ |
12235
ca5dc9c2cb51
Get rid of the 'RIFF chunks have to be aligned on ODML_CHUNKLEN'
ranma
parents:
12062
diff
changeset
|
195 off_t rifflen; |
9007
12fc55eb3373
Cleanup of the muxer API, func parameters muxer & muxer_f eliminated.
arpi
parents:
8591
diff
changeset
|
196 muxer_t *muxer=s->muxer; |
12235
ca5dc9c2cb51
Get rid of the 'RIFF chunks have to be aligned on ODML_CHUNKLEN'
ranma
parents:
12062
diff
changeset
|
197 struct avi_stream_info *si = s->priv; |
ca5dc9c2cb51
Get rid of the 'RIFF chunks have to be aligned on ODML_CHUNKLEN'
ranma
parents:
12062
diff
changeset
|
198 struct avi_stream_info *vsi = muxer->def_v->priv; |
ca5dc9c2cb51
Get rid of the 'RIFF chunks have to be aligned on ODML_CHUNKLEN'
ranma
parents:
12062
diff
changeset
|
199 int paddedlen = len + (len&1); |
2529 | 200 |
13249
a6642a4330fa
ensure that avi files have a valid header as soon as possible.
rfelker
parents:
12497
diff
changeset
|
201 if (s->type == MUXER_TYPE_VIDEO && !s->h.dwSuggestedBufferSize) { |
a6642a4330fa
ensure that avi files have a valid header as soon as possible.
rfelker
parents:
12497
diff
changeset
|
202 off_t pos=ftell(muxer->file); |
a6642a4330fa
ensure that avi files have a valid header as soon as possible.
rfelker
parents:
12497
diff
changeset
|
203 fseek(muxer->file, 0, SEEK_SET); |
a6642a4330fa
ensure that avi files have a valid header as soon as possible.
rfelker
parents:
12497
diff
changeset
|
204 avifile_write_header(muxer); |
a6642a4330fa
ensure that avi files have a valid header as soon as possible.
rfelker
parents:
12497
diff
changeset
|
205 fseek(muxer->file, pos, SEEK_SET); |
a6642a4330fa
ensure that avi files have a valid header as soon as possible.
rfelker
parents:
12497
diff
changeset
|
206 } |
a6642a4330fa
ensure that avi files have a valid header as soon as possible.
rfelker
parents:
12497
diff
changeset
|
207 |
12235
ca5dc9c2cb51
Get rid of the 'RIFF chunks have to be aligned on ODML_CHUNKLEN'
ranma
parents:
12062
diff
changeset
|
208 rifflen = muxer->file_end - vsi->riffofs[vsi->riffofspos] - 8; |
ca5dc9c2cb51
Get rid of the 'RIFF chunks have to be aligned on ODML_CHUNKLEN'
ranma
parents:
12062
diff
changeset
|
209 if (vsi->riffofspos == 0) { |
ca5dc9c2cb51
Get rid of the 'RIFF chunks have to be aligned on ODML_CHUNKLEN'
ranma
parents:
12062
diff
changeset
|
210 rifflen += 8+muxer->idx_pos*sizeof(AVIINDEXENTRY); |
ca5dc9c2cb51
Get rid of the 'RIFF chunks have to be aligned on ODML_CHUNKLEN'
ranma
parents:
12062
diff
changeset
|
211 } |
12363 | 212 if (rifflen + paddedlen > ODML_CHUNKLEN && write_odml == 1) { |
12235
ca5dc9c2cb51
Get rid of the 'RIFF chunks have to be aligned on ODML_CHUNKLEN'
ranma
parents:
12062
diff
changeset
|
213 if (vsi->riffofspos == 0) { |
12363 | 214 avifile_write_standard_index(muxer); |
12235
ca5dc9c2cb51
Get rid of the 'RIFF chunks have to be aligned on ODML_CHUNKLEN'
ranma
parents:
12062
diff
changeset
|
215 } |
ca5dc9c2cb51
Get rid of the 'RIFF chunks have to be aligned on ODML_CHUNKLEN'
ranma
parents:
12062
diff
changeset
|
216 avifile_odml_new_riff(muxer); |
ca5dc9c2cb51
Get rid of the 'RIFF chunks have to be aligned on ODML_CHUNKLEN'
ranma
parents:
12062
diff
changeset
|
217 } |
ca5dc9c2cb51
Get rid of the 'RIFF chunks have to be aligned on ODML_CHUNKLEN'
ranma
parents:
12062
diff
changeset
|
218 |
ca5dc9c2cb51
Get rid of the 'RIFF chunks have to be aligned on ODML_CHUNKLEN'
ranma
parents:
12062
diff
changeset
|
219 if (vsi->riffofspos == 0) { |
12036 | 220 // add to the traditional index: |
221 if(muxer->idx_pos>=muxer->idx_size){ | |
222 muxer->idx_size+=256; // 4kB | |
223 muxer->idx=realloc(muxer->idx,16*muxer->idx_size); | |
224 } | |
225 muxer->idx[muxer->idx_pos].ckid=s->ckid; | |
226 muxer->idx[muxer->idx_pos].dwFlags=flags; // keyframe? | |
12235
ca5dc9c2cb51
Get rid of the 'RIFF chunks have to be aligned on ODML_CHUNKLEN'
ranma
parents:
12062
diff
changeset
|
227 muxer->idx[muxer->idx_pos].dwChunkOffset=muxer->file_end-(muxer->movi_start-4); |
12036 | 228 muxer->idx[muxer->idx_pos].dwChunkLength=len; |
229 ++muxer->idx_pos; | |
230 } | |
231 | |
232 // add to odml index | |
233 if(si->idxpos>=si->idxsize){ | |
234 si->idxsize+=256; | |
235 si->idx=realloc(si->idx,sizeof(*si->idx)*si->idxsize); | |
2529 | 236 } |
12036 | 237 si->idx[si->idxpos].flags=(flags&AVIIF_KEYFRAME)?0:ODML_NOTKEYFRAME; |
12235
ca5dc9c2cb51
Get rid of the 'RIFF chunks have to be aligned on ODML_CHUNKLEN'
ranma
parents:
12062
diff
changeset
|
238 si->idx[si->idxpos].ofs=muxer->file_end; |
12036 | 239 si->idx[si->idxpos].len=len; |
240 ++si->idxpos; | |
241 | |
2529 | 242 // write out the chunk: |
9007
12fc55eb3373
Cleanup of the muxer API, func parameters muxer & muxer_f eliminated.
arpi
parents:
8591
diff
changeset
|
243 write_avi_chunk(muxer->file,s->ckid,len,s->buffer); /* unsigned char */ |
6918 | 244 |
12036 | 245 if (len > s->h.dwSuggestedBufferSize){ |
246 s->h.dwSuggestedBufferSize = len; | |
247 } | |
8585 | 248 if((unsigned int)len>s->h.dwSuggestedBufferSize) s->h.dwSuggestedBufferSize=len; |
1 | 249 |
12235
ca5dc9c2cb51
Get rid of the 'RIFF chunks have to be aligned on ODML_CHUNKLEN'
ranma
parents:
12062
diff
changeset
|
250 muxer->file_end += 8 + paddedlen; |
1 | 251 } |
252 | |
2529 | 253 static void write_avi_list(FILE *f,unsigned int id,int len){ |
1 | 254 unsigned int list_id=FOURCC_LIST; |
6918 | 255 int le_len; |
256 int le_id; | |
1 | 257 len+=4; // list fix |
6918 | 258 list_id = le2me_32(list_id); |
259 le_len = le2me_32(len); | |
260 le_id = le2me_32(id); | |
1 | 261 fwrite(&list_id,4,1,f); |
6918 | 262 fwrite(&le_len,4,1,f); |
263 fwrite(&le_id,4,1,f); | |
1 | 264 } |
265 | |
11374 | 266 #define WFSIZE(wf) (sizeof(WAVEFORMATEX)+(wf)->cbSize) |
2635
c1e24e01601b
fixed AVI header creation - now should be compatible with NaNdub
arpi
parents:
2555
diff
changeset
|
267 |
9007
12fc55eb3373
Cleanup of the muxer API, func parameters muxer & muxer_f eliminated.
arpi
parents:
8591
diff
changeset
|
268 static void avifile_write_header(muxer_t *muxer){ |
8585 | 269 uint32_t riff[3]; |
12036 | 270 unsigned int dmlh[1]; |
8585 | 271 unsigned int i; |
2529 | 272 unsigned int hdrsize; |
8585 | 273 muxer_info_t info[16]; |
12036 | 274 FILE *f = muxer->file; |
275 VideoPropHeader vprp; | |
12061 | 276 uint32_t aspect = avi_aspect(muxer->def_v); |
12036 | 277 off_t pos; |
12235
ca5dc9c2cb51
Get rid of the 'RIFF chunks have to be aligned on ODML_CHUNKLEN'
ranma
parents:
12062
diff
changeset
|
278 struct avi_stream_info *vsi = muxer->def_v->priv; |
ca5dc9c2cb51
Get rid of the 'RIFF chunks have to be aligned on ODML_CHUNKLEN'
ranma
parents:
12062
diff
changeset
|
279 int isodml = vsi->riffofspos > 0; |
12036 | 280 |
17065
cf6bfdf41143
Clean up some muxer messages, patch by Corey Hickey bugfood-ml AT -fatooh/org- , small fixes by me
reynaldo
parents:
17023
diff
changeset
|
281 mp_msg(MSGT_MUXER, MSGL_INFO, MSGTR_WritingHeader); |
12061 | 282 if (aspect == 0) { |
283 mp_msg(MSGT_MUXER, MSGL_INFO, "ODML: Aspect information not (yet?) available or unspecified, not writing vprp header.\n"); | |
284 } else { | |
285 mp_msg(MSGT_MUXER, MSGL_INFO, "ODML: vprp aspect is %d:%d.\n", aspect >> 16, aspect & 0xffff); | |
286 } | |
287 | |
17648 | 288 /* deal with stream delays */ |
289 for (i = 0; muxer->streams[i] && i < MUXER_MAX_STREAMS; ++i) { | |
290 muxer_stream_t *s = muxer->streams[i]; | |
291 if (s->type == MUXER_TYPE_AUDIO && muxer->audio_delay_fix > 0.0) { | |
292 s->h.dwStart = muxer->audio_delay_fix * s->h.dwRate/s->h.dwScale; | |
293 mp_msg(MSGT_MUXER, MSGL_INFO, MSGTR_SettingAudioDelay, (float)s->h.dwStart * s->h.dwScale/s->h.dwRate); | |
294 } | |
295 if (s->type == MUXER_TYPE_VIDEO && muxer->audio_delay_fix < 0.0) { | |
296 s->h.dwStart = -muxer->audio_delay_fix * s->h.dwRate/s->h.dwScale; | |
297 mp_msg(MSGT_MUXER, MSGL_INFO, MSGTR_SettingVideoDelay, (float)s->h.dwStart * s->h.dwScale/s->h.dwRate); | |
298 } | |
299 } | |
300 | |
12036 | 301 if (isodml) { |
302 unsigned int rifflen, movilen; | |
12235
ca5dc9c2cb51
Get rid of the 'RIFF chunks have to be aligned on ODML_CHUNKLEN'
ranma
parents:
12062
diff
changeset
|
303 int i; |
ca5dc9c2cb51
Get rid of the 'RIFF chunks have to be aligned on ODML_CHUNKLEN'
ranma
parents:
12062
diff
changeset
|
304 |
ca5dc9c2cb51
Get rid of the 'RIFF chunks have to be aligned on ODML_CHUNKLEN'
ranma
parents:
12062
diff
changeset
|
305 vsi->riffofs[vsi->riffofspos+1] = muxer->file_end; |
12036 | 306 |
12235
ca5dc9c2cb51
Get rid of the 'RIFF chunks have to be aligned on ODML_CHUNKLEN'
ranma
parents:
12062
diff
changeset
|
307 /* fixup RIFF lengths */ |
ca5dc9c2cb51
Get rid of the 'RIFF chunks have to be aligned on ODML_CHUNKLEN'
ranma
parents:
12062
diff
changeset
|
308 for (i=0; i<=vsi->riffofspos; i++) { |
ca5dc9c2cb51
Get rid of the 'RIFF chunks have to be aligned on ODML_CHUNKLEN'
ranma
parents:
12062
diff
changeset
|
309 rifflen = vsi->riffofs[i+1] - vsi->riffofs[i] - 8; |
ca5dc9c2cb51
Get rid of the 'RIFF chunks have to be aligned on ODML_CHUNKLEN'
ranma
parents:
12062
diff
changeset
|
310 movilen = le2me_32(rifflen - 12); |
ca5dc9c2cb51
Get rid of the 'RIFF chunks have to be aligned on ODML_CHUNKLEN'
ranma
parents:
12062
diff
changeset
|
311 rifflen = le2me_32(rifflen); |
ca5dc9c2cb51
Get rid of the 'RIFF chunks have to be aligned on ODML_CHUNKLEN'
ranma
parents:
12062
diff
changeset
|
312 fseeko(f, vsi->riffofs[i]+4, SEEK_SET); |
ca5dc9c2cb51
Get rid of the 'RIFF chunks have to be aligned on ODML_CHUNKLEN'
ranma
parents:
12062
diff
changeset
|
313 fwrite(&rifflen,4,1,f); |
ca5dc9c2cb51
Get rid of the 'RIFF chunks have to be aligned on ODML_CHUNKLEN'
ranma
parents:
12062
diff
changeset
|
314 |
ca5dc9c2cb51
Get rid of the 'RIFF chunks have to be aligned on ODML_CHUNKLEN'
ranma
parents:
12062
diff
changeset
|
315 /* fixup movi length */ |
ca5dc9c2cb51
Get rid of the 'RIFF chunks have to be aligned on ODML_CHUNKLEN'
ranma
parents:
12062
diff
changeset
|
316 if (i > 0) { |
ca5dc9c2cb51
Get rid of the 'RIFF chunks have to be aligned on ODML_CHUNKLEN'
ranma
parents:
12062
diff
changeset
|
317 fseeko(f, vsi->riffofs[i]+16, SEEK_SET); |
ca5dc9c2cb51
Get rid of the 'RIFF chunks have to be aligned on ODML_CHUNKLEN'
ranma
parents:
12062
diff
changeset
|
318 fwrite(&movilen,4,1,f); |
ca5dc9c2cb51
Get rid of the 'RIFF chunks have to be aligned on ODML_CHUNKLEN'
ranma
parents:
12062
diff
changeset
|
319 } |
12036 | 320 } |
7145
3854945aefbb
new mencoder option -info, to store copyright, title, encoder version etc in AVI
arpi
parents:
7144
diff
changeset
|
321 |
12235
ca5dc9c2cb51
Get rid of the 'RIFF chunks have to be aligned on ODML_CHUNKLEN'
ranma
parents:
12062
diff
changeset
|
322 fseeko(f, 12, SEEK_SET); |
12036 | 323 } else { |
324 // RIFF header: | |
325 riff[0]=mmioFOURCC('R','I','F','F'); | |
326 riff[1]=muxer->file_end-2*sizeof(unsigned int); // filesize | |
327 riff[2]=formtypeAVI; // 'AVI ' | |
328 riff[0]=le2me_32(riff[0]); | |
329 riff[1]=le2me_32(riff[1]); | |
330 riff[2]=le2me_32(riff[2]); | |
331 fwrite(&riff,12,1,f); | |
332 } | |
333 | |
2529 | 334 // update AVI header: |
335 if(muxer->def_v){ | |
12036 | 336 int i; |
2529 | 337 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
|
338 // muxer->avih.dwMaxBytesPerSec=1000000; // dummy!!!!! FIXME |
c1e24e01601b
fixed AVI header creation - now should be compatible with NaNdub
arpi
parents:
2555
diff
changeset
|
339 // muxer->avih.dwPaddingGranularity=2; // ??? |
2529 | 340 muxer->avih.dwFlags|=AVIF_ISINTERLEAVED|AVIF_TRUSTCKTYPE; |
12036 | 341 muxer->avih.dwTotalFrames=0; |
342 for (i=0; i<muxer->idx_pos; i++) { | |
343 if (muxer->idx[i].ckid == muxer->def_v->ckid) | |
344 muxer->avih.dwTotalFrames++; | |
345 } | |
2635
c1e24e01601b
fixed AVI header creation - now should be compatible with NaNdub
arpi
parents:
2555
diff
changeset
|
346 // muxer->avih.dwSuggestedBufferSize=muxer->def_v->h.dwSuggestedBufferSize; |
2529 | 347 muxer->avih.dwWidth=muxer->def_v->bih->biWidth; |
348 muxer->avih.dwHeight=muxer->def_v->bih->biHeight; | |
349 } | |
350 | |
1 | 351 // AVI header: |
2529 | 352 hdrsize=sizeof(muxer->avih)+8; |
12036 | 353 if (isodml) hdrsize+=sizeof(dmlh)+20; // dmlh |
2529 | 354 // calc total header size: |
355 for(i=0;i<muxer->avih.dwStreams;i++){ | |
12036 | 356 muxer_stream_t *s = muxer->streams[i]; |
357 struct avi_stream_info *si = s->priv; | |
358 | |
2529 | 359 hdrsize+=12; // LIST |
360 hdrsize+=sizeof(muxer->streams[i]->h)+8; // strh | |
361 switch(muxer->streams[i]->type){ | |
8585 | 362 case MUXER_TYPE_VIDEO: |
2529 | 363 hdrsize+=muxer->streams[i]->bih->biSize+8; // strf |
12061 | 364 if (aspect != 0) { |
12051 | 365 hdrsize+=8+4*(9+8*1); // vprp |
366 } | |
2529 | 367 break; |
8585 | 368 case MUXER_TYPE_AUDIO: |
2635
c1e24e01601b
fixed AVI header creation - now should be compatible with NaNdub
arpi
parents:
2555
diff
changeset
|
369 hdrsize+=WFSIZE(muxer->streams[i]->wf)+8; // strf |
2529 | 370 break; |
371 } | |
12036 | 372 if (isodml && si && si->superidx && si->superidxsize) { |
373 hdrsize += 32 + 16*si->superidxsize; //indx | |
374 } | |
2529 | 375 } |
376 write_avi_list(f,listtypeAVIHEADER,hdrsize); | |
6918 | 377 |
378 le2me_MainAVIHeader(&muxer->avih); | |
379 write_avi_chunk(f,ckidAVIMAINHDR,sizeof(muxer->avih),&muxer->avih); /* MainAVIHeader */ | |
380 le2me_MainAVIHeader(&muxer->avih); | |
2529 | 381 |
382 // stream headers: | |
383 for(i=0;i<muxer->avih.dwStreams;i++){ | |
12036 | 384 muxer_stream_t *s = muxer->streams[i]; |
385 struct avi_stream_info *si = s->priv; | |
386 unsigned int idxhdr[8]; | |
387 int j,n; | |
388 | |
389 hdrsize=sizeof(s->h)+8; // strh | |
390 if (si && si->superidx && si->superidxsize) { | |
391 hdrsize += 32 + 16*si->superidxsize; //indx | |
392 } | |
393 switch(s->type){ | |
8585 | 394 case MUXER_TYPE_VIDEO: |
12036 | 395 hdrsize+=s->bih->biSize+8; // strf |
396 s->h.fccHandler = s->bih->biCompression; | |
397 s->h.rcFrame.right = s->bih->biWidth; | |
398 s->h.rcFrame.bottom = s->bih->biHeight; | |
12061 | 399 if (aspect != 0) { |
12051 | 400 // fill out vprp info |
401 memset(&vprp, 0, sizeof(vprp)); | |
402 vprp.dwVerticalRefreshRate = (s->h.dwRate+s->h.dwScale-1)/s->h.dwScale; | |
403 vprp.dwHTotalInT = muxer->avih.dwWidth; | |
404 vprp.dwVTotalInLines = muxer->avih.dwHeight; | |
12061 | 405 vprp.dwFrameAspectRatio = aspect; |
12051 | 406 vprp.dwFrameWidthInPixels = muxer->avih.dwWidth; |
407 vprp.dwFrameHeightInLines = muxer->avih.dwHeight; | |
408 vprp.nbFieldPerFrame = 1; | |
409 vprp.FieldInfo[0].CompressedBMHeight = muxer->avih.dwHeight; | |
410 vprp.FieldInfo[0].CompressedBMWidth = muxer->avih.dwWidth; | |
411 vprp.FieldInfo[0].ValidBMHeight = muxer->avih.dwHeight; | |
412 vprp.FieldInfo[0].ValidBMWidth = muxer->avih.dwWidth; | |
413 hdrsize+=8+4*(9+8*1); // vprp | |
414 } | |
2529 | 415 break; |
8585 | 416 case MUXER_TYPE_AUDIO: |
12036 | 417 hdrsize+=WFSIZE(s->wf)+8; // strf |
418 s->h.fccHandler = s->wf->wFormatTag; | |
2529 | 419 break; |
420 } | |
12036 | 421 |
2529 | 422 write_avi_list(f,listtypeSTREAMHEADER,hdrsize); |
12036 | 423 le2me_AVIStreamHeader(&s->h); |
424 write_avi_chunk(f,ckidSTREAMHEADER,sizeof(s->h),&s->h); /* AVISTreamHeader */ // strh | |
425 le2me_AVIStreamHeader(&s->h); | |
6918 | 426 |
12036 | 427 switch(s->type){ |
8585 | 428 case MUXER_TYPE_VIDEO: |
6918 | 429 { |
12036 | 430 int biSize=s->bih->biSize; |
431 le2me_BITMAPINFOHEADER(s->bih); | |
432 write_avi_chunk(f,ckidSTREAMFORMAT,biSize,s->bih); /* BITMAPINFOHEADER */ | |
12053 | 433 le2me_BITMAPINFOHEADER(s->bih); |
434 | |
12061 | 435 if (aspect != 0) { |
12053 | 436 int fields = vprp.nbFieldPerFrame; |
12051 | 437 le2me_VideoPropHeader(&vprp); |
438 le2me_VIDEO_FIELD_DESC(&vprp.FieldInfo[0]); | |
439 le2me_VIDEO_FIELD_DESC(&vprp.FieldInfo[1]); | |
440 write_avi_chunk(f,mmioFOURCC('v','p','r','p'), | |
12053 | 441 sizeof(VideoPropHeader) - |
442 sizeof(VIDEO_FIELD_DESC)*(2-fields), | |
443 &vprp); /* Video Properties Header */ | |
12051 | 444 } |
6918 | 445 } |
2529 | 446 break; |
8585 | 447 case MUXER_TYPE_AUDIO: |
6918 | 448 { |
12036 | 449 int wfsize = WFSIZE(s->wf); |
450 le2me_WAVEFORMATEX(s->wf); | |
451 write_avi_chunk(f,ckidSTREAMFORMAT,wfsize,s->wf); /* WAVEFORMATEX */ | |
452 le2me_WAVEFORMATEX(s->wf); | |
6918 | 453 } |
2529 | 454 break; |
455 } | |
12036 | 456 if (isodml && si && si->superidx && si->superidxsize) { |
457 n = si->superidxsize; | |
458 | |
459 idxhdr[0] = le2me_32(mmioFOURCC('i', 'n', 'd', 'x')); | |
460 idxhdr[1] = le2me_32(24 + 16*n); | |
461 idxhdr[2] = le2me_32(0x00000004); | |
462 idxhdr[3] = le2me_32(si->superidxpos); | |
463 idxhdr[4] = le2me_32(s->ckid); | |
464 idxhdr[5] = 0; | |
465 idxhdr[6] = 0; | |
466 idxhdr[7] = 0; | |
467 | |
468 fwrite(idxhdr,sizeof(idxhdr),1,f); | |
469 for (j=0; j<n; j++) { | |
470 struct avi_odmlsuperidx_entry *entry = &si->superidx[j]; | |
471 unsigned int data[4]; | |
472 data[0] = le2me_32(entry->ofs); | |
473 data[1] = le2me_32(entry->ofs >> 32); | |
474 data[2] = le2me_32(entry->len); | |
475 data[3] = le2me_32(entry->duration); | |
476 fwrite(data,sizeof(data),1,f); | |
477 } | |
478 } | |
479 } | |
480 | |
481 // ODML | |
482 if (isodml) { | |
483 memset(dmlh, 0, sizeof(dmlh)); | |
484 dmlh[0] = le2me_32(muxer->avih.dwTotalFrames); | |
485 write_avi_list(f,mmioFOURCC('o','d','m','l'),sizeof(dmlh)+8); | |
486 write_avi_chunk(f,mmioFOURCC('d','m','l','h'),sizeof(dmlh),dmlh); | |
2529 | 487 } |
488 | |
7145
3854945aefbb
new mencoder option -info, to store copyright, title, encoder version etc in AVI
arpi
parents:
7144
diff
changeset
|
489 // ============= INFO =============== |
3854945aefbb
new mencoder option -info, to store copyright, title, encoder version etc in AVI
arpi
parents:
7144
diff
changeset
|
490 // always include software info |
3854945aefbb
new mencoder option -info, to store copyright, title, encoder version etc in AVI
arpi
parents:
7144
diff
changeset
|
491 info[0].id=mmioFOURCC('I','S','F','T'); // Software: |
3854945aefbb
new mencoder option -info, to store copyright, title, encoder version etc in AVI
arpi
parents:
7144
diff
changeset
|
492 info[0].text="MEncoder " VERSION; |
3854945aefbb
new mencoder option -info, to store copyright, title, encoder version etc in AVI
arpi
parents:
7144
diff
changeset
|
493 // include any optional strings |
3854945aefbb
new mencoder option -info, to store copyright, title, encoder version etc in AVI
arpi
parents:
7144
diff
changeset
|
494 i=1; |
3854945aefbb
new mencoder option -info, to store copyright, title, encoder version etc in AVI
arpi
parents:
7144
diff
changeset
|
495 if(info_name!=NULL){ |
3854945aefbb
new mencoder option -info, to store copyright, title, encoder version etc in AVI
arpi
parents:
7144
diff
changeset
|
496 info[i].id=mmioFOURCC('I','N','A','M'); // Name: |
3854945aefbb
new mencoder option -info, to store copyright, title, encoder version etc in AVI
arpi
parents:
7144
diff
changeset
|
497 info[i++].text=info_name; |
3854945aefbb
new mencoder option -info, to store copyright, title, encoder version etc in AVI
arpi
parents:
7144
diff
changeset
|
498 } |
3854945aefbb
new mencoder option -info, to store copyright, title, encoder version etc in AVI
arpi
parents:
7144
diff
changeset
|
499 if(info_artist!=NULL){ |
3854945aefbb
new mencoder option -info, to store copyright, title, encoder version etc in AVI
arpi
parents:
7144
diff
changeset
|
500 info[i].id=mmioFOURCC('I','A','R','T'); // Artist: |
3854945aefbb
new mencoder option -info, to store copyright, title, encoder version etc in AVI
arpi
parents:
7144
diff
changeset
|
501 info[i++].text=info_artist; |
3854945aefbb
new mencoder option -info, to store copyright, title, encoder version etc in AVI
arpi
parents:
7144
diff
changeset
|
502 } |
3854945aefbb
new mencoder option -info, to store copyright, title, encoder version etc in AVI
arpi
parents:
7144
diff
changeset
|
503 if(info_genre!=NULL){ |
3854945aefbb
new mencoder option -info, to store copyright, title, encoder version etc in AVI
arpi
parents:
7144
diff
changeset
|
504 info[i].id=mmioFOURCC('I','G','N','R'); // Genre: |
3854945aefbb
new mencoder option -info, to store copyright, title, encoder version etc in AVI
arpi
parents:
7144
diff
changeset
|
505 info[i++].text=info_genre; |
3854945aefbb
new mencoder option -info, to store copyright, title, encoder version etc in AVI
arpi
parents:
7144
diff
changeset
|
506 } |
3854945aefbb
new mencoder option -info, to store copyright, title, encoder version etc in AVI
arpi
parents:
7144
diff
changeset
|
507 if(info_subject!=NULL){ |
3854945aefbb
new mencoder option -info, to store copyright, title, encoder version etc in AVI
arpi
parents:
7144
diff
changeset
|
508 info[i].id=mmioFOURCC('I','S','B','J'); // Subject: |
3854945aefbb
new mencoder option -info, to store copyright, title, encoder version etc in AVI
arpi
parents:
7144
diff
changeset
|
509 info[i++].text=info_subject; |
3854945aefbb
new mencoder option -info, to store copyright, title, encoder version etc in AVI
arpi
parents:
7144
diff
changeset
|
510 } |
3854945aefbb
new mencoder option -info, to store copyright, title, encoder version etc in AVI
arpi
parents:
7144
diff
changeset
|
511 if(info_copyright!=NULL){ |
3854945aefbb
new mencoder option -info, to store copyright, title, encoder version etc in AVI
arpi
parents:
7144
diff
changeset
|
512 info[i].id=mmioFOURCC('I','C','O','P'); // Copyright: |
3854945aefbb
new mencoder option -info, to store copyright, title, encoder version etc in AVI
arpi
parents:
7144
diff
changeset
|
513 info[i++].text=info_copyright; |
3854945aefbb
new mencoder option -info, to store copyright, title, encoder version etc in AVI
arpi
parents:
7144
diff
changeset
|
514 } |
3854945aefbb
new mencoder option -info, to store copyright, title, encoder version etc in AVI
arpi
parents:
7144
diff
changeset
|
515 if(info_sourceform!=NULL){ |
3854945aefbb
new mencoder option -info, to store copyright, title, encoder version etc in AVI
arpi
parents:
7144
diff
changeset
|
516 info[i].id=mmioFOURCC('I','S','R','F'); // Source Form: |
3854945aefbb
new mencoder option -info, to store copyright, title, encoder version etc in AVI
arpi
parents:
7144
diff
changeset
|
517 info[i++].text=info_sourceform; |
3854945aefbb
new mencoder option -info, to store copyright, title, encoder version etc in AVI
arpi
parents:
7144
diff
changeset
|
518 } |
3854945aefbb
new mencoder option -info, to store copyright, title, encoder version etc in AVI
arpi
parents:
7144
diff
changeset
|
519 if(info_comment!=NULL){ |
3854945aefbb
new mencoder option -info, to store copyright, title, encoder version etc in AVI
arpi
parents:
7144
diff
changeset
|
520 info[i].id=mmioFOURCC('I','C','M','T'); // Comment: |
3854945aefbb
new mencoder option -info, to store copyright, title, encoder version etc in AVI
arpi
parents:
7144
diff
changeset
|
521 info[i++].text=info_comment; |
3854945aefbb
new mencoder option -info, to store copyright, title, encoder version etc in AVI
arpi
parents:
7144
diff
changeset
|
522 } |
3854945aefbb
new mencoder option -info, to store copyright, title, encoder version etc in AVI
arpi
parents:
7144
diff
changeset
|
523 info[i].id=0; |
3854945aefbb
new mencoder option -info, to store copyright, title, encoder version etc in AVI
arpi
parents:
7144
diff
changeset
|
524 |
3854945aefbb
new mencoder option -info, to store copyright, title, encoder version etc in AVI
arpi
parents:
7144
diff
changeset
|
525 hdrsize=0; |
3854945aefbb
new mencoder option -info, to store copyright, title, encoder version etc in AVI
arpi
parents:
7144
diff
changeset
|
526 // calc info size: |
3854945aefbb
new mencoder option -info, to store copyright, title, encoder version etc in AVI
arpi
parents:
7144
diff
changeset
|
527 for(i=0;info[i].id!=0;i++) if(info[i].text){ |
3854945aefbb
new mencoder option -info, to store copyright, title, encoder version etc in AVI
arpi
parents:
7144
diff
changeset
|
528 size_t sz=strlen(info[i].text)+1; |
3854945aefbb
new mencoder option -info, to store copyright, title, encoder version etc in AVI
arpi
parents:
7144
diff
changeset
|
529 hdrsize+=sz+8+sz%2; |
3854945aefbb
new mencoder option -info, to store copyright, title, encoder version etc in AVI
arpi
parents:
7144
diff
changeset
|
530 } |
3854945aefbb
new mencoder option -info, to store copyright, title, encoder version etc in AVI
arpi
parents:
7144
diff
changeset
|
531 // write infos: |
3854945aefbb
new mencoder option -info, to store copyright, title, encoder version etc in AVI
arpi
parents:
7144
diff
changeset
|
532 if (hdrsize!=0){ |
3854945aefbb
new mencoder option -info, to store copyright, title, encoder version etc in AVI
arpi
parents:
7144
diff
changeset
|
533 write_avi_list(f,mmioFOURCC('I','N','F','O'),hdrsize); |
3854945aefbb
new mencoder option -info, to store copyright, title, encoder version etc in AVI
arpi
parents:
7144
diff
changeset
|
534 for(i=0;info[i].id!=0;i++) if(info[i].text){ |
3854945aefbb
new mencoder option -info, to store copyright, title, encoder version etc in AVI
arpi
parents:
7144
diff
changeset
|
535 write_avi_chunk(f,info[i].id,strlen(info[i].text)+1,info[i].text); |
3854945aefbb
new mencoder option -info, to store copyright, title, encoder version etc in AVI
arpi
parents:
7144
diff
changeset
|
536 } |
3854945aefbb
new mencoder option -info, to store copyright, title, encoder version etc in AVI
arpi
parents:
7144
diff
changeset
|
537 } |
3854945aefbb
new mencoder option -info, to store copyright, title, encoder version etc in AVI
arpi
parents:
7144
diff
changeset
|
538 |
2529 | 539 // JUNK: |
12036 | 540 write_avi_chunk(f,ckidAVIPADDING,MOVIALIGN-(ftello(f)%MOVIALIGN)-8,NULL); /* junk */ |
541 if (!isodml) { | |
542 // 'movi' header: | |
543 write_avi_list(f,listtypeAVIMOVIE,muxer->movi_end-ftello(f)-12); | |
544 } else { | |
545 if (ftello(f) != MOVIALIGN) { | |
546 mp_msg(MSGT_MUXER, MSGL_ERR, "Opendml superindex is too big for reserved space!\n"); | |
17366 | 547 mp_msg(MSGT_MUXER, MSGL_ERR, "Expected filepos %d, real filepos %ld, missing space %ld\n", MOVIALIGN, ftell(muxer->file), ftell(muxer->file)-MOVIALIGN); |
12037 | 548 mp_msg(MSGT_MUXER, MSGL_ERR, "Try increasing MOVIALIGN in libmpdemux/muxer_avi.c\n"); |
12036 | 549 } |
550 write_avi_list(f,listtypeAVIMOVIE,muxer->movi_end-ftello(f)-12); | |
551 } | |
552 muxer->movi_start=ftello(muxer->file); | |
12235
ca5dc9c2cb51
Get rid of the 'RIFF chunks have to be aligned on ODML_CHUNKLEN'
ranma
parents:
12062
diff
changeset
|
553 if (muxer->file_end == 0) muxer->file_end = ftello(muxer->file); |
12036 | 554 } |
555 | |
556 static void avifile_odml_write_index(muxer_t *muxer){ | |
557 muxer_stream_t* s; | |
558 struct avi_stream_info *si; | |
559 int i; | |
560 | |
561 for (i=0; i<muxer->avih.dwStreams; i++) { | |
562 int j,k,n,idxpos,len,last,entries_per_subidx; | |
563 unsigned int idxhdr[8]; | |
564 s = muxer->streams[i]; | |
565 si = s->priv; | |
566 | |
567 /* | |
568 * According to Avery Lee MSMP wants the subidx chunks to have the same size. | |
569 * | |
570 * So this code figures out how many entries we can put into | |
571 * an ix?? chunk, so that each ix?? chunk has the same size and the offsets | |
572 * don't overflow (Using ODML_CHUNKLEN for that is a bit more restrictive | |
573 * than it has to be though). | |
574 */ | |
575 | |
576 len = 0; | |
577 n = 0; | |
578 entries_per_subidx = INT_MAX; | |
579 do { | |
580 off_t start = si->idx[0].ofs; | |
581 last = entries_per_subidx; | |
582 for (j=0; j<si->idxpos; j++) { | |
583 len = si->idx[j].ofs - start; | |
584 if(len >= ODML_CHUNKLEN || n >= entries_per_subidx) { | |
585 if (entries_per_subidx > n) { | |
586 entries_per_subidx = n; | |
587 } | |
588 start = si->idx[j].ofs; | |
589 len = 0; | |
590 n = 0; | |
591 } | |
592 n++; | |
593 } | |
594 } while (last != entries_per_subidx); | |
595 | |
596 si->superidxpos = (si->idxpos+entries_per_subidx-1) / entries_per_subidx; | |
597 | |
598 mp_msg(MSGT_MUXER, MSGL_V, "ODML: Stream %d: Using %d entries per subidx, %d entries in superidx\n", | |
599 i, entries_per_subidx, si->superidxpos); | |
600 | |
601 si->superidxsize = si->superidxpos; | |
602 si->superidx = malloc(sizeof(*si->superidx) * si->superidxsize); | |
603 memset(si->superidx, 0, sizeof(*si->superidx) * si->superidxsize); | |
604 | |
605 idxpos = 0; | |
606 for (j=0; j<si->superidxpos; j++) { | |
607 off_t start = si->idx[idxpos].ofs; | |
608 int duration; | |
609 | |
610 duration = 0; | |
611 for (k=0; k<entries_per_subidx && idxpos+k<si->idxpos; k++) { | |
612 duration += s->h.dwSampleSize ? si->idx[idxpos+k].len/s->h.dwSampleSize : 1; | |
613 } | |
614 | |
615 idxhdr[0] = le2me_32((s->ckid << 16) | mmioFOURCC('i', 'x', 0, 0)); | |
616 idxhdr[1] = le2me_32(24 + 8*k); | |
617 idxhdr[2] = le2me_32(0x01000002); | |
618 idxhdr[3] = le2me_32(k); | |
619 idxhdr[4] = le2me_32(s->ckid); | |
620 idxhdr[5] = le2me_32(start + 8); | |
621 idxhdr[6] = le2me_32((start + 8)>> 32); | |
622 idxhdr[7] = 0; /* unused */ | |
623 | |
624 si->superidx[j].len = 32 + 8*k; | |
625 si->superidx[j].ofs = ftello(muxer->file); | |
626 si->superidx[j].duration = duration; | |
627 | |
628 fwrite(idxhdr,sizeof(idxhdr),1,muxer->file); | |
629 for (k=0; k<entries_per_subidx && idxpos<si->idxpos; k++) { | |
630 unsigned int entry[2]; | |
631 entry[0] = le2me_32(si->idx[idxpos].ofs - start); | |
632 entry[1] = le2me_32(si->idx[idxpos].len | si->idx[idxpos].flags); | |
633 idxpos++; | |
634 fwrite(entry,sizeof(entry),1,muxer->file); | |
635 } | |
636 } | |
637 } | |
638 muxer->file_end=ftello(muxer->file); | |
1 | 639 } |
640 | |
12363 | 641 static void avifile_write_standard_index(muxer_t *muxer){ |
12036 | 642 |
643 muxer->movi_end=ftello(muxer->file); | |
2529 | 644 if(muxer->idx && muxer->idx_pos>0){ |
6918 | 645 int i; |
2529 | 646 // fixup index entries: |
647 // for(i=0;i<muxer->idx_pos;i++) muxer->idx[i].dwChunkOffset-=muxer->movi_start-4; | |
648 // write index chunk: | |
6918 | 649 for (i=0; i<muxer->idx_pos; i++) le2me_AVIINDEXENTRY((&muxer->idx[i])); |
9007
12fc55eb3373
Cleanup of the muxer API, func parameters muxer & muxer_f eliminated.
arpi
parents:
8591
diff
changeset
|
650 write_avi_chunk(muxer->file,ckidAVINEWINDEX,16*muxer->idx_pos,muxer->idx); /* AVIINDEXENTRY */ |
6918 | 651 for (i=0; i<muxer->idx_pos; i++) le2me_AVIINDEXENTRY((&muxer->idx[i])); |
2529 | 652 muxer->avih.dwFlags|=AVIF_HASINDEX; |
653 } | |
12036 | 654 muxer->file_end=ftello(muxer->file); |
1 | 655 } |
656 | |
12363 | 657 static void avifile_write_index(muxer_t *muxer){ |
658 struct avi_stream_info *vsi = muxer->def_v->priv; | |
659 | |
17065
cf6bfdf41143
Clean up some muxer messages, patch by Corey Hickey bugfood-ml AT -fatooh/org- , small fixes by me
reynaldo
parents:
17023
diff
changeset
|
660 mp_msg(MSGT_MUXER, MSGL_INFO, MSGTR_WritingTrailer); |
12363 | 661 if (vsi->riffofspos > 0){ |
662 avifile_odml_write_index(muxer); | |
663 } else { | |
664 avifile_write_standard_index(muxer); | |
665 } | |
666 } | |
667 | |
17659 | 668 static void avifile_fix_parameters(muxer_stream_t *s){ |
669 /* adjust audio_delay_fix according to individual stream delay */ | |
670 if (s->type == MUXER_TYPE_AUDIO) | |
671 s->muxer->audio_delay_fix -= (float)s->decoder_delay * s->h.dwScale/s->h.dwRate; | |
672 if (s->type == MUXER_TYPE_VIDEO) | |
673 s->muxer->audio_delay_fix += (float)s->decoder_delay * s->h.dwScale/s->h.dwRate; | |
674 } | |
675 | |
14753
70c446099f40
new mpeg muxer compatible with dvd/[s]vcd; small changes in the muxer layer (sanity checks in the muxer_init functions)
nicodvb
parents:
13250
diff
changeset
|
676 int muxer_init_muxer_avi(muxer_t *muxer){ |
8585 | 677 muxer->cont_new_stream = &avifile_new_stream; |
678 muxer->cont_write_chunk = &avifile_write_chunk; | |
679 muxer->cont_write_header = &avifile_write_header; | |
680 muxer->cont_write_index = &avifile_write_index; | |
17659 | 681 muxer->fix_stream_parameters = &avifile_fix_parameters; |
14753
70c446099f40
new mpeg muxer compatible with dvd/[s]vcd; small changes in the muxer layer (sanity checks in the muxer_init functions)
nicodvb
parents:
13250
diff
changeset
|
682 return 1; |
8585 | 683 } |