2 * Copyright (c) 2011 Justin Ruggles
4 * This file is part of Libav.
6 * Libav is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * Libav is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with Libav; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
26 #include "libavutil/intreadwrite.h"
27 #include "libavcodec/adx.h"
32 #define BLOCK_SAMPLES 32
34 typedef struct ADXDemuxerContext
{
38 static int adx_read_packet(AVFormatContext
*s
, AVPacket
*pkt
)
40 ADXDemuxerContext
*c
= s
->priv_data
;
41 AVCodecContext
*avctx
= s
->streams
[0]->codec
;
44 size
= BLOCK_SIZE
* avctx
->channels
;
46 pkt
->pos
= avio_tell(s
->pb
);
47 pkt
->stream_index
= 0;
49 ret
= av_get_packet(s
->pb
, pkt
, size
);
52 return ret
< 0 ? ret
: AVERROR(EIO
);
54 if (AV_RB16(pkt
->data
) & 0x8000) {
60 pkt
->pts
= (pkt
->pos
- c
->header_size
) / size
;
65 static int adx_read_header(AVFormatContext
*s
, AVFormatParameters
*ap
)
67 ADXDemuxerContext
*c
= s
->priv_data
;
68 AVCodecContext
*avctx
;
71 AVStream
*st
= avformat_new_stream(s
, NULL
);
73 return AVERROR(ENOMEM
);
74 avctx
= s
->streams
[0]->codec
;
76 if (avio_rb16(s
->pb
) != 0x8000)
77 return AVERROR_INVALIDDATA
;
78 c
->header_size
= avio_rb16(s
->pb
) + 4;
79 avio_seek(s
->pb
, -4, SEEK_CUR
);
81 avctx
->extradata
= av_mallocz(c
->header_size
+ FF_INPUT_BUFFER_PADDING_SIZE
);
82 if (!avctx
->extradata
)
83 return AVERROR(ENOMEM
);
84 if (avio_read(s
->pb
, avctx
->extradata
, c
->header_size
) < c
->header_size
) {
85 av_freep(&avctx
->extradata
);
88 avctx
->extradata_size
= c
->header_size
;
90 ret
= avpriv_adx_decode_header(avctx
, avctx
->extradata
,
91 avctx
->extradata_size
, &c
->header_size
,
96 st
->codec
->codec_type
= AVMEDIA_TYPE_AUDIO
;
97 st
->codec
->codec_id
= s
->iformat
->value
;
99 avpriv_set_pts_info(st
, 64, BLOCK_SAMPLES
, avctx
->sample_rate
);
104 AVInputFormat ff_adx_demuxer
= {
106 .long_name
= NULL_IF_CONFIG_SMALL("CRI ADX"),
107 .priv_data_size
= sizeof(ADXDemuxerContext
),
108 .read_header
= adx_read_header
,
109 .read_packet
= adx_read_packet
,
111 .value
= CODEC_ID_ADPCM_ADX
,