2 * True Audio (TTA) muxer
3 * Copyright (c) 2016 James Almer
5 * This file is part of FFmpeg.
7 * FFmpeg is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * FFmpeg is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with FFmpeg; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 #include "libavutil/crc.h"
23 #include "libavutil/intreadwrite.h"
27 #include "avio_internal.h"
30 typedef struct TTAMuxContext
{
31 AVIOContext
*seek_table
;
32 AVPacketList
*queue
, *queue_end
;
38 static int tta_init(AVFormatContext
*s
)
40 TTAMuxContext
*tta
= s
->priv_data
;
41 AVCodecParameters
*par
;
43 if (s
->nb_streams
!= 1) {
44 av_log(s
, AV_LOG_ERROR
, "Only one stream is supported\n");
45 return AVERROR(EINVAL
);
47 par
= s
->streams
[0]->codecpar
;
49 if (par
->codec_id
!= AV_CODEC_ID_TTA
) {
50 av_log(s
, AV_LOG_ERROR
, "Unsupported codec\n");
51 return AVERROR(EINVAL
);
53 if (par
->extradata
&& par
->extradata_size
< 22) {
54 av_log(s
, AV_LOG_ERROR
, "Invalid TTA extradata\n");
55 return AVERROR_INVALIDDATA
;
58 /* Prevent overflow */
59 if (par
->sample_rate
> 0x7FFFFFu
) {
60 av_log(s
, AV_LOG_ERROR
, "Sample rate too large\n");
61 return AVERROR(EINVAL
);
63 tta
->frame_size
= par
->sample_rate
* 256 / 245;
64 avpriv_set_pts_info(s
->streams
[0], 64, 1, par
->sample_rate
);
69 static int tta_write_header(AVFormatContext
*s
)
71 TTAMuxContext
*tta
= s
->priv_data
;
72 AVCodecParameters
*par
= s
->streams
[0]->codecpar
;
75 if ((ret
= avio_open_dyn_buf(&tta
->seek_table
)) < 0)
78 /* Ignore most extradata information if present. It can be innacurate
79 if for example remuxing from Matroska */
80 ffio_init_checksum(s
->pb
, ff_crcEDB88320_update
, UINT32_MAX
);
81 ffio_init_checksum(tta
->seek_table
, ff_crcEDB88320_update
, UINT32_MAX
);
82 avio_write(s
->pb
, "TTA1", 4);
83 avio_wl16(s
->pb
, par
->extradata
? AV_RL16(par
->extradata
+ 4) : 1);
84 avio_wl16(s
->pb
, par
->channels
);
85 avio_wl16(s
->pb
, par
->bits_per_raw_sample
);
86 avio_wl32(s
->pb
, par
->sample_rate
);
91 static int tta_write_packet(AVFormatContext
*s
, AVPacket
*pkt
)
93 TTAMuxContext
*tta
= s
->priv_data
;
96 ret
= ff_packet_list_put(&tta
->queue
, &tta
->queue_end
, pkt
,
97 FF_PACKETLIST_FLAG_REF_PACKET
);
102 avio_wl32(tta
->seek_table
, pkt
->size
);
103 tta
->nb_samples
+= pkt
->duration
;
105 if (tta
->frame_size
!= pkt
->duration
) {
106 if (tta
->last_frame
) {
107 /* Two frames with a different duration than the default frame
108 size means the TTA stream comes from a faulty container, and
109 there's no way the last frame duration will be correct. */
110 av_log(s
, AV_LOG_ERROR
, "Invalid frame durations\n");
112 return AVERROR_INVALIDDATA
;
114 /* First frame with a different duration than the default frame size.
115 Assume it's the last frame in the stream and continue. */
122 static void tta_queue_flush(AVFormatContext
*s
)
124 TTAMuxContext
*tta
= s
->priv_data
;
128 ff_packet_list_get(&tta
->queue
, &tta
->queue_end
, &pkt
);
129 avio_write(s
->pb
, pkt
.data
, pkt
.size
);
130 av_packet_unref(&pkt
);
134 static int tta_write_trailer(AVFormatContext
*s
)
136 TTAMuxContext
*tta
= s
->priv_data
;
141 avio_wl32(s
->pb
, tta
->nb_samples
);
142 crc
= ffio_get_checksum(s
->pb
) ^ UINT32_MAX
;
143 avio_wl32(s
->pb
, crc
);
145 /* Write Seek table */
146 crc
= ffio_get_checksum(tta
->seek_table
) ^ UINT32_MAX
;
147 avio_wl32(tta
->seek_table
, crc
);
148 size
= avio_get_dyn_buf(tta
->seek_table
, &ptr
);
149 avio_write(s
->pb
, ptr
, size
);
151 /* Write audio data */
159 static void tta_deinit(AVFormatContext
*s
)
161 TTAMuxContext
*tta
= s
->priv_data
;
163 ffio_free_dyn_buf(&tta
->seek_table
);
164 ff_packet_list_free(&tta
->queue
, &tta
->queue_end
);
167 AVOutputFormat ff_tta_muxer
= {
169 .long_name
= NULL_IF_CONFIG_SMALL("TTA (True Audio)"),
170 .mime_type
= "audio/x-tta",
172 .priv_data_size
= sizeof(TTAMuxContext
),
173 .audio_codec
= AV_CODEC_ID_TTA
,
174 .video_codec
= AV_CODEC_ID_NONE
,
176 .deinit
= tta_deinit
,
177 .write_header
= tta_write_header
,
178 .write_packet
= tta_write_packet
,
179 .write_trailer
= tta_write_trailer
,