Mercurial > libavformat.hg
annotate avienc.c @ 6048:e507a21a9566 libavformat
matroskaenc: Write codec time base as default duration for video tracks.
This isn't exactly semantically equivalent, but the field has already been
long abused to mean this, and writing it helps in determining a decent cfr
time base when transcoding from a mkv where the video codec stores none (VP8).
author | conrad |
---|---|
date | Mon, 24 May 2010 08:58:19 +0000 |
parents | 11bb10c37225 |
children | 563496476a23 |
rev | line source |
---|---|
0 | 1 /* |
1415
3b00fb8ef8e4
replace coder/decoder file description in libavformat by muxer/demuxer
aurel
parents:
1358
diff
changeset
|
2 * AVI muxer |
4251
77e0c7511d41
cosmetics: Remove pointless period after copyright statement non-sentences.
diego
parents:
4250
diff
changeset
|
3 * Copyright (c) 2000 Fabrice Bellard |
0 | 4 * |
1358
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1332
diff
changeset
|
5 * This file is part of FFmpeg. |
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1332
diff
changeset
|
6 * |
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1332
diff
changeset
|
7 * FFmpeg is free software; you can redistribute it and/or |
0 | 8 * modify it under the terms of the GNU Lesser General Public |
9 * License as published by the Free Software Foundation; either | |
1358
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1332
diff
changeset
|
10 * version 2.1 of the License, or (at your option) any later version. |
0 | 11 * |
1358
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1332
diff
changeset
|
12 * FFmpeg is distributed in the hope that it will be useful, |
0 | 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
15 * Lesser General Public License for more details. | |
16 * | |
17 * You should have received a copy of the GNU Lesser General Public | |
1358
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1332
diff
changeset
|
18 * License along with FFmpeg; if not, write to the Free Software |
896
edbe5c3717f9
Update licensing information: The FSF changed postal address.
diego
parents:
894
diff
changeset
|
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
0 | 20 */ |
21 #include "avformat.h" | |
22 #include "avi.h" | |
1172
6a5e58d2114b
move common stuff from avienc.c and wav.c to new file riff.c
mru
parents:
1169
diff
changeset
|
23 #include "riff.h" |
5633 | 24 #include "libavutil/intreadwrite.h" |
0 | 25 |
26 /* | |
885 | 27 * TODO: |
0 | 28 * - fill all fields if non streamed (nb_frames for example) |
29 */ | |
30 | |
119 | 31 typedef struct AVIIentry { |
32 unsigned int flags, pos, len; | |
33 } AVIIentry; | |
34 | |
35 #define AVI_INDEX_CLUSTER_SIZE 16384 | |
36 | |
0 | 37 typedef struct AVIIndex { |
3973
549a09cf23fe
Remove offset_t typedef and use int64_t directly instead.
diego
parents:
3872
diff
changeset
|
38 int64_t indx_start; |
119 | 39 int entry; |
40 int ents_allocated; | |
41 AVIIentry** cluster; | |
0 | 42 } AVIIndex; |
43 | |
44 typedef struct { | |
3973
549a09cf23fe
Remove offset_t typedef and use int64_t directly instead.
diego
parents:
3872
diff
changeset
|
45 int64_t riff_start, movi_list, odml_list; |
5597
d7c68046a431
Introduce AVIStream struct and move stream based variables to it.
michael
parents:
5058
diff
changeset
|
46 int64_t frames_hdr_all; |
119 | 47 int riff_id; |
5597
d7c68046a431
Introduce AVIStream struct and move stream based variables to it.
michael
parents:
5058
diff
changeset
|
48 } AVIContext; |
119 | 49 |
5597
d7c68046a431
Introduce AVIStream struct and move stream based variables to it.
michael
parents:
5058
diff
changeset
|
50 typedef struct { |
d7c68046a431
Introduce AVIStream struct and move stream based variables to it.
michael
parents:
5058
diff
changeset
|
51 int64_t frames_hdr_strm; |
d7c68046a431
Introduce AVIStream struct and move stream based variables to it.
michael
parents:
5058
diff
changeset
|
52 int audio_strm_length; |
d7c68046a431
Introduce AVIStream struct and move stream based variables to it.
michael
parents:
5058
diff
changeset
|
53 int packet_count; |
5598 | 54 int entry; |
5597
d7c68046a431
Introduce AVIStream struct and move stream based variables to it.
michael
parents:
5058
diff
changeset
|
55 |
d7c68046a431
Introduce AVIStream struct and move stream based variables to it.
michael
parents:
5058
diff
changeset
|
56 AVIIndex indexes; |
d7c68046a431
Introduce AVIStream struct and move stream based variables to it.
michael
parents:
5058
diff
changeset
|
57 } AVIStream ; |
0 | 58 |
885 | 59 static inline AVIIentry* avi_get_ientry(AVIIndex* idx, int ent_id) |
119 | 60 { |
61 int cl = ent_id / AVI_INDEX_CLUSTER_SIZE; | |
62 int id = ent_id % AVI_INDEX_CLUSTER_SIZE; | |
63 return &idx->cluster[cl][id]; | |
64 } | |
65 | |
5597
d7c68046a431
Introduce AVIStream struct and move stream based variables to it.
michael
parents:
5058
diff
changeset
|
66 static int64_t avi_start_new_riff(AVFormatContext *s, ByteIOContext *pb, |
3973
549a09cf23fe
Remove offset_t typedef and use int64_t directly instead.
diego
parents:
3872
diff
changeset
|
67 const char* riff_tag, const char* list_tag) |
102
c48108fe538e
AVI > 2Gb (OpenDML) generation patch by (Roman Shaposhnick <rvs at sun dot com>)
michaelni
parents:
94
diff
changeset
|
68 { |
5597
d7c68046a431
Introduce AVIStream struct and move stream based variables to it.
michael
parents:
5058
diff
changeset
|
69 AVIContext *avi= s->priv_data; |
3973
549a09cf23fe
Remove offset_t typedef and use int64_t directly instead.
diego
parents:
3872
diff
changeset
|
70 int64_t loff; |
119 | 71 int i; |
885 | 72 |
119 | 73 avi->riff_id++; |
5597
d7c68046a431
Introduce AVIStream struct and move stream based variables to it.
michael
parents:
5058
diff
changeset
|
74 for (i=0; i<s->nb_streams; i++){ |
d7c68046a431
Introduce AVIStream struct and move stream based variables to it.
michael
parents:
5058
diff
changeset
|
75 AVIStream *avist= s->streams[i]->priv_data; |
d7c68046a431
Introduce AVIStream struct and move stream based variables to it.
michael
parents:
5058
diff
changeset
|
76 avist->indexes.entry = 0; |
d7c68046a431
Introduce AVIStream struct and move stream based variables to it.
michael
parents:
5058
diff
changeset
|
77 } |
885 | 78 |
5058
33a244b7ca65
Add ff_ prefixes to exported symbols in libavformat/riff.h.
diego
parents:
5044
diff
changeset
|
79 avi->riff_start = ff_start_tag(pb, "RIFF"); |
102
c48108fe538e
AVI > 2Gb (OpenDML) generation patch by (Roman Shaposhnick <rvs at sun dot com>)
michaelni
parents:
94
diff
changeset
|
80 put_tag(pb, riff_tag); |
5058
33a244b7ca65
Add ff_ prefixes to exported symbols in libavformat/riff.h.
diego
parents:
5044
diff
changeset
|
81 loff = ff_start_tag(pb, "LIST"); |
102
c48108fe538e
AVI > 2Gb (OpenDML) generation patch by (Roman Shaposhnick <rvs at sun dot com>)
michaelni
parents:
94
diff
changeset
|
82 put_tag(pb, list_tag); |
c48108fe538e
AVI > 2Gb (OpenDML) generation patch by (Roman Shaposhnick <rvs at sun dot com>)
michaelni
parents:
94
diff
changeset
|
83 return loff; |
c48108fe538e
AVI > 2Gb (OpenDML) generation patch by (Roman Shaposhnick <rvs at sun dot com>)
michaelni
parents:
94
diff
changeset
|
84 } |
c48108fe538e
AVI > 2Gb (OpenDML) generation patch by (Roman Shaposhnick <rvs at sun dot com>)
michaelni
parents:
94
diff
changeset
|
85 |
5910
536e5527c1e0
Define AVMediaType enum, and use it instead of enum CodecType, which
stefano
parents:
5661
diff
changeset
|
86 static char* avi_stream2fourcc(char* tag, int index, enum AVMediaType type) |
119 | 87 { |
88 tag[0] = '0'; | |
89 tag[1] = '0' + index; | |
5910
536e5527c1e0
Define AVMediaType enum, and use it instead of enum CodecType, which
stefano
parents:
5661
diff
changeset
|
90 if (type == AVMEDIA_TYPE_VIDEO) { |
119 | 91 tag[2] = 'd'; |
92 tag[3] = 'c'; | |
5910
536e5527c1e0
Define AVMediaType enum, and use it instead of enum CodecType, which
stefano
parents:
5661
diff
changeset
|
93 } else if (type == AVMEDIA_TYPE_SUBTITLE) { |
5044
2ef633b32f7a
Add support for muxing XSUB subtitles to AVI muxer.
reimar
parents:
4816
diff
changeset
|
94 // note: this is not an official code |
2ef633b32f7a
Add support for muxing XSUB subtitles to AVI muxer.
reimar
parents:
4816
diff
changeset
|
95 tag[2] = 's'; |
2ef633b32f7a
Add support for muxing XSUB subtitles to AVI muxer.
reimar
parents:
4816
diff
changeset
|
96 tag[3] = 'b'; |
119 | 97 } else { |
98 tag[2] = 'w'; | |
99 tag[3] = 'b'; | |
100 } | |
101 tag[4] = '\0'; | |
102 return tag; | |
103 } | |
104 | |
1256 | 105 static void avi_write_info_tag(ByteIOContext *pb, const char *tag, const char *str) |
106 { | |
107 int len = strlen(str); | |
108 if (len > 0) { | |
109 len++; | |
110 put_tag(pb, tag); | |
111 put_le32(pb, len); | |
112 put_strz(pb, str); | |
113 if (len & 1) | |
114 put_byte(pb, 0); | |
115 } | |
116 } | |
117 | |
1267 | 118 static int avi_write_counters(AVFormatContext* s, int riff_id) |
119 { | |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2227
diff
changeset
|
120 ByteIOContext *pb = s->pb; |
1267 | 121 AVIContext *avi = s->priv_data; |
122 int n, au_byterate, au_ssize, au_scale, nb_frames = 0; | |
3973
549a09cf23fe
Remove offset_t typedef and use int64_t directly instead.
diego
parents:
3872
diff
changeset
|
123 int64_t file_size; |
1267 | 124 AVCodecContext* stream; |
125 | |
126 file_size = url_ftell(pb); | |
127 for(n = 0; n < s->nb_streams; n++) { | |
5597
d7c68046a431
Introduce AVIStream struct and move stream based variables to it.
michael
parents:
5058
diff
changeset
|
128 AVIStream *avist= s->streams[n]->priv_data; |
d7c68046a431
Introduce AVIStream struct and move stream based variables to it.
michael
parents:
5058
diff
changeset
|
129 |
d7c68046a431
Introduce AVIStream struct and move stream based variables to it.
michael
parents:
5058
diff
changeset
|
130 assert(avist->frames_hdr_strm); |
1267 | 131 stream = s->streams[n]->codec; |
5597
d7c68046a431
Introduce AVIStream struct and move stream based variables to it.
michael
parents:
5058
diff
changeset
|
132 url_fseek(pb, avist->frames_hdr_strm, SEEK_SET); |
1267 | 133 ff_parse_specific_params(stream, &au_byterate, &au_ssize, &au_scale); |
134 if(au_ssize == 0) { | |
5597
d7c68046a431
Introduce AVIStream struct and move stream based variables to it.
michael
parents:
5058
diff
changeset
|
135 put_le32(pb, avist->packet_count); |
1267 | 136 } else { |
5597
d7c68046a431
Introduce AVIStream struct and move stream based variables to it.
michael
parents:
5058
diff
changeset
|
137 put_le32(pb, avist->audio_strm_length / au_ssize); |
1267 | 138 } |
5910
536e5527c1e0
Define AVMediaType enum, and use it instead of enum CodecType, which
stefano
parents:
5661
diff
changeset
|
139 if(stream->codec_type == AVMEDIA_TYPE_VIDEO) |
5597
d7c68046a431
Introduce AVIStream struct and move stream based variables to it.
michael
parents:
5058
diff
changeset
|
140 nb_frames = FFMAX(nb_frames, avist->packet_count); |
1267 | 141 } |
142 if(riff_id == 1) { | |
143 assert(avi->frames_hdr_all); | |
144 url_fseek(pb, avi->frames_hdr_all, SEEK_SET); | |
145 put_le32(pb, nb_frames); | |
146 } | |
147 url_fseek(pb, file_size, SEEK_SET); | |
148 | |
149 return 0; | |
150 } | |
151 | |
0 | 152 static int avi_write_header(AVFormatContext *s) |
153 { | |
154 AVIContext *avi = s->priv_data; | |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2227
diff
changeset
|
155 ByteIOContext *pb = s->pb; |
0 | 156 int bitrate, n, i, nb_frames, au_byterate, au_ssize, au_scale; |
157 AVCodecContext *stream, *video_enc; | |
3973
549a09cf23fe
Remove offset_t typedef and use int64_t directly instead.
diego
parents:
3872
diff
changeset
|
158 int64_t list1, list2, strh, strf; |
5633 | 159 AVMetadataTag *t = NULL; |
0 | 160 |
5597
d7c68046a431
Introduce AVIStream struct and move stream based variables to it.
michael
parents:
5058
diff
changeset
|
161 for(n=0;n<s->nb_streams;n++) { |
d7c68046a431
Introduce AVIStream struct and move stream based variables to it.
michael
parents:
5058
diff
changeset
|
162 s->streams[n]->priv_data= av_mallocz(sizeof(AVIStream)); |
d7c68046a431
Introduce AVIStream struct and move stream based variables to it.
michael
parents:
5058
diff
changeset
|
163 if(!s->streams[n]->priv_data) |
d7c68046a431
Introduce AVIStream struct and move stream based variables to it.
michael
parents:
5058
diff
changeset
|
164 return AVERROR(ENOMEM); |
d7c68046a431
Introduce AVIStream struct and move stream based variables to it.
michael
parents:
5058
diff
changeset
|
165 } |
d7c68046a431
Introduce AVIStream struct and move stream based variables to it.
michael
parents:
5058
diff
changeset
|
166 |
0 | 167 /* header list */ |
119 | 168 avi->riff_id = 0; |
5597
d7c68046a431
Introduce AVIStream struct and move stream based variables to it.
michael
parents:
5058
diff
changeset
|
169 list1 = avi_start_new_riff(s, pb, "AVI ", "hdrl"); |
0 | 170 |
171 /* avi header */ | |
172 put_tag(pb, "avih"); | |
173 put_le32(pb, 14 * 4); | |
174 bitrate = 0; | |
175 | |
176 video_enc = NULL; | |
177 for(n=0;n<s->nb_streams;n++) { | |
820
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
796
diff
changeset
|
178 stream = s->streams[n]->codec; |
0 | 179 bitrate += stream->bit_rate; |
5910
536e5527c1e0
Define AVMediaType enum, and use it instead of enum CodecType, which
stefano
parents:
5661
diff
changeset
|
180 if (stream->codec_type == AVMEDIA_TYPE_VIDEO) |
0 | 181 video_enc = stream; |
182 } | |
885 | 183 |
0 | 184 nb_frames = 0; |
185 | |
36
1188ad85857a
audio only avi patch by (Andriy Rysin <arysin at bcsii dot net>)
michaelni
parents:
15
diff
changeset
|
186 if(video_enc){ |
1556 | 187 put_le32(pb, (uint32_t)(INT64_C(1000000) * video_enc->time_base.num / video_enc->time_base.den)); |
36
1188ad85857a
audio only avi patch by (Andriy Rysin <arysin at bcsii dot net>)
michaelni
parents:
15
diff
changeset
|
188 } else { |
887 | 189 put_le32(pb, 0); |
36
1188ad85857a
audio only avi patch by (Andriy Rysin <arysin at bcsii dot net>)
michaelni
parents:
15
diff
changeset
|
190 } |
0 | 191 put_le32(pb, bitrate / 8); /* XXX: not quite exact */ |
192 put_le32(pb, 0); /* padding */ | |
873
7af647503b67
Support for streaming: dont write indexes and dont signal HAS_INDEX in header. Also set filesize to max in this case.
alex
parents:
863
diff
changeset
|
193 if (url_is_streamed(pb)) |
887 | 194 put_le32(pb, AVIF_TRUSTCKTYPE | AVIF_ISINTERLEAVED); /* flags */ |
873
7af647503b67
Support for streaming: dont write indexes and dont signal HAS_INDEX in header. Also set filesize to max in this case.
alex
parents:
863
diff
changeset
|
195 else |
887 | 196 put_le32(pb, AVIF_TRUSTCKTYPE | AVIF_HASINDEX | AVIF_ISINTERLEAVED); /* flags */ |
0 | 197 avi->frames_hdr_all = url_ftell(pb); /* remember this offset to fill later */ |
198 put_le32(pb, nb_frames); /* nb frames, filled later */ | |
199 put_le32(pb, 0); /* initial frame */ | |
200 put_le32(pb, s->nb_streams); /* nb streams */ | |
201 put_le32(pb, 1024 * 1024); /* suggested buffer size */ | |
885 | 202 if(video_enc){ |
992 | 203 put_le32(pb, video_enc->width); |
204 put_le32(pb, video_enc->height); | |
36
1188ad85857a
audio only avi patch by (Andriy Rysin <arysin at bcsii dot net>)
michaelni
parents:
15
diff
changeset
|
205 } else { |
887 | 206 put_le32(pb, 0); |
207 put_le32(pb, 0); | |
885 | 208 } |
0 | 209 put_le32(pb, 0); /* reserved */ |
210 put_le32(pb, 0); /* reserved */ | |
211 put_le32(pb, 0); /* reserved */ | |
212 put_le32(pb, 0); /* reserved */ | |
885 | 213 |
0 | 214 /* stream list */ |
215 for(i=0;i<n;i++) { | |
5597
d7c68046a431
Introduce AVIStream struct and move stream based variables to it.
michael
parents:
5058
diff
changeset
|
216 AVIStream *avist= s->streams[i]->priv_data; |
5058
33a244b7ca65
Add ff_ prefixes to exported symbols in libavformat/riff.h.
diego
parents:
5044
diff
changeset
|
217 list2 = ff_start_tag(pb, "LIST"); |
0 | 218 put_tag(pb, "strl"); |
885 | 219 |
820
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
796
diff
changeset
|
220 stream = s->streams[i]->codec; |
0 | 221 |
222 /* stream generic header */ | |
5058
33a244b7ca65
Add ff_ prefixes to exported symbols in libavformat/riff.h.
diego
parents:
5044
diff
changeset
|
223 strh = ff_start_tag(pb, "strh"); |
0 | 224 switch(stream->codec_type) { |
5910
536e5527c1e0
Define AVMediaType enum, and use it instead of enum CodecType, which
stefano
parents:
5661
diff
changeset
|
225 case AVMEDIA_TYPE_SUBTITLE: |
5044
2ef633b32f7a
Add support for muxing XSUB subtitles to AVI muxer.
reimar
parents:
4816
diff
changeset
|
226 // XSUB subtitles behave like video tracks, other subtitles |
2ef633b32f7a
Add support for muxing XSUB subtitles to AVI muxer.
reimar
parents:
4816
diff
changeset
|
227 // are not (yet) supported. |
2ef633b32f7a
Add support for muxing XSUB subtitles to AVI muxer.
reimar
parents:
4816
diff
changeset
|
228 if (stream->codec_id != CODEC_ID_XSUB) break; |
5910
536e5527c1e0
Define AVMediaType enum, and use it instead of enum CodecType, which
stefano
parents:
5661
diff
changeset
|
229 case AVMEDIA_TYPE_VIDEO: put_tag(pb, "vids"); break; |
536e5527c1e0
Define AVMediaType enum, and use it instead of enum CodecType, which
stefano
parents:
5661
diff
changeset
|
230 case AVMEDIA_TYPE_AUDIO: put_tag(pb, "auds"); break; |
536e5527c1e0
Define AVMediaType enum, and use it instead of enum CodecType, which
stefano
parents:
5661
diff
changeset
|
231 // case AVMEDIA_TYPE_TEXT : put_tag(pb, "txts"); break; |
536e5527c1e0
Define AVMediaType enum, and use it instead of enum CodecType, which
stefano
parents:
5661
diff
changeset
|
232 case AVMEDIA_TYPE_DATA : put_tag(pb, "dats"); break; |
781 | 233 } |
5910
536e5527c1e0
Define AVMediaType enum, and use it instead of enum CodecType, which
stefano
parents:
5661
diff
changeset
|
234 if(stream->codec_type == AVMEDIA_TYPE_VIDEO || |
5044
2ef633b32f7a
Add support for muxing XSUB subtitles to AVI muxer.
reimar
parents:
4816
diff
changeset
|
235 stream->codec_id == CODEC_ID_XSUB) |
89
8e3cf4e9fc5a
rawvideo patch by (Fred Rothganger <rothgang at uiuc dot edu>)
michaelni
parents:
85
diff
changeset
|
236 put_le32(pb, stream->codec_tag); |
781 | 237 else |
238 put_le32(pb, 1); | |
239 put_le32(pb, 0); /* flags */ | |
240 put_le16(pb, 0); /* priority */ | |
241 put_le16(pb, 0); /* language */ | |
242 put_le32(pb, 0); /* initial frame */ | |
243 | |
244 ff_parse_specific_params(stream, &au_byterate, &au_ssize, &au_scale); | |
75
78bec272ce3a
read BITMAPINFOHEADER extra stuff (huffyuv decoding fixed)
michaelni
parents:
65
diff
changeset
|
245 |
781 | 246 put_le32(pb, au_scale); /* scale */ |
247 put_le32(pb, au_byterate); /* rate */ | |
248 av_set_pts_info(s->streams[i], 64, au_scale, au_byterate); | |
249 | |
250 put_le32(pb, 0); /* start */ | |
5597
d7c68046a431
Introduce AVIStream struct and move stream based variables to it.
michael
parents:
5058
diff
changeset
|
251 avist->frames_hdr_strm = url_ftell(pb); /* remember this offset to fill later */ |
887 | 252 if (url_is_streamed(pb)) |
253 put_le32(pb, AVI_MAX_RIFF_SIZE); /* FIXME: this may be broken, but who cares */ | |
254 else | |
255 put_le32(pb, 0); /* length, XXX: filled later */ | |
885 | 256 |
781 | 257 /* suggested buffer size */ //FIXME set at the end to largest chunk |
5910
536e5527c1e0
Define AVMediaType enum, and use it instead of enum CodecType, which
stefano
parents:
5661
diff
changeset
|
258 if(stream->codec_type == AVMEDIA_TYPE_VIDEO) |
885 | 259 put_le32(pb, 1024 * 1024); |
5910
536e5527c1e0
Define AVMediaType enum, and use it instead of enum CodecType, which
stefano
parents:
5661
diff
changeset
|
260 else if(stream->codec_type == AVMEDIA_TYPE_AUDIO) |
885 | 261 put_le32(pb, 12 * 1024); |
781 | 262 else |
885 | 263 put_le32(pb, 0); |
781 | 264 put_le32(pb, -1); /* quality */ |
265 put_le32(pb, au_ssize); /* sample size */ | |
266 put_le32(pb, 0); | |
267 put_le16(pb, stream->width); | |
268 put_le16(pb, stream->height); | |
5058
33a244b7ca65
Add ff_ prefixes to exported symbols in libavformat/riff.h.
diego
parents:
5044
diff
changeset
|
269 ff_end_tag(pb, strh); |
0 | 270 |
5910
536e5527c1e0
Define AVMediaType enum, and use it instead of enum CodecType, which
stefano
parents:
5661
diff
changeset
|
271 if(stream->codec_type != AVMEDIA_TYPE_DATA){ |
5058
33a244b7ca65
Add ff_ prefixes to exported symbols in libavformat/riff.h.
diego
parents:
5044
diff
changeset
|
272 strf = ff_start_tag(pb, "strf"); |
0 | 273 switch(stream->codec_type) { |
5910
536e5527c1e0
Define AVMediaType enum, and use it instead of enum CodecType, which
stefano
parents:
5661
diff
changeset
|
274 case AVMEDIA_TYPE_SUBTITLE: |
5044
2ef633b32f7a
Add support for muxing XSUB subtitles to AVI muxer.
reimar
parents:
4816
diff
changeset
|
275 // XSUB subtitles behave like video tracks, other subtitles |
2ef633b32f7a
Add support for muxing XSUB subtitles to AVI muxer.
reimar
parents:
4816
diff
changeset
|
276 // are not (yet) supported. |
2ef633b32f7a
Add support for muxing XSUB subtitles to AVI muxer.
reimar
parents:
4816
diff
changeset
|
277 if (stream->codec_id != CODEC_ID_XSUB) break; |
5910
536e5527c1e0
Define AVMediaType enum, and use it instead of enum CodecType, which
stefano
parents:
5661
diff
changeset
|
278 case AVMEDIA_TYPE_VIDEO: |
5058
33a244b7ca65
Add ff_ prefixes to exported symbols in libavformat/riff.h.
diego
parents:
5044
diff
changeset
|
279 ff_put_bmp_header(pb, stream, ff_codec_bmp_tags, 0); |
0 | 280 break; |
5910
536e5527c1e0
Define AVMediaType enum, and use it instead of enum CodecType, which
stefano
parents:
5661
diff
changeset
|
281 case AVMEDIA_TYPE_AUDIO: |
5058
33a244b7ca65
Add ff_ prefixes to exported symbols in libavformat/riff.h.
diego
parents:
5044
diff
changeset
|
282 if (ff_put_wav_header(pb, stream) < 0) { |
0 | 283 return -1; |
284 } | |
285 break; | |
286 default: | |
537 | 287 return -1; |
0 | 288 } |
5058
33a244b7ca65
Add ff_ prefixes to exported symbols in libavformat/riff.h.
diego
parents:
5044
diff
changeset
|
289 ff_end_tag(pb, strf); |
5633 | 290 if ((t = av_metadata_get(s->streams[i]->metadata, "strn", NULL, 0))) { |
291 avi_write_info_tag(s->pb, t->key, t->value); | |
292 t = NULL; | |
293 } | |
294 //FIXME a limitation of metadata conversion system | |
295 else if ((t = av_metadata_get(s->streams[i]->metadata, "INAM", NULL, 0))) { | |
296 avi_write_info_tag(s->pb, "strn", t->value); | |
297 t = NULL; | |
298 } | |
781 | 299 } |
885 | 300 |
887 | 301 if (!url_is_streamed(pb)) { |
302 unsigned char tag[5]; | |
303 int j; | |
885 | 304 |
305 /* Starting to lay out AVI OpenDML master index. | |
887 | 306 * We want to make it JUNK entry for now, since we'd |
307 * like to get away without making AVI an OpenDML one | |
308 * for compatibility reasons. | |
309 */ | |
5597
d7c68046a431
Introduce AVIStream struct and move stream based variables to it.
michael
parents:
5058
diff
changeset
|
310 avist->indexes.entry = avist->indexes.ents_allocated = 0; |
d7c68046a431
Introduce AVIStream struct and move stream based variables to it.
michael
parents:
5058
diff
changeset
|
311 avist->indexes.indx_start = ff_start_tag(pb, "JUNK"); |
887 | 312 put_le16(pb, 4); /* wLongsPerEntry */ |
313 put_byte(pb, 0); /* bIndexSubType (0 == frame index) */ | |
314 put_byte(pb, 0); /* bIndexType (0 == AVI_INDEX_OF_INDEXES) */ | |
315 put_le32(pb, 0); /* nEntriesInUse (will fill out later on) */ | |
316 put_tag(pb, avi_stream2fourcc(&tag[0], i, stream->codec_type)); | |
317 /* dwChunkId */ | |
318 put_le64(pb, 0); /* dwReserved[3] | |
319 put_le32(pb, 0); Must be 0. */ | |
320 for (j=0; j < AVI_MASTER_INDEX_SIZE * 2; j++) | |
321 put_le64(pb, 0); | |
5597
d7c68046a431
Introduce AVIStream struct and move stream based variables to it.
michael
parents:
5058
diff
changeset
|
322 ff_end_tag(pb, avist->indexes.indx_start); |
887 | 323 } |
885 | 324 |
5910
536e5527c1e0
Define AVMediaType enum, and use it instead of enum CodecType, which
stefano
parents:
5661
diff
changeset
|
325 if( stream->codec_type == AVMEDIA_TYPE_VIDEO |
3759
27537074f2a9
convert every muxer/demuxer to write/read sample_aspect_ratio from/to
aurel
parents:
3424
diff
changeset
|
326 && s->streams[i]->sample_aspect_ratio.num>0 |
27537074f2a9
convert every muxer/demuxer to write/read sample_aspect_ratio from/to
aurel
parents:
3424
diff
changeset
|
327 && s->streams[i]->sample_aspect_ratio.den>0){ |
5058
33a244b7ca65
Add ff_ prefixes to exported symbols in libavformat/riff.h.
diego
parents:
5044
diff
changeset
|
328 int vprp= ff_start_tag(pb, "vprp"); |
3759
27537074f2a9
convert every muxer/demuxer to write/read sample_aspect_ratio from/to
aurel
parents:
3424
diff
changeset
|
329 AVRational dar = av_mul_q(s->streams[i]->sample_aspect_ratio, |
3100 | 330 (AVRational){stream->width, stream->height}); |
331 int num, den; | |
332 av_reduce(&num, &den, dar.num, dar.den, 0xFFFF); | |
333 | |
334 put_le32(pb, 0); //video format = unknown | |
335 put_le32(pb, 0); //video standard= unknown | |
336 put_le32(pb, lrintf(1.0/av_q2d(stream->time_base))); | |
337 put_le32(pb, stream->width ); | |
338 put_le32(pb, stream->height); | |
3177 | 339 put_le16(pb, den); |
3100 | 340 put_le16(pb, num); |
341 put_le32(pb, stream->width ); | |
342 put_le32(pb, stream->height); | |
343 put_le32(pb, 1); //progressive FIXME | |
344 | |
345 put_le32(pb, stream->height); | |
346 put_le32(pb, stream->width ); | |
347 put_le32(pb, stream->height); | |
348 put_le32(pb, stream->width ); | |
349 put_le32(pb, 0); | |
350 put_le32(pb, 0); | |
351 | |
352 put_le32(pb, 0); | |
353 put_le32(pb, 0); | |
5058
33a244b7ca65
Add ff_ prefixes to exported symbols in libavformat/riff.h.
diego
parents:
5044
diff
changeset
|
354 ff_end_tag(pb, vprp); |
3100 | 355 } |
356 | |
5058
33a244b7ca65
Add ff_ prefixes to exported symbols in libavformat/riff.h.
diego
parents:
5044
diff
changeset
|
357 ff_end_tag(pb, list2); |
0 | 358 } |
885 | 359 |
119 | 360 if (!url_is_streamed(pb)) { |
361 /* AVI could become an OpenDML one, if it grows beyond 2Gb range */ | |
5058
33a244b7ca65
Add ff_ prefixes to exported symbols in libavformat/riff.h.
diego
parents:
5044
diff
changeset
|
362 avi->odml_list = ff_start_tag(pb, "JUNK"); |
119 | 363 put_tag(pb, "odml"); |
364 put_tag(pb, "dmlh"); | |
365 put_le32(pb, 248); | |
366 for (i = 0; i < 248; i+= 4) | |
367 put_le32(pb, 0); | |
5058
33a244b7ca65
Add ff_ prefixes to exported symbols in libavformat/riff.h.
diego
parents:
5044
diff
changeset
|
368 ff_end_tag(pb, avi->odml_list); |
119 | 369 } |
0 | 370 |
5058
33a244b7ca65
Add ff_ prefixes to exported symbols in libavformat/riff.h.
diego
parents:
5044
diff
changeset
|
371 ff_end_tag(pb, list1); |
885 | 372 |
5058
33a244b7ca65
Add ff_ prefixes to exported symbols in libavformat/riff.h.
diego
parents:
5044
diff
changeset
|
373 list2 = ff_start_tag(pb, "LIST"); |
1256 | 374 put_tag(pb, "INFO"); |
5633 | 375 for (i = 0; *ff_avi_tags[i]; i++) { |
376 if ((t = av_metadata_get(s->metadata, ff_avi_tags[i], NULL, AV_METADATA_MATCH_CASE))) | |
377 avi_write_info_tag(s->pb, t->key, t->value); | |
378 } | |
5058
33a244b7ca65
Add ff_ prefixes to exported symbols in libavformat/riff.h.
diego
parents:
5044
diff
changeset
|
379 ff_end_tag(pb, list2); |
1256 | 380 |
381 /* some padding for easier tag editing */ | |
5058
33a244b7ca65
Add ff_ prefixes to exported symbols in libavformat/riff.h.
diego
parents:
5044
diff
changeset
|
382 list2 = ff_start_tag(pb, "JUNK"); |
1256 | 383 for (i = 0; i < 1016; i += 4) |
384 put_le32(pb, 0); | |
5058
33a244b7ca65
Add ff_ prefixes to exported symbols in libavformat/riff.h.
diego
parents:
5044
diff
changeset
|
385 ff_end_tag(pb, list2); |
1256 | 386 |
5058
33a244b7ca65
Add ff_ prefixes to exported symbols in libavformat/riff.h.
diego
parents:
5044
diff
changeset
|
387 avi->movi_list = ff_start_tag(pb, "LIST"); |
0 | 388 put_tag(pb, "movi"); |
389 | |
390 put_flush_packet(pb); | |
391 | |
392 return 0; | |
393 } | |
394 | |
119 | 395 static int avi_write_ix(AVFormatContext *s) |
396 { | |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2227
diff
changeset
|
397 ByteIOContext *pb = s->pb; |
119 | 398 AVIContext *avi = s->priv_data; |
1332 | 399 char tag[5]; |
400 char ix_tag[] = "ix00"; | |
119 | 401 int i, j; |
885 | 402 |
976 | 403 assert(!url_is_streamed(pb)); |
873
7af647503b67
Support for streaming: dont write indexes and dont signal HAS_INDEX in header. Also set filesize to max in this case.
alex
parents:
863
diff
changeset
|
404 |
119 | 405 if (avi->riff_id > AVI_MASTER_INDEX_SIZE) |
406 return -1; | |
885 | 407 |
119 | 408 for (i=0;i<s->nb_streams;i++) { |
5597
d7c68046a431
Introduce AVIStream struct and move stream based variables to it.
michael
parents:
5058
diff
changeset
|
409 AVIStream *avist= s->streams[i]->priv_data; |
3973
549a09cf23fe
Remove offset_t typedef and use int64_t directly instead.
diego
parents:
3872
diff
changeset
|
410 int64_t ix, pos; |
885 | 411 |
887 | 412 avi_stream2fourcc(&tag[0], i, s->streams[i]->codec->codec_type); |
413 ix_tag[3] = '0' + i; | |
885 | 414 |
887 | 415 /* Writing AVI OpenDML leaf index chunk */ |
416 ix = url_ftell(pb); | |
417 put_tag(pb, &ix_tag[0]); /* ix?? */ | |
5597
d7c68046a431
Introduce AVIStream struct and move stream based variables to it.
michael
parents:
5058
diff
changeset
|
418 put_le32(pb, avist->indexes.entry * 8 + 24); |
887 | 419 /* chunk size */ |
119 | 420 put_le16(pb, 2); /* wLongsPerEntry */ |
887 | 421 put_byte(pb, 0); /* bIndexSubType (0 == frame index) */ |
422 put_byte(pb, 1); /* bIndexType (1 == AVI_INDEX_OF_CHUNKS) */ | |
5597
d7c68046a431
Introduce AVIStream struct and move stream based variables to it.
michael
parents:
5058
diff
changeset
|
423 put_le32(pb, avist->indexes.entry); |
887 | 424 /* nEntriesInUse */ |
425 put_tag(pb, &tag[0]); /* dwChunkId */ | |
426 put_le64(pb, avi->movi_list);/* qwBaseOffset */ | |
427 put_le32(pb, 0); /* dwReserved_3 (must be 0) */ | |
119 | 428 |
5597
d7c68046a431
Introduce AVIStream struct and move stream based variables to it.
michael
parents:
5058
diff
changeset
|
429 for (j=0; j<avist->indexes.entry; j++) { |
d7c68046a431
Introduce AVIStream struct and move stream based variables to it.
michael
parents:
5058
diff
changeset
|
430 AVIIentry* ie = avi_get_ientry(&avist->indexes, j); |
887 | 431 put_le32(pb, ie->pos + 8); |
432 put_le32(pb, ((uint32_t)ie->len & ~0x80000000) | | |
433 (ie->flags & 0x10 ? 0 : 0x80000000)); | |
119 | 434 } |
887 | 435 put_flush_packet(pb); |
119 | 436 pos = url_ftell(pb); |
885 | 437 |
887 | 438 /* Updating one entry in the AVI OpenDML master index */ |
5597
d7c68046a431
Introduce AVIStream struct and move stream based variables to it.
michael
parents:
5058
diff
changeset
|
439 url_fseek(pb, avist->indexes.indx_start - 8, SEEK_SET); |
887 | 440 put_tag(pb, "indx"); /* enabling this entry */ |
441 url_fskip(pb, 8); | |
442 put_le32(pb, avi->riff_id); /* nEntriesInUse */ | |
443 url_fskip(pb, 16*avi->riff_id); | |
444 put_le64(pb, ix); /* qwOffset */ | |
445 put_le32(pb, pos - ix); /* dwSize */ | |
5597
d7c68046a431
Introduce AVIStream struct and move stream based variables to it.
michael
parents:
5058
diff
changeset
|
446 put_le32(pb, avist->indexes.entry); /* dwDuration */ |
119 | 447 |
887 | 448 url_fseek(pb, pos, SEEK_SET); |
119 | 449 } |
450 return 0; | |
451 } | |
452 | |
453 static int avi_write_idx1(AVFormatContext *s) | |
102
c48108fe538e
AVI > 2Gb (OpenDML) generation patch by (Roman Shaposhnick <rvs at sun dot com>)
michaelni
parents:
94
diff
changeset
|
454 { |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2227
diff
changeset
|
455 ByteIOContext *pb = s->pb; |
102
c48108fe538e
AVI > 2Gb (OpenDML) generation patch by (Roman Shaposhnick <rvs at sun dot com>)
michaelni
parents:
94
diff
changeset
|
456 AVIContext *avi = s->priv_data; |
3973
549a09cf23fe
Remove offset_t typedef and use int64_t directly instead.
diego
parents:
3872
diff
changeset
|
457 int64_t idx_chunk; |
1267 | 458 int i; |
1332 | 459 char tag[5]; |
102
c48108fe538e
AVI > 2Gb (OpenDML) generation patch by (Roman Shaposhnick <rvs at sun dot com>)
michaelni
parents:
94
diff
changeset
|
460 |
c48108fe538e
AVI > 2Gb (OpenDML) generation patch by (Roman Shaposhnick <rvs at sun dot com>)
michaelni
parents:
94
diff
changeset
|
461 if (!url_is_streamed(pb)) { |
5598 | 462 AVIStream *avist; |
887 | 463 AVIIentry* ie = 0, *tie; |
464 int empty, stream_id = -1; | |
102
c48108fe538e
AVI > 2Gb (OpenDML) generation patch by (Roman Shaposhnick <rvs at sun dot com>)
michaelni
parents:
94
diff
changeset
|
465 |
5058
33a244b7ca65
Add ff_ prefixes to exported symbols in libavformat/riff.h.
diego
parents:
5044
diff
changeset
|
466 idx_chunk = ff_start_tag(pb, "idx1"); |
5598 | 467 for(i=0; i<s->nb_streams; i++){ |
468 avist= s->streams[i]->priv_data; | |
469 avist->entry=0; | |
470 } | |
471 | |
887 | 472 do { |
473 empty = 1; | |
474 for (i=0; i<s->nb_streams; i++) { | |
5598 | 475 avist= s->streams[i]->priv_data; |
476 if (avist->indexes.entry <= avist->entry) | |
887 | 477 continue; |
885 | 478 |
5598 | 479 tie = avi_get_ientry(&avist->indexes, avist->entry); |
887 | 480 if (empty || tie->pos < ie->pos) { |
481 ie = tie; | |
482 stream_id = i; | |
483 } | |
484 empty = 0; | |
485 } | |
486 if (!empty) { | |
5598 | 487 avist= s->streams[stream_id]->priv_data; |
887 | 488 avi_stream2fourcc(&tag[0], stream_id, |
489 s->streams[stream_id]->codec->codec_type); | |
490 put_tag(pb, &tag[0]); | |
491 put_le32(pb, ie->flags); | |
119 | 492 put_le32(pb, ie->pos); |
493 put_le32(pb, ie->len); | |
5598 | 494 avist->entry++; |
887 | 495 } |
496 } while (!empty); | |
5058
33a244b7ca65
Add ff_ prefixes to exported symbols in libavformat/riff.h.
diego
parents:
5044
diff
changeset
|
497 ff_end_tag(pb, idx_chunk); |
102
c48108fe538e
AVI > 2Gb (OpenDML) generation patch by (Roman Shaposhnick <rvs at sun dot com>)
michaelni
parents:
94
diff
changeset
|
498 |
1267 | 499 avi_write_counters(s, avi->riff_id); |
102
c48108fe538e
AVI > 2Gb (OpenDML) generation patch by (Roman Shaposhnick <rvs at sun dot com>)
michaelni
parents:
94
diff
changeset
|
500 } |
c48108fe538e
AVI > 2Gb (OpenDML) generation patch by (Roman Shaposhnick <rvs at sun dot com>)
michaelni
parents:
94
diff
changeset
|
501 return 0; |
c48108fe538e
AVI > 2Gb (OpenDML) generation patch by (Roman Shaposhnick <rvs at sun dot com>)
michaelni
parents:
94
diff
changeset
|
502 } |
c48108fe538e
AVI > 2Gb (OpenDML) generation patch by (Roman Shaposhnick <rvs at sun dot com>)
michaelni
parents:
94
diff
changeset
|
503 |
468 | 504 static int avi_write_packet(AVFormatContext *s, AVPacket *pkt) |
0 | 505 { |
506 AVIContext *avi = s->priv_data; | |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2227
diff
changeset
|
507 ByteIOContext *pb = s->pb; |
0 | 508 unsigned char tag[5]; |
468 | 509 unsigned int flags=0; |
510 const int stream_index= pkt->stream_index; | |
5597
d7c68046a431
Introduce AVIStream struct and move stream based variables to it.
michael
parents:
5058
diff
changeset
|
511 AVIStream *avist= s->streams[stream_index]->priv_data; |
820
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
796
diff
changeset
|
512 AVCodecContext *enc= s->streams[stream_index]->codec; |
468 | 513 int size= pkt->size; |
102
c48108fe538e
AVI > 2Gb (OpenDML) generation patch by (Roman Shaposhnick <rvs at sun dot com>)
michaelni
parents:
94
diff
changeset
|
514 |
1443
404048ea11bc
Replace most of the %lld and %llx by their (cleaner) PRI*64 counterparts.
diego
parents:
1415
diff
changeset
|
515 // av_log(s, AV_LOG_DEBUG, "%"PRId64" %d %d\n", pkt->dts, avi->packet_count[stream_index], stream_index); |
5597
d7c68046a431
Introduce AVIStream struct and move stream based variables to it.
michael
parents:
5058
diff
changeset
|
516 while(enc->block_align==0 && pkt->dts != AV_NOPTS_VALUE && pkt->dts > avist->packet_count){ |
479 | 517 AVPacket empty_packet; |
518 | |
519 av_init_packet(&empty_packet); | |
520 empty_packet.size= 0; | |
521 empty_packet.data= NULL; | |
522 empty_packet.stream_index= stream_index; | |
523 avi_write_packet(s, &empty_packet); | |
1443
404048ea11bc
Replace most of the %lld and %llx by their (cleaner) PRI*64 counterparts.
diego
parents:
1415
diff
changeset
|
524 // av_log(s, AV_LOG_DEBUG, "dup %"PRId64" %d\n", pkt->dts, avi->packet_count[stream_index]); |
479 | 525 } |
5597
d7c68046a431
Introduce AVIStream struct and move stream based variables to it.
michael
parents:
5058
diff
changeset
|
526 avist->packet_count++; |
479 | 527 |
873
7af647503b67
Support for streaming: dont write indexes and dont signal HAS_INDEX in header. Also set filesize to max in this case.
alex
parents:
863
diff
changeset
|
528 // Make sure to put an OpenDML chunk when the file size exceeds the limits |
885 | 529 if (!url_is_streamed(pb) && |
887 | 530 (url_ftell(pb) - avi->riff_start > AVI_MAX_RIFF_SIZE)) { |
885 | 531 |
119 | 532 avi_write_ix(s); |
5058
33a244b7ca65
Add ff_ prefixes to exported symbols in libavformat/riff.h.
diego
parents:
5044
diff
changeset
|
533 ff_end_tag(pb, avi->movi_list); |
885 | 534 |
887 | 535 if (avi->riff_id == 1) |
536 avi_write_idx1(s); | |
119 | 537 |
5058
33a244b7ca65
Add ff_ prefixes to exported symbols in libavformat/riff.h.
diego
parents:
5044
diff
changeset
|
538 ff_end_tag(pb, avi->riff_start); |
5597
d7c68046a431
Introduce AVIStream struct and move stream based variables to it.
michael
parents:
5058
diff
changeset
|
539 avi->movi_list = avi_start_new_riff(s, pb, "AVIX", "movi"); |
102
c48108fe538e
AVI > 2Gb (OpenDML) generation patch by (Roman Shaposhnick <rvs at sun dot com>)
michaelni
parents:
94
diff
changeset
|
540 } |
885 | 541 |
119 | 542 avi_stream2fourcc(&tag[0], stream_index, enc->codec_type); |
5913
11bb10c37225
Replace all occurences of PKT_FLAG_KEY with AV_PKT_FLAG_KEY.
cehoyos
parents:
5910
diff
changeset
|
543 if(pkt->flags&AV_PKT_FLAG_KEY) |
468 | 544 flags = 0x10; |
5910
536e5527c1e0
Define AVMediaType enum, and use it instead of enum CodecType, which
stefano
parents:
5661
diff
changeset
|
545 if (enc->codec_type == AVMEDIA_TYPE_AUDIO) { |
5597
d7c68046a431
Introduce AVIStream struct and move stream based variables to it.
michael
parents:
5058
diff
changeset
|
546 avist->audio_strm_length += size; |
468 | 547 } |
0 | 548 |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2227
diff
changeset
|
549 if (!url_is_streamed(s->pb)) { |
5597
d7c68046a431
Introduce AVIStream struct and move stream based variables to it.
michael
parents:
5058
diff
changeset
|
550 AVIIndex* idx = &avist->indexes; |
887 | 551 int cl = idx->entry / AVI_INDEX_CLUSTER_SIZE; |
552 int id = idx->entry % AVI_INDEX_CLUSTER_SIZE; | |
119 | 553 if (idx->ents_allocated <= idx->entry) { |
887 | 554 idx->cluster = av_realloc(idx->cluster, (cl+1)*sizeof(void*)); |
555 if (!idx->cluster) | |
556 return -1; | |
119 | 557 idx->cluster[cl] = av_malloc(AVI_INDEX_CLUSTER_SIZE*sizeof(AVIIentry)); |
887 | 558 if (!idx->cluster[cl]) |
559 return -1; | |
560 idx->ents_allocated += AVI_INDEX_CLUSTER_SIZE; | |
561 } | |
885 | 562 |
887 | 563 idx->cluster[cl][id].flags = flags; |
119 | 564 idx->cluster[cl][id].pos = url_ftell(pb) - avi->movi_list; |
565 idx->cluster[cl][id].len = size; | |
887 | 566 idx->entry++; |
0 | 567 } |
885 | 568 |
0 | 569 put_buffer(pb, tag, 4); |
570 put_le32(pb, size); | |
468 | 571 put_buffer(pb, pkt->data, size); |
0 | 572 if (size & 1) |
573 put_byte(pb, 0); | |
574 | |
575 put_flush_packet(pb); | |
576 return 0; | |
577 } | |
578 | |
579 static int avi_write_trailer(AVFormatContext *s) | |
580 { | |
102
c48108fe538e
AVI > 2Gb (OpenDML) generation patch by (Roman Shaposhnick <rvs at sun dot com>)
michaelni
parents:
94
diff
changeset
|
581 AVIContext *avi = s->priv_data; |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2227
diff
changeset
|
582 ByteIOContext *pb = s->pb; |
102
c48108fe538e
AVI > 2Gb (OpenDML) generation patch by (Roman Shaposhnick <rvs at sun dot com>)
michaelni
parents:
94
diff
changeset
|
583 int res = 0; |
119 | 584 int i, j, n, nb_frames; |
3973
549a09cf23fe
Remove offset_t typedef and use int64_t directly instead.
diego
parents:
3872
diff
changeset
|
585 int64_t file_size; |
0 | 586 |
1676 | 587 if (!url_is_streamed(pb)){ |
588 if (avi->riff_id == 1) { | |
5058
33a244b7ca65
Add ff_ prefixes to exported symbols in libavformat/riff.h.
diego
parents:
5044
diff
changeset
|
589 ff_end_tag(pb, avi->movi_list); |
1676 | 590 res = avi_write_idx1(s); |
5058
33a244b7ca65
Add ff_ prefixes to exported symbols in libavformat/riff.h.
diego
parents:
5044
diff
changeset
|
591 ff_end_tag(pb, avi->riff_start); |
1676 | 592 } else { |
593 avi_write_ix(s); | |
5058
33a244b7ca65
Add ff_ prefixes to exported symbols in libavformat/riff.h.
diego
parents:
5044
diff
changeset
|
594 ff_end_tag(pb, avi->movi_list); |
33a244b7ca65
Add ff_ prefixes to exported symbols in libavformat/riff.h.
diego
parents:
5044
diff
changeset
|
595 ff_end_tag(pb, avi->riff_start); |
119 | 596 |
1676 | 597 file_size = url_ftell(pb); |
598 url_fseek(pb, avi->odml_list - 8, SEEK_SET); | |
599 put_tag(pb, "LIST"); /* Making this AVI OpenDML one */ | |
600 url_fskip(pb, 16); | |
0 | 601 |
1676 | 602 for (n=nb_frames=0;n<s->nb_streams;n++) { |
603 AVCodecContext *stream = s->streams[n]->codec; | |
5597
d7c68046a431
Introduce AVIStream struct and move stream based variables to it.
michael
parents:
5058
diff
changeset
|
604 AVIStream *avist= s->streams[n]->priv_data; |
d7c68046a431
Introduce AVIStream struct and move stream based variables to it.
michael
parents:
5058
diff
changeset
|
605 |
5910
536e5527c1e0
Define AVMediaType enum, and use it instead of enum CodecType, which
stefano
parents:
5661
diff
changeset
|
606 if (stream->codec_type == AVMEDIA_TYPE_VIDEO) { |
5597
d7c68046a431
Introduce AVIStream struct and move stream based variables to it.
michael
parents:
5058
diff
changeset
|
607 if (nb_frames < avist->packet_count) |
d7c68046a431
Introduce AVIStream struct and move stream based variables to it.
michael
parents:
5058
diff
changeset
|
608 nb_frames = avist->packet_count; |
1676 | 609 } else { |
610 if (stream->codec_id == CODEC_ID_MP2 || stream->codec_id == CODEC_ID_MP3) { | |
5597
d7c68046a431
Introduce AVIStream struct and move stream based variables to it.
michael
parents:
5058
diff
changeset
|
611 nb_frames += avist->packet_count; |
1676 | 612 } |
0 | 613 } |
614 } | |
1676 | 615 put_le32(pb, nb_frames); |
616 url_fseek(pb, file_size, SEEK_SET); | |
617 | |
618 avi_write_counters(s, avi->riff_id); | |
102
c48108fe538e
AVI > 2Gb (OpenDML) generation patch by (Roman Shaposhnick <rvs at sun dot com>)
michaelni
parents:
94
diff
changeset
|
619 } |
873
7af647503b67
Support for streaming: dont write indexes and dont signal HAS_INDEX in header. Also set filesize to max in this case.
alex
parents:
863
diff
changeset
|
620 } |
119 | 621 put_flush_packet(pb); |
102
c48108fe538e
AVI > 2Gb (OpenDML) generation patch by (Roman Shaposhnick <rvs at sun dot com>)
michaelni
parents:
94
diff
changeset
|
622 |
5597
d7c68046a431
Introduce AVIStream struct and move stream based variables to it.
michael
parents:
5058
diff
changeset
|
623 for (i=0; i<s->nb_streams; i++) { |
d7c68046a431
Introduce AVIStream struct and move stream based variables to it.
michael
parents:
5058
diff
changeset
|
624 AVIStream *avist= s->streams[i]->priv_data; |
d7c68046a431
Introduce AVIStream struct and move stream based variables to it.
michael
parents:
5058
diff
changeset
|
625 for (j=0; j<avist->indexes.ents_allocated/AVI_INDEX_CLUSTER_SIZE; j++) |
d7c68046a431
Introduce AVIStream struct and move stream based variables to it.
michael
parents:
5058
diff
changeset
|
626 av_free(avist->indexes.cluster[j]); |
d7c68046a431
Introduce AVIStream struct and move stream based variables to it.
michael
parents:
5058
diff
changeset
|
627 av_freep(&avist->indexes.cluster); |
d7c68046a431
Introduce AVIStream struct and move stream based variables to it.
michael
parents:
5058
diff
changeset
|
628 avist->indexes.ents_allocated = avist->indexes.entry = 0; |
119 | 629 } |
885 | 630 |
102
c48108fe538e
AVI > 2Gb (OpenDML) generation patch by (Roman Shaposhnick <rvs at sun dot com>)
michaelni
parents:
94
diff
changeset
|
631 return res; |
0 | 632 } |
633 | |
1169 | 634 AVOutputFormat avi_muxer = { |
0 | 635 "avi", |
3424
7a0230981402
Make long_names in lavf/lavdev optional depending on CONFIG_SMALL.
diego
parents:
3177
diff
changeset
|
636 NULL_IF_CONFIG_SMALL("AVI format"), |
0 | 637 "video/x-msvideo", |
638 "avi", | |
639 sizeof(AVIContext), | |
640 CODEC_ID_MP2, | |
106
4da5d55b3690
we really shouldnt use M$* as default codec -> use MPEG4 as default
michaelni
parents:
105
diff
changeset
|
641 CODEC_ID_MPEG4, |
0 | 642 avi_write_header, |
643 avi_write_packet, | |
644 avi_write_trailer, | |
5058
33a244b7ca65
Add ff_ prefixes to exported symbols in libavformat/riff.h.
diego
parents:
5044
diff
changeset
|
645 .codec_tag= (const AVCodecTag* const []){ff_codec_bmp_tags, ff_codec_wav_tags, 0}, |
4567
963e3b76c7a6
Add AVFMT_VARIABLE_FPS to specify which muxers do not need duplicated frames.
michael
parents:
4477
diff
changeset
|
646 .flags= AVFMT_VARIABLE_FPS, |
5633 | 647 .metadata_conv = ff_avi_metadata_conv, |
0 | 648 }; |