Signed-off-by: Paul B Mahol <onemda@gmail.com>
Paul B Mahol authored on 2013/05/06 09:14:05... | ... |
@@ -162,33 +162,31 @@ void ff_id3v2_start(ID3v2EncContext *id3, AVIOContext *pb, int id3v2_version, |
162 | 162 |
avio_wb32(pb, 0); |
163 | 163 |
} |
164 | 164 |
|
165 |
-int ff_id3v2_write_metadata(AVFormatContext *s, ID3v2EncContext *id3) |
|
165 |
+static int write_metadata(AVIOContext *pb, AVDictionary **metadata, |
|
166 |
+ ID3v2EncContext *id3, int enc) |
|
166 | 167 |
{ |
167 | 168 |
AVDictionaryEntry *t = NULL; |
168 |
- int enc = id3->version == 3 ? ID3v2_ENCODING_UTF16BOM : |
|
169 |
- ID3v2_ENCODING_UTF8; |
|
169 |
+ int ret; |
|
170 | 170 |
|
171 |
- ff_metadata_conv(&s->metadata, ff_id3v2_34_metadata_conv, NULL); |
|
171 |
+ ff_metadata_conv(metadata, ff_id3v2_34_metadata_conv, NULL); |
|
172 | 172 |
if (id3->version == 3) |
173 |
- id3v2_3_metadata_split_date(&s->metadata); |
|
173 |
+ id3v2_3_metadata_split_date(metadata); |
|
174 | 174 |
else if (id3->version == 4) |
175 |
- ff_metadata_conv(&s->metadata, ff_id3v2_4_metadata_conv, NULL); |
|
176 |
- |
|
177 |
- while ((t = av_dict_get(s->metadata, "", t, AV_DICT_IGNORE_SUFFIX))) { |
|
178 |
- int ret; |
|
175 |
+ ff_metadata_conv(metadata, ff_id3v2_4_metadata_conv, NULL); |
|
179 | 176 |
|
180 |
- if ((ret = id3v2_check_write_tag(id3, s->pb, t, ff_id3v2_tags, enc)) > 0) { |
|
177 |
+ while ((t = av_dict_get(*metadata, "", t, AV_DICT_IGNORE_SUFFIX))) { |
|
178 |
+ if ((ret = id3v2_check_write_tag(id3, pb, t, ff_id3v2_tags, enc)) > 0) { |
|
181 | 179 |
id3->len += ret; |
182 | 180 |
continue; |
183 | 181 |
} |
184 |
- if ((ret = id3v2_check_write_tag(id3, s->pb, t, id3->version == 3 ? |
|
185 |
- ff_id3v2_3_tags : ff_id3v2_4_tags, enc)) > 0) { |
|
182 |
+ if ((ret = id3v2_check_write_tag(id3, pb, t, id3->version == 3 ? |
|
183 |
+ ff_id3v2_3_tags : ff_id3v2_4_tags, enc)) > 0) { |
|
186 | 184 |
id3->len += ret; |
187 | 185 |
continue; |
188 | 186 |
} |
189 | 187 |
|
190 | 188 |
/* unknown tag, write as TXXX frame */ |
191 |
- if ((ret = id3v2_put_ttag(id3, s->pb, t->key, t->value, MKBETAG('T', 'X', 'X', 'X'), enc)) < 0) |
|
189 |
+ if ((ret = id3v2_put_ttag(id3, pb, t->key, t->value, MKBETAG('T', 'X', 'X', 'X'), enc)) < 0) |
|
192 | 190 |
return ret; |
193 | 191 |
id3->len += ret; |
194 | 192 |
} |
... | ... |
@@ -196,6 +194,64 @@ int ff_id3v2_write_metadata(AVFormatContext *s, ID3v2EncContext *id3) |
196 | 196 |
return 0; |
197 | 197 |
} |
198 | 198 |
|
199 |
+static int write_chapter(AVFormatContext *s, ID3v2EncContext *id3, int id, int enc) |
|
200 |
+{ |
|
201 |
+ const AVRational time_base = {1, 1000}; |
|
202 |
+ AVChapter *ch = s->chapters[id]; |
|
203 |
+ uint8_t *dyn_buf = NULL; |
|
204 |
+ AVIOContext *dyn_bc = NULL; |
|
205 |
+ char name[123]; |
|
206 |
+ int len, start, end, ret; |
|
207 |
+ |
|
208 |
+ if ((ret = avio_open_dyn_buf(&dyn_bc)) < 0) |
|
209 |
+ goto fail; |
|
210 |
+ |
|
211 |
+ start = av_rescale_q(ch->start, ch->time_base, time_base); |
|
212 |
+ end = av_rescale_q(ch->end, ch->time_base, time_base); |
|
213 |
+ |
|
214 |
+ snprintf(name, 122, "ch%d", id); |
|
215 |
+ id3->len += avio_put_str(dyn_bc, name); |
|
216 |
+ avio_wb32(dyn_bc, start); |
|
217 |
+ avio_wb32(dyn_bc, end); |
|
218 |
+ avio_wb32(dyn_bc, 0xFFFFFFFFu); |
|
219 |
+ avio_wb32(dyn_bc, 0xFFFFFFFFu); |
|
220 |
+ |
|
221 |
+ if ((ret = write_metadata(dyn_bc, &ch->metadata, id3, enc)) < 0) |
|
222 |
+ goto fail; |
|
223 |
+ |
|
224 |
+ len = avio_close_dyn_buf(dyn_bc, &dyn_buf); |
|
225 |
+ id3->len += 16 + ID3v2_HEADER_SIZE; |
|
226 |
+ |
|
227 |
+ avio_wb32(s->pb, MKBETAG('C', 'H', 'A', 'P')); |
|
228 |
+ avio_wb32(s->pb, len); |
|
229 |
+ avio_wb16(s->pb, 0); |
|
230 |
+ avio_write(s->pb, dyn_buf, len); |
|
231 |
+ |
|
232 |
+fail: |
|
233 |
+ if (dyn_bc && !dyn_buf) |
|
234 |
+ avio_close_dyn_buf(dyn_bc, &dyn_buf); |
|
235 |
+ av_freep(&dyn_buf); |
|
236 |
+ |
|
237 |
+ return ret; |
|
238 |
+} |
|
239 |
+ |
|
240 |
+int ff_id3v2_write_metadata(AVFormatContext *s, ID3v2EncContext *id3) |
|
241 |
+{ |
|
242 |
+ int enc = id3->version == 3 ? ID3v2_ENCODING_UTF16BOM : |
|
243 |
+ ID3v2_ENCODING_UTF8; |
|
244 |
+ int i, ret; |
|
245 |
+ |
|
246 |
+ if ((ret = write_metadata(s->pb, &s->metadata, id3, enc)) < 0) |
|
247 |
+ return ret; |
|
248 |
+ |
|
249 |
+ for (i = 0; i < s->nb_chapters; i++) { |
|
250 |
+ if ((ret = write_chapter(s, id3, i, enc)) < 0) |
|
251 |
+ return ret; |
|
252 |
+ } |
|
253 |
+ |
|
254 |
+ return 0; |
|
255 |
+} |
|
256 |
+ |
|
199 | 257 |
int ff_id3v2_write_apic(AVFormatContext *s, ID3v2EncContext *id3, AVPacket *pkt) |
200 | 258 |
{ |
201 | 259 |
AVStream *st = s->streams[pkt->stream_index]; |