diff options
author | Paul B Mahol <onemda@gmail.com> | 2012-12-28 17:40:55 +0400 |
---|---|---|
committer | Paul B Mahol <onemda@gmail.com> | 2012-12-31 11:10:57 +0400 |
commit | 9a742826443afd72c238d4920fe82cbbb0ce8007 (patch) | |
tree | a408151422c31982c4820b017ba788f034fb5206 /libavformat/wavenc.c | |
parent | fe5a2fc46c55c6c725dab92b34185dbfa3683f3f (diff) |
Sony Wave64 muxer
Signed-off-by: Paul B Mahol <onemda@gmail.com>
Diffstat (limited to 'libavformat/wavenc.c')
-rw-r--r-- | libavformat/wavenc.c | 84 |
1 files changed, 84 insertions, 0 deletions
diff --git a/libavformat/wavenc.c b/libavformat/wavenc.c index 5a4b085764..79e3713a9b 100644 --- a/libavformat/wavenc.c +++ b/libavformat/wavenc.c @@ -2,6 +2,9 @@ * WAV muxer * Copyright (c) 2001, 2002 Fabrice Bellard * + * Sony Wave64 muxer + * Copyright (c) 2012 Paul B Mahol + * * This file is part of FFmpeg. * * FFmpeg is free software; you can redistribute it and/or @@ -43,6 +46,7 @@ typedef struct WAVMuxContext { int write_bext; } WAVMuxContext; +#if CONFIG_WAV_MUXER static inline void bwf_write_bext_string(AVFormatContext *s, const char *key, int maxlen) { AVDictionaryEntry *tag; @@ -218,3 +222,83 @@ AVOutputFormat ff_wav_muxer = { .codec_tag = (const AVCodecTag* const []){ ff_codec_wav_tags, 0 }, .priv_class = &wav_muxer_class, }; +#endif /* CONFIG_WAV_MUXER */ + +#if CONFIG_W64_MUXER +#include "w64.h" + +static void start_guid(AVIOContext *pb, const uint8_t *guid, int64_t *pos) +{ + *pos = avio_tell(pb); + + avio_write(pb, guid, 16); + avio_wl64(pb, INT64_MAX); +} + +static void end_guid(AVIOContext *pb, int64_t start) +{ + int64_t end, pos = avio_tell(pb); + + end = FFALIGN(pos, 8); + ffio_fill(pb, 0, end - pos); + avio_seek(pb, start + 16, SEEK_SET); + avio_wl64(pb, end - start); + avio_seek(pb, end, SEEK_SET); +} + +static int w64_write_header(AVFormatContext *s) +{ + WAVMuxContext *wav = s->priv_data; + AVIOContext *pb = s->pb; + int64_t start; + int ret; + + avio_write(pb, ff_w64_guid_riff, sizeof(ff_w64_guid_riff)); + avio_wl64(pb, -1); + avio_write(pb, ff_w64_guid_wave, sizeof(ff_w64_guid_wave)); + start_guid(pb, ff_w64_guid_fmt, &start); + if ((ret = ff_put_wav_header(pb, s->streams[0]->codec)) < 0) { + av_log(s, AV_LOG_ERROR, "%s codec not supported\n", + s->streams[0]->codec->codec ? s->streams[0]->codec->codec->name : "NONE"); + return ret; + } + end_guid(pb, start); + start_guid(pb, ff_w64_guid_data, &wav->data); + + return 0; +} + +static int w64_write_trailer(AVFormatContext *s) +{ + AVIOContext *pb = s->pb; + WAVMuxContext *wav = s->priv_data; + int64_t file_size; + + if (pb->seekable) { + end_guid(pb, wav->data); + + file_size = avio_tell(pb); + avio_seek(pb, 16, SEEK_SET); + avio_wl64(pb, file_size); + avio_seek(pb, file_size, SEEK_SET); + + avio_flush(pb); + } + + return 0; +} + +AVOutputFormat ff_w64_muxer = { + .name = "w64", + .long_name = NULL_IF_CONFIG_SMALL("Sony Wave64"), + .extensions = "w64", + .priv_data_size = sizeof(WAVMuxContext), + .audio_codec = AV_CODEC_ID_PCM_S16LE, + .video_codec = AV_CODEC_ID_NONE, + .write_header = w64_write_header, + .write_packet = wav_write_packet, + .write_trailer = w64_write_trailer, + .flags = AVFMT_TS_NONSTRICT, + .codec_tag = (const AVCodecTag* const []){ ff_codec_wav_tags, 0 }, +}; +#endif /* CONFIG_W64_MUXER */ |