configure: Drop unused helper function test_cflags_cpp()
[libav.git] / libavformat / soxenc.c
CommitLineData
cbfe5bee
DV
1/*
2 * SoX native format muxer
3 * Copyright (c) 2009 Daniel Verkamp <daniel@drv.nu>
4 *
5 * Based on libSoX sox-fmt.c
6 * Copyright (c) 2008 robs@users.sourceforge.net
7 *
2912e87a 8 * This file is part of Libav.
cbfe5bee 9 *
2912e87a 10 * Libav is free software; you can redistribute it and/or
cbfe5bee
DV
11 * modify it under the terms of the GNU Lesser General Public
12 * License as published by the Free Software Foundation; either
13 * version 2.1 of the License, or (at your option) any later version.
14 *
2912e87a 15 * Libav is distributed in the hope that it will be useful,
cbfe5bee
DV
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Lesser General Public License for more details.
19 *
20 * You should have received a copy of the GNU Lesser General Public
2912e87a 21 * License along with Libav; if not, write to the Free Software
cbfe5bee
DV
22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23 */
24
25/**
ba87f080 26 * @file
f6f95d4e 27 * SoX native format muxer
cbfe5bee 28 * @author Daniel Verkamp
bee6d2fd 29 * @see http://wiki.multimedia.cx/index.php?title=SoX_native_intermediate_format
cbfe5bee
DV
30 */
31
32#include "libavutil/intreadwrite.h"
3383a53e 33#include "libavutil/intfloat.h"
d2d67e42 34#include "libavutil/dict.h"
cbfe5bee 35#include "avformat.h"
0abdb293 36#include "avio_internal.h"
cbfe5bee
DV
37#include "sox.h"
38
daf8cf35 39typedef struct SoXContext {
cbfe5bee
DV
40 int64_t header_size;
41} SoXContext;
42
43static int sox_write_header(AVFormatContext *s)
44{
45 SoXContext *sox = s->priv_data;
ae628ec1 46 AVIOContext *pb = s->pb;
9200514a 47 AVCodecParameters *par = s->streams[0]->codecpar;
d2d67e42 48 AVDictionaryEntry *comment;
cbfe5bee
DV
49 size_t comment_len = 0, comment_size;
50
d2d67e42 51 comment = av_dict_get(s->metadata, "comment", NULL, 0);
cbfe5bee
DV
52 if (comment)
53 comment_len = strlen(comment->value);
54 comment_size = (comment_len + 7) & ~7;
55
56 sox->header_size = SOX_FIXED_HDR + comment_size;
57
9200514a 58 if (par->codec_id == AV_CODEC_ID_PCM_S32LE) {
0abdb293 59 ffio_wfourcc(pb, ".SoX");
77eb5504
AK
60 avio_wl32(pb, sox->header_size);
61 avio_wl64(pb, 0); /* number of samples */
9200514a
AK
62 avio_wl64(pb, av_double2int(par->sample_rate));
63 avio_wl32(pb, par->channels);
77eb5504 64 avio_wl32(pb, comment_size);
9200514a 65 } else if (par->codec_id == AV_CODEC_ID_PCM_S32BE) {
0abdb293 66 ffio_wfourcc(pb, "XoS.");
77eb5504
AK
67 avio_wb32(pb, sox->header_size);
68 avio_wb64(pb, 0); /* number of samples */
9200514a
AK
69 avio_wb64(pb, av_double2int(par->sample_rate));
70 avio_wb32(pb, par->channels);
77eb5504 71 avio_wb32(pb, comment_size);
cbfe5bee
DV
72 } else {
73 av_log(s, AV_LOG_ERROR, "invalid codec; use pcm_s32le or pcm_s32be\n");
74 return -1;
75 }
76
77 if (comment_len)
77eb5504 78 avio_write(pb, comment->value, comment_len);
cbfe5bee
DV
79
80 for ( ; comment_size > comment_len; comment_len++)
77eb5504 81 avio_w8(pb, 0);
cbfe5bee 82
b7f2fdde 83 avio_flush(pb);
cbfe5bee
DV
84
85 return 0;
86}
87
88static int sox_write_packet(AVFormatContext *s, AVPacket *pkt)
89{
ae628ec1 90 AVIOContext *pb = s->pb;
77eb5504 91 avio_write(pb, pkt->data, pkt->size);
cbfe5bee
DV
92 return 0;
93}
94
95static int sox_write_trailer(AVFormatContext *s)
96{
97 SoXContext *sox = s->priv_data;
ae628ec1 98 AVIOContext *pb = s->pb;
9200514a 99 AVCodecParameters *par = s->streams[0]->codecpar;
cbfe5bee 100
83548fe8 101 if (s->pb->seekable & AVIO_SEEKABLE_NORMAL) {
cbfe5bee 102 /* update number of samples */
a2704c97 103 int64_t file_size = avio_tell(pb);
cbfe5bee 104 int64_t num_samples = (file_size - sox->header_size - 4LL) >> 2LL;
6b4aa5da 105 avio_seek(pb, 8, SEEK_SET);
9200514a 106 if (par->codec_id == AV_CODEC_ID_PCM_S32LE) {
77eb5504 107 avio_wl64(pb, num_samples);
cbfe5bee 108 } else
77eb5504 109 avio_wb64(pb, num_samples);
6b4aa5da 110 avio_seek(pb, file_size, SEEK_SET);
cbfe5bee 111
b7f2fdde 112 avio_flush(pb);
cbfe5bee
DV
113 }
114
115 return 0;
116}
117
c6610a21 118AVOutputFormat ff_sox_muxer = {
dfc2c4d9 119 .name = "sox",
6774247a 120 .long_name = NULL_IF_CONFIG_SMALL("SoX native"),
dfc2c4d9
AK
121 .extensions = "sox",
122 .priv_data_size = sizeof(SoXContext),
36ef5369
AK
123 .audio_codec = AV_CODEC_ID_PCM_S32LE,
124 .video_codec = AV_CODEC_ID_NONE,
dfc2c4d9
AK
125 .write_header = sox_write_header,
126 .write_packet = sox_write_packet,
127 .write_trailer = sox_write_trailer,
f792d3cb 128 .flags = AVFMT_NOTIMESTAMPS,
cbfe5bee 129};