This also adds libavformat/movmeta that contains the meta data information. Actually the sample configuration data is performed with side packet data AV_PKT_DATA_TIMED_METADATA_INFO where the value is stored inside AVTimedMetadataInfo.
Signed-off-by: Erkki Seppälä <erkki.seppala....@nokia.com> Signed-off-by: OZOPlayer <oz...@nokia.com> --- libavcodec/avcodec.h | 16 ++++++++++ libavformat/isom.c | 1 + libavformat/movenc.c | 83 ++++++++++++++++++++++++++++++++++++++++++++++++--- libavformat/movenc.h | 1 + libavformat/movmeta.h | 46 ++++++++++++++++++++++++++++ 5 files changed, 143 insertions(+), 4 deletions(-) create mode 100644 libavformat/movmeta.h diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index 4219a9f..0079d22 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -1350,6 +1350,16 @@ typedef struct AVCPBProperties { * @{ */ +typedef struct AVTimedMetadataInfo { + char meta_tag[4]; /**< 4cc describing this metadata box type */ + int meta_length; /**< length of data for the metadata type information */ + + char conf_tag[4]; /**< configurationg box type 4cc, ie. 'conf' */ + int conf_length; /**< length of the data for the configuration box */ + + /** followed by meta_length bytes of meta data followed by conf_length bytes of conf data */ +} AVTimedMetadataInfo; + typedef struct AVTrackReferences { int next_tref_ofs; /**< offset in bytes to the next AVTrackReferences or 0 if this is the last one*/ char tag[4]; /**< 4cc used for describing this */ @@ -1546,6 +1556,12 @@ enum AVPacketSideDataType { AV_PKT_DATA_TRACK_REFERENCES, /** + * Configured the timed metadata parameters, such as the uri and + * meta data configuration. The value is of type AVTimedMetadataInfo. + */ + AV_PKT_DATA_TIMED_METADATA_INFO, + + /** * Assign alternate groups for tracks. An example of alternate * groups would be audio tracks (or video tracks) that are * alternative to each other. Each alternative track shares the diff --git a/libavformat/isom.c b/libavformat/isom.c index 1a90d00..473700f 100644 --- a/libavformat/isom.c +++ b/libavformat/isom.c @@ -357,6 +357,7 @@ const AVCodecTag ff_codec_movsubtitle_tags[] = { const AVCodecTag ff_codec_metadata_tags[] = { { AV_CODEC_ID_META, MKTAG('m', 'e', 't', 'a') }, + { AV_CODEC_ID_META, MKTAG('u', 'r', 'i', 'm') }, { AV_CODEC_ID_NONE, 0 }, }; diff --git a/libavformat/movenc.c b/libavformat/movenc.c index a6f234e..84a6940 100644 --- a/libavformat/movenc.c +++ b/libavformat/movenc.c @@ -1552,6 +1552,69 @@ static int mov_write_fiel_tag(AVIOContext *pb, MOVTrack *track, int field_order) return 10; } +static int mov_write_urim_uri_box(AVIOContext *pb, const char *uri, int length) +{ + int64_t pos = avio_tell(pb); + avio_wb32(pb, 0); /* size */ + ffio_wfourcc(pb, "uri "); + avio_w8(pb, 0); /* version */ + avio_wb24(pb, 0); /* flags */ + + avio_write(pb, uri, length); /* uri */ + avio_w8(pb, 0); /* null-terminated */ + + return update_size(pb, pos); +} + +static int mov_write_conf_box(AVIOContext *pb, const uint8_t *data, int length, char* tag) +{ + int64_t pos = avio_tell(pb); + avio_wb32(pb, 0); /* size */ + ffio_wfourcc(pb, tag); + + avio_w8(pb, 0); /* version */ + avio_wb24(pb, 0); /* flags */ + + avio_write(pb, data, length); /* data */ + + return update_size(pb, pos); +} + +static int mov_write_meta_codec(AVIOContext *pb, MOVTrack *track) +{ + int64_t pos = avio_tell(pb); + + char *data; + char *tag; + + AVTimedMetadataInfo *meta = + (void*) av_stream_get_side_data(track->st, AV_PKT_DATA_TIMED_METADATA_INFO, + NULL); + + av_assert0(meta); + + avio_wb32(pb, 0); /* size */ + ffio_wfourcc(pb, meta->meta_tag); + + avio_wb32(pb, 0); /* Reserved */ + avio_wb16(pb, 0); /* Reserved */ + avio_wb16(pb, 1); /* Data-reference index */ + + data = (char*) (meta + 1); + tag = meta->meta_tag; + if (tag[0] == 'u' && tag[1] == 'r' && tag[2] == 'i' && tag[3] == 'm') { + mov_write_urim_uri_box(pb, data, meta->meta_length); + data += meta->meta_length; + } + + if (meta->conf_length) { + mov_write_conf_box(pb, data, meta->conf_length, meta->conf_tag); + data += meta->conf_length; + } + + return update_size(pb, pos); +} + static int mov_write_subtitle_tag(AVIOContext *pb, MOVTrack *track) { int64_t pos = avio_tell(pb); @@ -1951,6 +2014,18 @@ static int mov_write_tmcd_tag(AVIOContext *pb, MOVTrack *track) return update_size(pb, pos); } +static int mov_write_data_tag(AVIOContext *pb, MOVTrack *track) +{ + if (track->par->codec_id == AV_CODEC_ID_META) + return mov_write_meta_codec(pb, track); + else if (track->par->codec_tag == MKTAG('t','m','c','d')) + return mov_write_tmcd_tag(pb, track); + else if (track->par->codec_tag == MKTAG('r','t','p',' ')) + return mov_write_rtp_tag(pb, track); + else + return 0; +} + static int mov_write_stsd_tag(AVFormatContext *s, AVIOContext *pb, MOVMuxContext *mov, MOVTrack *track) { int64_t pos = avio_tell(pb); @@ -1962,12 +2037,10 @@ static int mov_write_stsd_tag(AVFormatContext *s, AVIOContext *pb, MOVMuxContext mov_write_video_tag(pb, mov, track); else if (track->par->codec_type == AVMEDIA_TYPE_AUDIO) mov_write_audio_tag(s, pb, mov, track); + else if (track->par->codec_type == AVMEDIA_TYPE_DATA) + mov_write_data_tag(pb, track); else if (track->par->codec_type == AVMEDIA_TYPE_SUBTITLE) mov_write_subtitle_tag(pb, track); - else if (track->par->codec_tag == MKTAG('r','t','p',' ')) - mov_write_rtp_tag(pb, track); - else if (track->par->codec_tag == MKTAG('t','m','c','d')) - mov_write_tmcd_tag(pb, track); return update_size(pb, pos); } @@ -2323,6 +2396,8 @@ static int mov_write_minf_tag(AVFormatContext *s, AVIOContext *pb, MOVMuxContext else mov_write_gmhd_tag(pb, track); } + else if (track->par->codec_type == AVMEDIA_TYPE_DATA) + mov_write_nmhd_tag(pb); if (track->mode == MODE_MOV) /* FIXME: Why do it for MODE_MOV only ? */ mov_write_hdlr_tag(s, pb, NULL); mov_write_dinf_tag(pb); diff --git a/libavformat/movenc.h b/libavformat/movenc.h index 700d8d5..0fdc70f 100644 --- a/libavformat/movenc.h +++ b/libavformat/movenc.h @@ -27,6 +27,7 @@ #include "avformat.h" #include "movenccenc.h" #include "movtref.h" +#include "movmeta.h" #define MOV_FRAG_INFO_ALLOC_INCREMENT 64 #define MOV_INDEX_CLUSTER_SIZE 1024 diff --git a/libavformat/movmeta.h b/libavformat/movmeta.h new file mode 100644 index 0000000..e57b381 --- /dev/null +++ b/libavformat/movmeta.h @@ -0,0 +1,46 @@ +/* + * MOV, 3GP, MP4 muxer + * Copyright (c) 2015 Erkki Seppälä <erkki.seppala....@nokia.com> + * + * 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 + */ + +#ifndef AVFORMAT_MOVMETA_H +#define AVFORMAT_MOVMETA_H + +#include "avformat.h" + +typedef enum MOVMetaType { + MOV_META_NONE, + MOV_META_URIM +} MOVMetaType; + +typedef struct MOVConfMeta { + uint32_t tag; + int length; + void *data; +} MOVConfMeta; + +typedef struct MOVMeta { + uint32_t tag; + int length; + void *data; + + MOVConfMeta conf; +} MOVMeta; + +#endif /* AVFORMAT_MOVMETA_H */ -- 2.7.4 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel