Revision 9b75309c libavformat/matroskaenc.c

View differences:

libavformat/matroskaenc.c
25 25
#include "matroska.h"
26 26
#include "avc.h"
27 27
#include "flacenc.h"
28
#include "avlanguage.h"
28 29
#include "libavutil/intreadwrite.h"
29 30
#include "libavutil/random_seed.h"
30 31
#include "libavutil/lfg.h"
......
688 689
    return 0;
689 690
}
690 691

  
692
static void mkv_write_simpletag(ByteIOContext *pb, AVMetadataTag *t)
693
{
694
    uint8_t *key = av_strdup(t->key);
695
    uint8_t *p   = key;
696
    const uint8_t *lang = NULL;
697
    ebml_master tag;
698

  
699
    if ((p = strrchr(p, '-')) &&
700
        (lang = av_convert_lang_to(p + 1, AV_LANG_ISO639_2_BIBL)))
701
        *p = 0;
702

  
703
    p = key;
704
    while (*p) {
705
        if (*p == ' ')
706
            *p = '_';
707
        else if (*p >= 'a' && *p <= 'z')
708
            *p -= 'a' - 'A';
709
        p++;
710
    }
711

  
712
    tag = start_ebml_master(pb, MATROSKA_ID_SIMPLETAG, 0);
713
    put_ebml_string(pb, MATROSKA_ID_TAGNAME, key);
714
    if (lang)
715
        put_ebml_string(pb, MATROSKA_ID_TAGLANG, lang);
716
    put_ebml_string(pb, MATROSKA_ID_TAGSTRING, t->value);
717
    end_ebml_master(pb, tag);
718

  
719
    av_freep(&key);
720
}
721

  
722
static int mkv_write_tag(AVFormatContext *s, AVMetadata *m, unsigned int elementid,
723
                         unsigned int uid, ebml_master *tags)
724
{
725
    MatroskaMuxContext *mkv = s->priv_data;
726
    ebml_master tag, targets;
727
    AVMetadataTag *t = NULL;
728
    int ret;
729

  
730
    if (!tags->pos) {
731
        ret = mkv_add_seekhead_entry(mkv->main_seekhead, MATROSKA_ID_TAGS, url_ftell(s->pb));
732
        if (ret < 0) return ret;
733

  
734
        *tags = start_ebml_master(s->pb, MATROSKA_ID_TAGS, 0);
735
    }
736

  
737
    tag     = start_ebml_master(s->pb, MATROSKA_ID_TAG,        0);
738
    targets = start_ebml_master(s->pb, MATROSKA_ID_TAGTARGETS, 0);
739
    if (elementid)
740
        put_ebml_uint(s->pb, elementid, uid);
741
    end_ebml_master(s->pb, targets);
742

  
743
    while ((t = av_metadata_get(m, "", t, AV_METADATA_IGNORE_SUFFIX)))
744
        mkv_write_simpletag(s->pb, t);
745

  
746
    end_ebml_master(s->pb, tag);
747
    return 0;
748
}
749

  
750
static int mkv_write_tags(AVFormatContext *s)
751
{
752
    ebml_master tags = {0};
753
    int i, ret;
754

  
755
    if (av_metadata_get(s->metadata, "", NULL, AV_METADATA_IGNORE_SUFFIX)) {
756
        ret = mkv_write_tag(s, s->metadata, 0, 0, &tags);
757
        if (ret < 0) return ret;
758
    }
759

  
760
    for (i = 0; i < s->nb_streams; i++) {
761
        AVStream *st = s->streams[i];
762

  
763
        if (!av_metadata_get(st->metadata, "", 0, AV_METADATA_IGNORE_SUFFIX))
764
            continue;
765

  
766
        ret = mkv_write_tag(s, st->metadata, MATROSKA_ID_TAGTARGETS_TRACKUID, i + 1, &tags);
767
        if (ret < 0) return ret;
768
    }
769

  
770
    for (i = 0; i < s->nb_chapters; i++) {
771
        AVChapter *ch = s->chapters[i];
772

  
773
        if (!av_metadata_get(ch->metadata, "", NULL, AV_METADATA_IGNORE_SUFFIX))
774
            continue;
775

  
776
        ret = mkv_write_tag(s, ch->metadata, MATROSKA_ID_TAGTARGETS_CHAPTERUID, ch->id, &tags);
777
        if (ret < 0) return ret;
778
    }
779

  
780
    if (tags.pos)
781
        end_ebml_master(s->pb, tags);
782
    return 0;
783
}
784

  
691 785
static int mkv_write_header(AVFormatContext *s)
692 786
{
693 787
    MatroskaMuxContext *mkv = s->priv_data;
......
758 852
    if (mkv->mode != MODE_WEBM) {
759 853
        ret = mkv_write_chapters(s);
760 854
        if (ret < 0) return ret;
855

  
856
        ret = mkv_write_tags(s);
857
        if (ret < 0) return ret;
761 858
    }
762 859

  
763 860
    if (url_is_streamed(s->pb))
......
1089 1186
    .flags = AVFMT_GLOBALHEADER | AVFMT_VARIABLE_FPS,
1090 1187
    .codec_tag = (const AVCodecTag* const []){ff_codec_bmp_tags, ff_codec_wav_tags, 0},
1091 1188
    .subtitle_codec = CODEC_ID_TEXT,
1189
    .metadata_conv = ff_mkv_metadata_conv,
1092 1190
};
1093 1191
#endif
1094 1192

  
......
1122 1220
    mkv_write_trailer,
1123 1221
    .flags = AVFMT_GLOBALHEADER,
1124 1222
    .codec_tag = (const AVCodecTag* const []){ff_codec_wav_tags, 0},
1223
    .metadata_conv = ff_mkv_metadata_conv,
1125 1224
};
1126 1225
#endif

Also available in: Unified diff