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