Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * Metadata muxer
  3.  * Copyright (c) 2010 Anton Khirnov
  4.  *
  5.  * This file is part of FFmpeg.
  6.  *
  7.  * FFmpeg is free software; you can redistribute it and/or
  8.  * modify it under the terms of the GNU Lesser General Public
  9.  * License as published by the Free Software Foundation; either
  10.  * version 2.1 of the License, or (at your option) any later version.
  11.  *
  12.  * FFmpeg is distributed in the hope that it will be useful,
  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
  18.  * License along with FFmpeg; if not, write to the Free Software
  19.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  20.  */
  21.  
  22. #include <inttypes.h>
  23.  
  24. #include "avformat.h"
  25. #include "ffmeta.h"
  26. #include "libavutil/dict.h"
  27.  
  28.  
  29. static void write_escape_str(AVIOContext *s, const uint8_t *str)
  30. {
  31.     const uint8_t *p = str;
  32.  
  33.     while (*p) {
  34.         if (*p == '#' || *p == ';' || *p == '=' || *p == '\\' || *p == '\n')
  35.             avio_w8(s, '\\');
  36.         avio_w8(s, *p);
  37.         p++;
  38.     }
  39. }
  40.  
  41. static void write_tags(AVIOContext *s, AVDictionary *m)
  42. {
  43.     AVDictionaryEntry *t = NULL;
  44.     while ((t = av_dict_get(m, "", t, AV_DICT_IGNORE_SUFFIX))) {
  45.         write_escape_str(s, t->key);
  46.         avio_w8(s, '=');
  47.         write_escape_str(s, t->value);
  48.         avio_w8(s, '\n');
  49.     }
  50. }
  51.  
  52. static int write_header(AVFormatContext *s)
  53. {
  54.     avio_write(s->pb, ID_STRING, sizeof(ID_STRING) - 1);
  55.     avio_w8(s->pb, '1');          // version
  56.     avio_w8(s->pb, '\n');
  57.     avio_flush(s->pb);
  58.     return 0;
  59. }
  60.  
  61. static int write_trailer(AVFormatContext *s)
  62. {
  63.     int i;
  64.  
  65.     write_tags(s->pb, s->metadata);
  66.  
  67.     for (i = 0; i < s->nb_streams; i++) {
  68.         avio_write(s->pb, ID_STREAM, sizeof(ID_STREAM) - 1);
  69.         avio_w8(s->pb, '\n');
  70.         write_tags(s->pb, s->streams[i]->metadata);
  71.     }
  72.  
  73.     for (i = 0; i < s->nb_chapters; i++) {
  74.         AVChapter *ch = s->chapters[i];
  75.         avio_write(s->pb, ID_CHAPTER, sizeof(ID_CHAPTER) - 1);
  76.         avio_w8(s->pb, '\n');
  77.         avio_printf(s->pb, "TIMEBASE=%d/%d\n", ch->time_base.num, ch->time_base.den);
  78.         avio_printf(s->pb, "START=%"PRId64"\n", ch->start);
  79.         avio_printf(s->pb, "END=%"PRId64"\n",   ch->end);
  80.         write_tags(s->pb, ch->metadata);
  81.     }
  82.  
  83.     return 0;
  84. }
  85.  
  86. static int write_packet(AVFormatContext *s, AVPacket *pkt)
  87. {
  88.     return 0;
  89. }
  90.  
  91. AVOutputFormat ff_ffmetadata_muxer = {
  92.     .name          = "ffmetadata",
  93.     .long_name     = NULL_IF_CONFIG_SMALL("FFmpeg metadata in text"),
  94.     .extensions    = "ffmeta",
  95.     .write_header  = write_header,
  96.     .write_packet  = write_packet,
  97.     .write_trailer = write_trailer,
  98.     .flags         = AVFMT_NOTIMESTAMPS | AVFMT_NOSTREAMS,
  99. };
  100.