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