FFmpeg
Loading...
Searching...
No Matches
ttaenc.c
Go to the documentation of this file.
1/*
2 * True Audio (TTA) muxer
3 * Copyright (c) 2016 James Almer
4 *
5 * This file is part of FFmpeg.
6 *
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.
11 *
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.
16 *
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
20 */
21
22#include "libavutil/crc.h"
24
25#include "packet_internal.h"
26#include "apetag.h"
27#include "avformat.h"
28#include "avio_internal.h"
29#include "internal.h"
30#include "mux.h"
31
39
41{
42 TTAMuxContext *tta = s->priv_data;
43 AVCodecParameters *par = s->streams[0]->codecpar;
44
45 if (par->codec_id != AV_CODEC_ID_TTA) {
46 av_log(s, AV_LOG_ERROR, "Unsupported codec\n");
47 return AVERROR(EINVAL);
48 }
49 if (par->extradata && par->extradata_size < 22) {
50 av_log(s, AV_LOG_ERROR, "Invalid TTA extradata\n");
52 }
53
54 /* Prevent overflow */
55 if (par->sample_rate > 0x7FFFFFu) {
56 av_log(s, AV_LOG_ERROR, "Sample rate too large\n");
57 return AVERROR(EINVAL);
58 }
59 tta->frame_size = par->sample_rate * 256 / 245;
60 avpriv_set_pts_info(s->streams[0], 64, 1, par->sample_rate);
61
62 return 0;
63}
64
66{
67 TTAMuxContext *tta = s->priv_data;
68 AVCodecParameters *par = s->streams[0]->codecpar;
69 int ret;
70
71 if ((ret = avio_open_dyn_buf(&tta->seek_table)) < 0)
72 return ret;
73
74 /* Ignore most extradata information if present. It can be inaccurate
75 if for example remuxing from Matroska */
78 avio_write(s->pb, "TTA1", 4);
79 avio_wl16(s->pb, par->extradata ? AV_RL16(par->extradata + 4) : 1);
82 avio_wl32(s->pb, par->sample_rate);
83
84 return 0;
85}
86
88{
89 TTAMuxContext *tta = s->priv_data;
90 int ret;
91
92 ret = ff_packet_list_put(&tta->queue, pkt, NULL, 0);
93 if (ret < 0) {
94 return ret;
95 }
96 pkt = &tta->queue.tail->pkt;
97
98 avio_wl32(tta->seek_table, pkt->size);
99 tta->nb_samples += pkt->duration;
100
101 if (tta->frame_size != pkt->duration) {
102 if (tta->last_frame) {
103 /* Two frames with a different duration than the default frame
104 size means the TTA stream comes from a faulty container, and
105 there's no way the last frame duration will be correct. */
106 av_log(s, AV_LOG_ERROR, "Invalid frame durations\n");
107
108 return AVERROR_INVALIDDATA;
109 }
110 /* First frame with a different duration than the default frame size.
111 Assume it's the last frame in the stream and continue. */
112 tta->last_frame++;
113 }
114
115 return 0;
116}
117
119{
120 TTAMuxContext *tta = s->priv_data;
121 AVPacket *const pkt = ffformatcontext(s)->pkt;
122
123 while (tta->queue.head) {
125 avio_write(s->pb, pkt->data, pkt->size);
127 }
128}
129
131{
132 TTAMuxContext *tta = s->priv_data;
133 uint8_t *ptr;
134 unsigned int crc;
135 int size;
136
137 avio_wl32(s->pb, tta->nb_samples);
138 crc = ffio_get_checksum(s->pb) ^ UINT32_MAX;
139 avio_wl32(s->pb, crc);
140
141 /* Write Seek table */
142 crc = ffio_get_checksum(tta->seek_table) ^ UINT32_MAX;
143 avio_wl32(tta->seek_table, crc);
144 size = avio_get_dyn_buf(tta->seek_table, &ptr);
145 avio_write(s->pb, ptr, size);
146
147 /* Write audio data */
149
151
152 return 0;
153}
154
156{
157 TTAMuxContext *tta = s->priv_data;
158
161}
162
164 .p.name = "tta",
165 .p.long_name = NULL_IF_CONFIG_SMALL("TTA (True Audio)"),
166 .p.mime_type = "audio/x-tta",
167 .p.extensions = "tta",
168 .priv_data_size = sizeof(TTAMuxContext),
169 .p.audio_codec = AV_CODEC_ID_TTA,
170 .p.video_codec = AV_CODEC_ID_NONE,
171 .p.subtitle_codec = AV_CODEC_ID_NONE,
172 .flags_internal = FF_OFMT_FLAG_MAX_ONE_OF_EACH |
174 .init = tta_init,
175 .deinit = tta_deinit,
176 .write_header = tta_write_header,
177 .write_packet = tta_write_packet,
178 .write_trailer = tta_write_trailer,
179};
const FFOutputFormat ff_tta_muxer
Definition ttaenc.c:163
int ff_ape_write_tag(AVFormatContext *s)
Write an APE tag into a file.
Definition apetag.c:178
void avpriv_set_pts_info(AVStream *st, int pts_wrap_bits, unsigned int pts_num, unsigned int pts_den)
Set the time base and wrapping info for a given stream.
Definition avformat.c:834
Main libavformat public API header.
void avio_wl32(AVIOContext *s, unsigned int val)
Definition aviobuf.c:360
void avio_wl16(AVIOContext *s, unsigned int val)
Definition aviobuf.c:440
void avio_write(AVIOContext *s, const unsigned char *buf, int size)
Definition aviobuf.c:206
int avio_open_dyn_buf(AVIOContext **s)
Open a write only memory stream.
Definition aviobuf.c:1365
int avio_get_dyn_buf(AVIOContext *s, uint8_t **pbuffer)
Return the written size and a pointer to the buffer.
Definition aviobuf.c:1377
void ffio_init_checksum(AVIOContext *s, unsigned long(*update_checksum)(unsigned long c, const uint8_t *p, unsigned int len), unsigned long checksum)
Definition aviobuf.c:594
void ffio_free_dyn_buf(AVIOContext **s)
Free a dynamic buffer.
Definition aviobuf.c:1438
unsigned long ffio_get_checksum(AVIOContext *s)
Definition aviobuf.c:586
unsigned long ff_crcEDB88320_update(unsigned long checksum, const uint8_t *buf, unsigned int len)
Definition aviobuf.c:574
#define s(width, name)
Definition cbs_vp9.c:198
#define NULL
Definition coverity.c:32
Public header for CRC hash function implementation.
static AVPacket * pkt
@ AV_CODEC_ID_NONE
Definition codec_id.h:48
@ AV_CODEC_ID_TTA
Definition codec_id.h:475
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
Definition packet.c:434
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition error.h:61
#define AVERROR(e)
Definition error.h:45
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition log.h:210
#define AV_RL16(p)
static av_always_inline FFFormatContext * ffformatcontext(AVFormatContext *s)
Definition internal.h:130
int ff_packet_list_get(PacketList *list, AVPacket *pkt)
Remove the oldest AVPacket in the list and return it.
Definition packet_list.c:89
void ff_packet_list_free(PacketList *list)
Wipe the list and unref all the packets in it.
int ff_packet_list_put(PacketList *list, AVPacket *pkt, int(*copy)(AVPacket *dst, const AVPacket *src), int flags)
Append an AVPacket to the list.
Definition packet_list.c:40
static void tta_queue_flush(AVFormatContext *s)
Definition ttaenc.c:118
static int tta_write_packet(AVFormatContext *s, AVPacket *pkt)
Definition ttaenc.c:87
static int tta_write_header(AVFormatContext *s)
Definition ttaenc.c:65
static int tta_write_trailer(AVFormatContext *s)
Definition ttaenc.c:130
static int tta_init(AVFormatContext *s)
Definition ttaenc.c:40
static void tta_deinit(AVFormatContext *s)
Definition ttaenc.c:155
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition internal.h:88
#define FF_OFMT_FLAG_MAX_ONE_OF_EACH
If this flag is set, it indicates that for each codec type whose corresponding default codec (i....
Definition mux.h:50
#define FF_OFMT_FLAG_ONLY_DEFAULT_CODECS
If this flag is set, then the only permitted audio/video/subtitle codec ids are AVOutputFormat....
Definition mux.h:59
int nb_channels
Number of channels in this layout.
This struct describes the properties of an encoded stream.
Definition codec_par.h:49
int extradata_size
Size of the extradata content in bytes.
Definition codec_par.h:75
AVChannelLayout ch_layout
The channel layout and number of channels.
Definition codec_par.h:207
int bits_per_raw_sample
The number of valid bits in each output sample.
Definition codec_par.h:130
uint8_t * extradata
Extra binary data needed for initializing the decoder, codec-dependent.
Definition codec_par.h:71
enum AVCodecID codec_id
Specific type of the encoded data (the codec used).
Definition codec_par.h:57
int sample_rate
The number of audio samples per second.
Definition codec_par.h:213
Format I/O context.
Definition avformat.h:1333
Bytestream IO Context.
Definition avio.h:160
This structure stores compressed data.
Definition packet.h:580
AVPacket * pkt
Used to hold temporary packets for the generic demuxing code.
Definition internal.h:111
PacketListEntry * tail
PacketListEntry * head
AVIOContext * seek_table
Definition ttaenc.c:33
PacketList queue
Definition ttaenc.c:34
int last_frame
Definition ttaenc.c:37
int frame_size
Definition ttaenc.c:36
uint32_t nb_samples
Definition ttaenc.c:35
#define av_log(a,...)
int size