a4651511 |
/*
* Metadata muxer
* Copyright (c) 2010 Anton Khirnov
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
|
c0ae5152 |
#include <inttypes.h>
|
a4651511 |
#include "avformat.h" |
14fa75ea |
#include "ffmeta.h" |
d2d67e42 |
#include "libavutil/dict.h" |
a4651511 |
|
ae628ec1 |
static void write_escape_str(AVIOContext *s, const uint8_t *str) |
a4651511 |
{
const uint8_t *p = str;
while (*p) {
if (*p == '#' || *p == ';' || *p == '=' || *p == '\\' || *p == '\n') |
77eb5504 |
avio_w8(s, '\\');
avio_w8(s, *p); |
a4651511 |
p++;
}
}
|
d2d67e42 |
static void write_tags(AVIOContext *s, AVDictionary *m) |
a4651511 |
{ |
d2d67e42 |
AVDictionaryEntry *t = NULL;
while ((t = av_dict_get(m, "", t, AV_DICT_IGNORE_SUFFIX))) { |
a4651511 |
write_escape_str(s, t->key); |
77eb5504 |
avio_w8(s, '='); |
a4651511 |
write_escape_str(s, t->value); |
77eb5504 |
avio_w8(s, '\n'); |
a4651511 |
}
}
static int write_header(AVFormatContext *s)
{ |
bbc413f9 |
avio_write(s->pb, ID_STRING, sizeof(ID_STRING) - 1); |
77eb5504 |
avio_w8(s->pb, '1'); // version
avio_w8(s->pb, '\n'); |
b7f2fdde |
avio_flush(s->pb); |
a4651511 |
return 0;
}
static int write_trailer(AVFormatContext *s)
{
int i;
write_tags(s->pb, s->metadata);
for (i = 0; i < s->nb_streams; i++) { |
bbc413f9 |
avio_write(s->pb, ID_STREAM, sizeof(ID_STREAM) - 1); |
77eb5504 |
avio_w8(s->pb, '\n'); |
a4651511 |
write_tags(s->pb, s->streams[i]->metadata);
}
for (i = 0; i < s->nb_chapters; i++) {
AVChapter *ch = s->chapters[i]; |
bbc413f9 |
avio_write(s->pb, ID_CHAPTER, sizeof(ID_CHAPTER) - 1); |
77eb5504 |
avio_w8(s->pb, '\n'); |
d9d86e00 |
avio_printf(s->pb, "TIMEBASE=%d/%d\n", ch->time_base.num, ch->time_base.den);
avio_printf(s->pb, "START=%"PRId64"\n", ch->start);
avio_printf(s->pb, "END=%"PRId64"\n", ch->end); |
a4651511 |
write_tags(s->pb, ch->metadata);
}
|
b7f2fdde |
avio_flush(s->pb); |
a4651511 |
return 0;
}
static int write_packet(AVFormatContext *s, AVPacket *pkt)
{
return 0;
}
|
c6610a21 |
AVOutputFormat ff_ffmetadata_muxer = { |
a4651511 |
.name = "ffmetadata",
.long_name = NULL_IF_CONFIG_SMALL("FFmpeg metadata in text format"),
.extensions = "ffmeta",
.write_header = write_header,
.write_packet = write_packet,
.write_trailer = write_trailer,
.flags = AVFMT_NOTIMESTAMPS | AVFMT_NOSTREAMS,
}; |