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
30 typedef struct RedSparkContext
{
34 static int redspark_probe(AVProbeData
*p
)
39 /* Decrypt first 8 bytes of the header */
40 data
= AV_RB32(p
->buf
);
41 data
= data
^ (key
= data
^ 0x52656453);
42 AV_WB32(header
, data
);
43 key
= (key
<< 11) | (key
>> 21);
45 data
= AV_RB32(p
->buf
+ 4) ^ (((key
<< 3) | (key
>> 29)) + key
);
46 AV_WB32(header
+ 4, data
);
48 if (AV_RB64(header
) == AV_RB64("RedSpark"))
49 return AVPROBE_SCORE_MAX
;
54 static int redspark_read_header(AVFormatContext
*s
)
56 AVIOContext
*pb
= s
->pb
;
57 RedSparkContext
*redspark
= s
->priv_data
;
58 AVCodecContext
*codec
;
60 int i
, coef_off
, ret
= 0;
62 uint8_t *header
, *pbc
;
65 st
= avformat_new_stream(s
, NULL
);
67 return AVERROR(ENOMEM
);
70 header
= av_malloc(HEADER_SIZE
+ FF_INPUT_BUFFER_PADDING_SIZE
);
72 return AVERROR(ENOMEM
);
77 data
= data
^ (key
= data
^ 0x52656453);
78 bytestream_put_be32(&pbc
, data
);
79 key
= (key
<< 11) | (key
>> 21);
81 for (i
= 4; i
< HEADER_SIZE
; i
+= 4) {
82 data
= avio_rb32(pb
) ^ (key
= ((key
<< 3) | (key
>> 29)) + key
);
83 bytestream_put_be32(&pbc
, data
);
86 codec
->codec_id
= AV_CODEC_ID_ADPCM_THP
;
87 codec
->codec_type
= AVMEDIA_TYPE_AUDIO
;
89 bytestream2_init(&gbc
, header
, HEADER_SIZE
);
90 bytestream2_seek(&gbc
, 0x3c, SEEK_SET
);
91 codec
->sample_rate
= bytestream2_get_be32u(&gbc
);
92 if (codec
->sample_rate
<= 0 || codec
->sample_rate
> 96000) {
93 av_log(s
, AV_LOG_ERROR
, "Invalid sample rate: %d\n", codec
->sample_rate
);
94 ret
= AVERROR_INVALIDDATA
;
98 st
->duration
= bytestream2_get_be32u(&gbc
) * 14;
99 redspark
->samples_count
= 0;
100 bytestream2_skipu(&gbc
, 10);
101 codec
->channels
= bytestream2_get_byteu(&gbc
);
102 if (!codec
->channels
) {
103 ret
= AVERROR_INVALIDDATA
;
107 coef_off
= 0x54 + codec
->channels
* 8;
108 if (bytestream2_get_byteu(&gbc
)) // Loop flag
111 if (coef_off
+ codec
->channels
* (32 + 14) > HEADER_SIZE
) {
112 ret
= AVERROR_INVALIDDATA
;
116 if (ff_alloc_extradata(codec
, 32 * codec
->channels
)) {
117 ret
= AVERROR(ENOMEM
);
121 /* Get the ADPCM table */
122 bytestream2_seek(&gbc
, coef_off
, SEEK_SET
);
123 for (i
= 0; i
< codec
->channels
; i
++) {
124 if (bytestream2_get_bufferu(&gbc
, codec
->extradata
+ i
* 32, 32) != 32) {
125 ret
= AVERROR_INVALIDDATA
;
128 bytestream2_skipu(&gbc
, 14);
131 avpriv_set_pts_info(st
, 64, 1, codec
->sample_rate
);
139 static int redspark_read_packet(AVFormatContext
*s
, AVPacket
*pkt
)
141 AVCodecContext
*codec
= s
->streams
[0]->codec
;
142 RedSparkContext
*redspark
= s
->priv_data
;
143 uint32_t size
= 8 * codec
->channels
;
146 if (avio_feof(s
->pb
) || redspark
->samples_count
== s
->streams
[0]->duration
)
149 ret
= av_get_packet(s
->pb
, pkt
, size
);
156 redspark
->samples_count
+= pkt
->duration
;
157 pkt
->stream_index
= 0;
162 AVInputFormat ff_redspark_demuxer
= {
164 .long_name
= NULL_IF_CONFIG_SMALL("RedSpark"),
165 .priv_data_size
= sizeof(RedSparkContext
),
166 .read_probe
= redspark_probe
,
167 .read_header
= redspark_read_header
,
168 .read_packet
= redspark_read_packet
,