3 * Copyright (c) 2013 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 "libavcodec/bytestream.h"
23 #include "libavutil/intreadwrite.h"
28 #define HEADER_SIZE 4096
29 #define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
31 typedef struct RedSparkContext
{
35 static int redspark_probe(AVProbeData
*p
)
40 /* Decrypt first 8 bytes of the header */
41 data
= AV_RB32(p
->buf
);
42 key
= data
^ 0x52656453;
44 AV_WB32(header
, data
);
48 data
= AV_RB32(p
->buf
+ 4) ^ key
;
49 AV_WB32(header
+ 4, data
);
51 if (AV_RB64(header
) == AV_RB64("RedSpark"))
52 return AVPROBE_SCORE_MAX
;
57 static int redspark_read_header(AVFormatContext
*s
)
59 AVIOContext
*pb
= s
->pb
;
60 RedSparkContext
*redspark
= s
->priv_data
;
61 AVCodecParameters
*par
;
63 int i
, coef_off
, ret
= 0;
65 uint8_t header
[HEADER_SIZE
];
68 st
= avformat_new_stream(s
, NULL
);
70 return AVERROR(ENOMEM
);
75 key
= data
^ 0x52656453;
77 AV_WB32(header
, data
);
80 for (i
= 4; i
< HEADER_SIZE
; i
+= 4) {
82 data
= avio_rb32(pb
) ^ key
;
83 AV_WB32(header
+ i
, data
);
86 par
->codec_id
= AV_CODEC_ID_ADPCM_THP
;
87 par
->codec_type
= AVMEDIA_TYPE_AUDIO
;
89 bytestream2_init(&gbc
, header
, HEADER_SIZE
);
90 bytestream2_seek(&gbc
, 0x3c, SEEK_SET
);
91 par
->sample_rate
= bytestream2_get_be32u(&gbc
);
92 if (par
->sample_rate
<= 0 || par
->sample_rate
> 96000) {
93 av_log(s
, AV_LOG_ERROR
, "Invalid sample rate: %d\n", par
->sample_rate
);
94 return AVERROR_INVALIDDATA
;
97 st
->duration
= bytestream2_get_be32u(&gbc
) * 14;
98 redspark
->samples_count
= 0;
99 bytestream2_skipu(&gbc
, 10);
100 par
->channels
= bytestream2_get_byteu(&gbc
);
101 if (!par
->channels
) {
102 return AVERROR_INVALIDDATA
;
105 coef_off
= 0x54 + par
->channels
* 8;
106 if (bytestream2_get_byteu(&gbc
)) // Loop flag
109 if (coef_off
+ par
->channels
* (32 + 14) > HEADER_SIZE
) {
110 return AVERROR_INVALIDDATA
;
113 if (ff_alloc_extradata(par
, 32 * par
->channels
)) {
114 return AVERROR_INVALIDDATA
;
117 /* Get the ADPCM table */
118 bytestream2_seek(&gbc
, coef_off
, SEEK_SET
);
119 for (i
= 0; i
< par
->channels
; i
++) {
120 if (bytestream2_get_bufferu(&gbc
, par
->extradata
+ i
* 32, 32) != 32) {
121 return AVERROR_INVALIDDATA
;
123 bytestream2_skipu(&gbc
, 14);
126 avpriv_set_pts_info(st
, 64, 1, par
->sample_rate
);
131 static int redspark_read_packet(AVFormatContext
*s
, AVPacket
*pkt
)
133 AVCodecParameters
*par
= s
->streams
[0]->codecpar
;
134 RedSparkContext
*redspark
= s
->priv_data
;
135 uint32_t size
= 8 * par
->channels
;
138 if (avio_feof(s
->pb
) || redspark
->samples_count
== s
->streams
[0]->duration
)
141 ret
= av_get_packet(s
->pb
, pkt
, size
);
143 av_packet_unref(pkt
);
148 redspark
->samples_count
+= pkt
->duration
;
149 pkt
->stream_index
= 0;
154 AVInputFormat ff_redspark_demuxer
= {
156 .long_name
= NULL_IF_CONFIG_SMALL("RedSpark"),
157 .priv_data_size
= sizeof(RedSparkContext
),
158 .read_probe
= redspark_probe
,
159 .read_header
= redspark_read_header
,
160 .read_packet
= redspark_read_packet
,