FFmpeg  4.4.6
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"
23 #include "libavutil/intreadwrite.h"
24 
26 #include "apetag.h"
27 #include "avformat.h"
28 #include "avio_internal.h"
29 #include "internal.h"
30 
31 typedef struct TTAMuxContext {
34  uint32_t nb_samples;
38 
40 {
41  TTAMuxContext *tta = s->priv_data;
42  AVCodecParameters *par;
43 
44  if (s->nb_streams != 1) {
45  av_log(s, AV_LOG_ERROR, "Only one stream is supported\n");
46  return AVERROR(EINVAL);
47  }
48  par = s->streams[0]->codecpar;
49 
50  if (par->codec_id != AV_CODEC_ID_TTA) {
51  av_log(s, AV_LOG_ERROR, "Unsupported codec\n");
52  return AVERROR(EINVAL);
53  }
54  if (par->extradata && par->extradata_size < 22) {
55  av_log(s, AV_LOG_ERROR, "Invalid TTA extradata\n");
56  return AVERROR_INVALIDDATA;
57  }
58 
59  /* Prevent overflow */
60  if (par->sample_rate > 0x7FFFFFu) {
61  av_log(s, AV_LOG_ERROR, "Sample rate too large\n");
62  return AVERROR(EINVAL);
63  }
64  tta->frame_size = par->sample_rate * 256 / 245;
65  avpriv_set_pts_info(s->streams[0], 64, 1, par->sample_rate);
66 
67  return 0;
68 }
69 
71 {
72  TTAMuxContext *tta = s->priv_data;
73  AVCodecParameters *par = s->streams[0]->codecpar;
74  int ret;
75 
76  if ((ret = avio_open_dyn_buf(&tta->seek_table)) < 0)
77  return ret;
78 
79  /* Ignore most extradata information if present. It can be innacurate
80  if for example remuxing from Matroska */
81  ffio_init_checksum(s->pb, ff_crcEDB88320_update, UINT32_MAX);
83  avio_write(s->pb, "TTA1", 4);
84  avio_wl16(s->pb, par->extradata ? AV_RL16(par->extradata + 4) : 1);
85  avio_wl16(s->pb, par->channels);
86  avio_wl16(s->pb, par->bits_per_raw_sample);
87  avio_wl32(s->pb, par->sample_rate);
88 
89  return 0;
90 }
91 
93 {
94  TTAMuxContext *tta = s->priv_data;
95  int ret;
96 
97  ret = avpriv_packet_list_put(&tta->queue, &tta->queue_end, pkt,
98  av_packet_ref, 0);
99  if (ret < 0) {
100  return ret;
101  }
102 
103  avio_wl32(tta->seek_table, pkt->size);
104  tta->nb_samples += pkt->duration;
105 
106  if (tta->frame_size != pkt->duration) {
107  if (tta->last_frame) {
108  /* Two frames with a different duration than the default frame
109  size means the TTA stream comes from a faulty container, and
110  there's no way the last frame duration will be correct. */
111  av_log(s, AV_LOG_ERROR, "Invalid frame durations\n");
112 
113  return AVERROR_INVALIDDATA;
114  }
115  /* First frame with a different duration than the default frame size.
116  Assume it's the last frame in the stream and continue. */
117  tta->last_frame++;
118  }
119 
120  return 0;
121 }
122 
124 {
125  TTAMuxContext *tta = s->priv_data;
126  AVPacket pkt;
127 
128  while (tta->queue) {
129  avpriv_packet_list_get(&tta->queue, &tta->queue_end, &pkt);
130  avio_write(s->pb, pkt.data, pkt.size);
132  }
133 }
134 
136 {
137  TTAMuxContext *tta = s->priv_data;
138  uint8_t *ptr;
139  unsigned int crc;
140  int size;
141 
142  avio_wl32(s->pb, tta->nb_samples);
143  crc = ffio_get_checksum(s->pb) ^ UINT32_MAX;
144  avio_wl32(s->pb, crc);
145 
146  /* Write Seek table */
147  crc = ffio_get_checksum(tta->seek_table) ^ UINT32_MAX;
148  avio_wl32(tta->seek_table, crc);
149  size = avio_get_dyn_buf(tta->seek_table, &ptr);
150  avio_write(s->pb, ptr, size);
151 
152  /* Write audio data */
154 
156 
157  return 0;
158 }
159 
161 {
162  TTAMuxContext *tta = s->priv_data;
163 
166 }
167 
169  .name = "tta",
170  .long_name = NULL_IF_CONFIG_SMALL("TTA (True Audio)"),
171  .mime_type = "audio/x-tta",
172  .extensions = "tta",
173  .priv_data_size = sizeof(TTAMuxContext),
174  .audio_codec = AV_CODEC_ID_TTA,
175  .video_codec = AV_CODEC_ID_NONE,
176  .init = tta_init,
177  .deinit = tta_deinit,
181 };
int ff_ape_write_tag(AVFormatContext *s)
Write an APE tag into a file.
Definition: apetag.c:186
uint8_t
Main libavformat public API header.
void avio_wl32(AVIOContext *s, unsigned int val)
Definition: aviobuf.c:375
void avio_wl16(AVIOContext *s, unsigned int val)
Definition: aviobuf.c:455
void avio_write(AVIOContext *s, const unsigned char *buf, int size)
Definition: aviobuf.c:225
int avio_open_dyn_buf(AVIOContext **s)
Open a write only memory stream.
Definition: aviobuf.c:1382
int avio_get_dyn_buf(AVIOContext *s, uint8_t **pbuffer)
Return the written size and a pointer to the buffer.
Definition: aviobuf.c:1394
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:612
void ffio_free_dyn_buf(AVIOContext **s)
Free a dynamic buffer.
Definition: aviobuf.c:1457
unsigned long ffio_get_checksum(AVIOContext *s)
Definition: aviobuf.c:604
unsigned long ff_crcEDB88320_update(unsigned long checksum, const uint8_t *buf, unsigned int len)
Definition: aviobuf.c:592
void avpriv_packet_list_free(PacketList **pkt_buf, PacketList **pkt_buf_end)
Wipe the list and unref all the packets in it.
Definition: avpacket.c:806
int avpriv_packet_list_get(PacketList **pkt_buffer, PacketList **pkt_buffer_end, AVPacket *pkt)
Remove the oldest AVPacket in the list and return it.
Definition: avpacket.c:790
int avpriv_packet_list_put(PacketList **packet_buffer, PacketList **plast_pktl, AVPacket *pkt, int(*copy)(AVPacket *dst, const AVPacket *src), int flags)
Append an AVPacket to the list.
Definition: avpacket.c:753
#define AV_RL16
Definition: intreadwrite.h:42
static av_cold int init(AVCodecContext *avctx)
Definition: avrndec.c:31
#define s(width, name)
Definition: cbs_vp9.c:257
Public header for CRC hash function implementation.
static void write_packet(OutputFile *of, AVPacket *pkt, OutputStream *ost, int unqueue)
Definition: ffmpeg.c:730
static void write_header(FFV1Context *f)
Definition: ffv1enc.c:346
@ AV_CODEC_ID_NONE
Definition: codec_id.h:47
@ AV_CODEC_ID_TTA
Definition: codec_id.h:446
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
Definition: avpacket.c:634
int av_packet_ref(AVPacket *dst, const AVPacket *src)
Setup a new reference to the data described by a given packet.
Definition: avpacket.c:641
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:59
#define AVERROR(e)
Definition: error.h:43
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:194
void avpriv_set_pts_info(AVStream *s, int pts_wrap_bits, unsigned int pts_num, unsigned int pts_den)
Set the time base and wrapping info for a given stream.
Definition: utils.c:4945
static void tta_queue_flush(AVFormatContext *s)
Definition: ttaenc.c:123
static int tta_write_packet(AVFormatContext *s, AVPacket *pkt)
Definition: ttaenc.c:92
static int tta_write_header(AVFormatContext *s)
Definition: ttaenc.c:70
AVOutputFormat ff_tta_muxer
Definition: ttaenc.c:168
static int tta_write_trailer(AVFormatContext *s)
Definition: ttaenc.c:135
static int tta_init(AVFormatContext *s)
Definition: ttaenc.c:39
static void tta_deinit(AVFormatContext *s)
Definition: ttaenc.c:160
common internal API header
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition: internal.h:117
This struct describes the properties of an encoded stream.
Definition: codec_par.h:52
int extradata_size
Size of the extradata content in bytes.
Definition: codec_par.h:78
int channels
Audio only.
Definition: codec_par.h:166
int bits_per_raw_sample
This is the number of valid bits in each output sample.
Definition: codec_par.h:115
uint8_t * extradata
Extra binary data needed for initializing the decoder, codec-dependent.
Definition: codec_par.h:74
enum AVCodecID codec_id
Specific type of the encoded data (the codec used).
Definition: codec_par.h:60
int sample_rate
Audio only.
Definition: codec_par.h:170
Format I/O context.
Definition: avformat.h:1232
Bytestream IO Context.
Definition: avio.h:161
const char * name
Definition: avformat.h:491
This structure stores compressed data.
Definition: packet.h:346
int size
Definition: packet.h:370
int64_t duration
Duration of this packet in AVStream->time_base units, 0 if unknown.
Definition: packet.h:387
uint8_t * data
Definition: packet.h:369
AVIOContext * seek_table
Definition: ttaenc.c:32
PacketList * queue_end
Definition: ttaenc.c:33
int last_frame
Definition: ttaenc.c:36
int frame_size
Definition: ttaenc.c:35
uint32_t nb_samples
Definition: ttaenc.c:34
PacketList * queue
Definition: ttaenc.c:33
#define av_log(a,...)
AVPacket * pkt
Definition: movenc.c:59
int size
static int write_trailer(AVFormatContext *s1)
Definition: v4l2enc.c:98