xref: /third_party/ffmpeg/libavformat/aptxdec.c (revision cabdff1a)
1/*
2 * RAW aptX demuxer
3 *
4 * Copyright (C) 2017  Aurelien Jacobs <aurel@gnuage.org>
5 *
6 * This file is part of FFmpeg.
7 *
8 * FFmpeg is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
12 *
13 * FFmpeg is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with FFmpeg; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 */
22
23#include "config_components.h"
24
25#include "libavutil/opt.h"
26#include "avformat.h"
27
28#define APTX_BLOCK_SIZE   4
29#define APTX_PACKET_SIZE  (256*APTX_BLOCK_SIZE)
30
31#define APTX_HD_BLOCK_SIZE   6
32#define APTX_HD_PACKET_SIZE  (256*APTX_HD_BLOCK_SIZE)
33
34typedef struct AptXDemuxerContext {
35    AVClass *class;
36    int sample_rate;
37} AptXDemuxerContext;
38
39static AVStream *aptx_read_header_common(AVFormatContext *s)
40{
41    AptXDemuxerContext *s1 = s->priv_data;
42    AVStream *st = avformat_new_stream(s, NULL);
43    if (!st)
44        return NULL;
45    st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
46    st->codecpar->format = AV_SAMPLE_FMT_S32P;
47    st->codecpar->ch_layout.nb_channels = 2;
48    st->codecpar->sample_rate = s1->sample_rate;
49    st->start_time = 0;
50    return st;
51}
52
53static int aptx_read_header(AVFormatContext *s)
54{
55    AVStream *st = aptx_read_header_common(s);
56    if (!st)
57        return AVERROR(ENOMEM);
58    st->codecpar->codec_id = AV_CODEC_ID_APTX;
59    st->codecpar->bits_per_coded_sample = 4;
60    st->codecpar->block_align = APTX_BLOCK_SIZE;
61    st->codecpar->frame_size = APTX_PACKET_SIZE;
62    return 0;
63}
64
65static int aptx_hd_read_header(AVFormatContext *s)
66{
67    AVStream *st = aptx_read_header_common(s);
68    if (!st)
69        return AVERROR(ENOMEM);
70    st->codecpar->codec_id = AV_CODEC_ID_APTX_HD;
71    st->codecpar->bits_per_coded_sample = 6;
72    st->codecpar->block_align = APTX_HD_BLOCK_SIZE;
73    st->codecpar->frame_size = APTX_HD_PACKET_SIZE;
74    return 0;
75}
76
77static int aptx_read_packet(AVFormatContext *s, AVPacket *pkt)
78{
79    return av_get_packet(s->pb, pkt, APTX_PACKET_SIZE);
80}
81
82static int aptx_hd_read_packet(AVFormatContext *s, AVPacket *pkt)
83{
84    return av_get_packet(s->pb, pkt, APTX_HD_PACKET_SIZE);
85}
86
87static const AVOption aptx_options[] = {
88    { "sample_rate", "", offsetof(AptXDemuxerContext, sample_rate), AV_OPT_TYPE_INT, {.i64 = 48000}, 0, INT_MAX, AV_OPT_FLAG_DECODING_PARAM },
89    { NULL },
90};
91
92static const AVClass aptx_demuxer_class = {
93    .class_name = "aptx (hd) demuxer",
94    .item_name  = av_default_item_name,
95    .option     = aptx_options,
96    .version    = LIBAVUTIL_VERSION_INT,
97};
98
99#if CONFIG_APTX_DEMUXER
100const AVInputFormat ff_aptx_demuxer = {
101    .name           = "aptx",
102    .long_name      = NULL_IF_CONFIG_SMALL("raw aptX"),
103    .extensions     = "aptx",
104    .priv_data_size = sizeof(AptXDemuxerContext),
105    .read_header    = aptx_read_header,
106    .read_packet    = aptx_read_packet,
107    .flags          = AVFMT_GENERIC_INDEX,
108    .priv_class     = &aptx_demuxer_class,
109};
110#endif
111
112#if CONFIG_APTX_HD_DEMUXER
113const AVInputFormat ff_aptx_hd_demuxer = {
114    .name           = "aptx_hd",
115    .long_name      = NULL_IF_CONFIG_SMALL("raw aptX HD"),
116    .extensions     = "aptxhd",
117    .priv_data_size = sizeof(AptXDemuxerContext),
118    .read_header    = aptx_hd_read_header,
119    .read_packet    = aptx_hd_read_packet,
120    .flags          = AVFMT_GENERIC_INDEX,
121    .priv_class     = &aptx_demuxer_class,
122};
123#endif
124