/*
- * Adaptive stream format muxer
- * Copyright (c) 2000, 2001 Fabrice Bellard.
+ * ASF muxer
+ * Copyright (c) 2000, 2001 Fabrice Bellard
*
* This file is part of FFmpeg.
*
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "avformat.h"
+#include "metadata.h"
#include "riff.h"
#include "asf.h"
static void put_guid(ByteIOContext *s, const GUID *g)
{
assert(sizeof(*g) == 16);
- put_buffer(s, g, sizeof(*g));
+ put_buffer(s, *g, sizeof(*g));
}
static void put_str16_nolen(ByteIOContext *s, const char *tag);
{
ASFContext *asf = s->priv_data;
ByteIOContext *pb = s->pb;
+ AVMetadataTag *title, *author, *copyright, *comment;
int header_size, n, extra_size, extra_size2, wav_extra_size, file_time;
int has_title;
+ int metadata_count;
AVCodecContext *enc;
int64_t header_offset, cur_pos, hpos;
int bit_rate;
int64_t duration;
+ title = av_metadata_get(s->metadata, "title" , NULL, 0);
+ author = av_metadata_get(s->metadata, "author" , NULL, 0);
+ copyright = av_metadata_get(s->metadata, "copyright", NULL, 0);
+ comment = av_metadata_get(s->metadata, "comment" , NULL, 0);
+
duration = asf->duration + PREROLL_TIME * 10000;
- has_title = (s->title[0] || s->author[0] || s->copyright[0] || s->comment[0]);
+ has_title = title || author || copyright || comment;
+ metadata_count = s->metadata ? s->metadata->count : 0;
bit_rate = 0;
for(n=0;n<s->nb_streams;n++) {
put_guid(pb, &asf_header);
put_le64(pb, -1); /* header length, will be patched after */
- put_le32(pb, 3 + has_title + s->nb_streams); /* number of chunks in header */
+ put_le32(pb, 3 + has_title + !!metadata_count + s->nb_streams); /* number of chunks in header */
put_byte(pb, 1); /* ??? */
put_byte(pb, 2); /* ??? */
/* title and other infos */
if (has_title) {
hpos = put_header(pb, &comment_header);
- if ( s->title[0] ) { put_le16(pb, 2 * (strlen(s->title ) + 1)); } else { put_le16(pb, 0); }
- if ( s->author[0] ) { put_le16(pb, 2 * (strlen(s->author ) + 1)); } else { put_le16(pb, 0); }
- if ( s->copyright[0] ) { put_le16(pb, 2 * (strlen(s->copyright) + 1)); } else { put_le16(pb, 0); }
- if ( s->comment[0] ) { put_le16(pb, 2 * (strlen(s->comment ) + 1)); } else { put_le16(pb, 0); }
+ put_le16(pb, title ? 2 * (strlen(title->value ) + 1) : 0);
+ put_le16(pb, author ? 2 * (strlen(author->value ) + 1) : 0);
+ put_le16(pb, copyright ? 2 * (strlen(copyright->value) + 1) : 0);
+ put_le16(pb, comment ? 2 * (strlen(comment->value ) + 1) : 0);
put_le16(pb, 0);
- if ( s->title[0] ) put_str16_nolen(pb, s->title);
- if ( s->author[0] ) put_str16_nolen(pb, s->author);
- if ( s->copyright[0] ) put_str16_nolen(pb, s->copyright);
- if ( s->comment[0] ) put_str16_nolen(pb, s->comment);
+ if (title ) put_str16_nolen(pb, title->value );
+ if (author ) put_str16_nolen(pb, author->value );
+ if (copyright) put_str16_nolen(pb, copyright->value);
+ if (comment ) put_str16_nolen(pb, comment->value );
+ end_header(pb, hpos);
+ }
+ if (metadata_count) {
+ AVMetadataTag *tag = NULL;
+ hpos = put_header(pb, &extended_content_header);
+ put_le16(pb, metadata_count);
+ while ((tag = av_metadata_get(s->metadata, "", tag, AV_METADATA_IGNORE_SUFFIX))) {
+ put_le16(pb, 2*(strlen(tag->key) + 3) + 1);
+ put_le16(pb, 'W');
+ put_le16(pb, 'M');
+ put_le16(pb, '/');
+ put_str16_nolen(pb, tag->key);
+ put_le16(pb, 0);
+ put_le16(pb, 2*strlen(tag->value) + 1);
+ put_str16_nolen(pb, tag->value);
+ }
end_header(pb, hpos);
}
asf->nb_packets = 0;
asf->last_indexed_pts = 0;
- asf->index_ptr = (ASFIndex*)av_malloc( sizeof(ASFIndex) * ASF_INDEX_BLOCK );
+ asf->index_ptr = av_malloc( sizeof(ASFIndex) * ASF_INDEX_BLOCK );
asf->nb_index_memory_alloc = ASF_INDEX_BLOCK;
asf->nb_index_count = 0;
asf->maximum_packet = 0;
ASFContext *asf = s->priv_data;
int packet_hdr_size, packet_filled_size;
+ assert(asf->packet_timestamp_end >= asf->packet_timestamp_start);
+
if (asf->is_streamed) {
put_chunk(s, 0x4424, asf->packet_size, 0);
}
// multi payloads
frag_len1 = asf->packet_size_left - PAYLOAD_HEADER_SIZE_MULTIPLE_PAYLOADS - PACKET_HEADER_MIN_SIZE - 1;
- asf->packet_timestamp_start = timestamp;
-
if(frag_len1 < payload_len && avst->codec->codec_type == CODEC_TYPE_AUDIO){
flush_packet(s);
continue;
if(codec->codec_type == CODEC_TYPE_AUDIO)
flags &= ~PKT_FLAG_KEY;
- //XXX /FIXME use duration from AVPacket (quick hack by)
pts = (pkt->pts != AV_NOPTS_VALUE) ? pkt->pts : pkt->dts;
assert(pts != AV_NOPTS_VALUE);
duration = pts * 10000;
- asf->duration= FFMAX(asf->duration, duration);
+ asf->duration= FFMAX(asf->duration, duration + pkt->duration * 10000);
packet_st = asf->nb_packets;
put_frame(s, stream, s->streams[pkt->stream_index], pkt->dts, pkt->data, pkt->size, flags);
return 0;
}
-#ifdef CONFIG_ASF_MUXER
+#if CONFIG_ASF_MUXER
AVOutputFormat asf_muxer = {
"asf",
- "asf format",
+ NULL_IF_CONFIG_SMALL("ASF format"),
"video/x-ms-asf",
"asf,wmv,wma",
sizeof(ASFContext),
-#ifdef CONFIG_LIBMP3LAME
+#if CONFIG_LIBMP3LAME
CODEC_ID_MP3,
#else
CODEC_ID_MP2,
asf_write_packet,
asf_write_trailer,
.flags = AVFMT_GLOBALHEADER,
- .codec_tag= (const AVCodecTag*[]){codec_asf_bmp_tags, codec_bmp_tags, codec_wav_tags, 0},
+ .codec_tag= (const AVCodecTag* const []){codec_asf_bmp_tags, codec_bmp_tags, codec_wav_tags, 0},
};
#endif
-#ifdef CONFIG_ASF_STREAM_MUXER
+#if CONFIG_ASF_STREAM_MUXER
AVOutputFormat asf_stream_muxer = {
"asf_stream",
- "asf format",
+ NULL_IF_CONFIG_SMALL("ASF format"),
"video/x-ms-asf",
"asf,wmv,wma",
sizeof(ASFContext),
-#ifdef CONFIG_LIBMP3LAME
+#if CONFIG_LIBMP3LAME
CODEC_ID_MP3,
#else
CODEC_ID_MP2,
asf_write_packet,
asf_write_trailer,
.flags = AVFMT_GLOBALHEADER,
- .codec_tag= (const AVCodecTag*[]){codec_asf_bmp_tags, codec_bmp_tags, codec_wav_tags, 0},
+ .codec_tag= (const AVCodecTag* const []){codec_asf_bmp_tags, codec_bmp_tags, codec_wav_tags, 0},
};
#endif //CONFIG_ASF_STREAM_MUXER