Libav 0.7.1
|
00001 /* 00002 * Metadata muxer 00003 * Copyright (c) 2010 Anton Khirnov 00004 * 00005 * This file is part of Libav. 00006 * 00007 * Libav is free software; you can redistribute it and/or 00008 * modify it under the terms of the GNU Lesser General Public 00009 * License as published by the Free Software Foundation; either 00010 * version 2.1 of the License, or (at your option) any later version. 00011 * 00012 * Libav is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00015 * Lesser General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU Lesser General Public 00018 * License along with Libav; if not, write to the Free Software 00019 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00020 */ 00021 00022 #include <inttypes.h> 00023 00024 #include "avformat.h" 00025 #include "ffmeta.h" 00026 #include "libavutil/dict.h" 00027 00028 00029 static void write_escape_str(AVIOContext *s, const uint8_t *str) 00030 { 00031 const uint8_t *p = str; 00032 00033 while (*p) { 00034 if (*p == '#' || *p == ';' || *p == '=' || *p == '\\' || *p == '\n') 00035 avio_w8(s, '\\'); 00036 avio_w8(s, *p); 00037 p++; 00038 } 00039 } 00040 00041 static void write_tags(AVIOContext *s, AVDictionary *m) 00042 { 00043 AVDictionaryEntry *t = NULL; 00044 while ((t = av_dict_get(m, "", t, AV_DICT_IGNORE_SUFFIX))) { 00045 write_escape_str(s, t->key); 00046 avio_w8(s, '='); 00047 write_escape_str(s, t->value); 00048 avio_w8(s, '\n'); 00049 } 00050 } 00051 00052 static int write_header(AVFormatContext *s) 00053 { 00054 avio_write(s->pb, ID_STRING, sizeof(ID_STRING) - 1); 00055 avio_w8(s->pb, '1'); // version 00056 avio_w8(s->pb, '\n'); 00057 avio_flush(s->pb); 00058 return 0; 00059 } 00060 00061 static int write_trailer(AVFormatContext *s) 00062 { 00063 int i; 00064 00065 write_tags(s->pb, s->metadata); 00066 00067 for (i = 0; i < s->nb_streams; i++) { 00068 avio_write(s->pb, ID_STREAM, sizeof(ID_STREAM) - 1); 00069 avio_w8(s->pb, '\n'); 00070 write_tags(s->pb, s->streams[i]->metadata); 00071 } 00072 00073 for (i = 0; i < s->nb_chapters; i++) { 00074 AVChapter *ch = s->chapters[i]; 00075 avio_write(s->pb, ID_CHAPTER, sizeof(ID_CHAPTER) - 1); 00076 avio_w8(s->pb, '\n'); 00077 avio_printf(s->pb, "TIMEBASE=%d/%d\n", ch->time_base.num, ch->time_base.den); 00078 avio_printf(s->pb, "START=%"PRId64"\n", ch->start); 00079 avio_printf(s->pb, "END=%"PRId64"\n", ch->end); 00080 write_tags(s->pb, ch->metadata); 00081 } 00082 00083 avio_flush(s->pb); 00084 00085 return 0; 00086 } 00087 00088 static int write_packet(AVFormatContext *s, AVPacket *pkt) 00089 { 00090 return 0; 00091 } 00092 00093 AVOutputFormat ff_ffmetadata_muxer = { 00094 .name = "ffmetadata", 00095 .long_name = NULL_IF_CONFIG_SMALL("FFmpeg metadata in text format"), 00096 .extensions = "ffmeta", 00097 .write_header = write_header, 00098 .write_packet = write_packet, 00099 .write_trailer = write_trailer, 00100 .flags = AVFMT_NOTIMESTAMPS | AVFMT_NOSTREAMS, 00101 };