FFmpeg
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
genh.c
Go to the documentation of this file.
1 /*
2  * GENH demuxer
3  * Copyright (c) 2015 Paul B Mahol
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/intreadwrite.h"
23 #include "avformat.h"
24 #include "internal.h"
25 
26 typedef struct GENHDemuxContext {
27  unsigned dsp_int_type;
28  unsigned interleave_size;
30 
31 static int genh_probe(AVProbeData *p)
32 {
33  if (AV_RL32(p->buf) != MKTAG('G','E','N','H'))
34  return 0;
35  if (AV_RL32(p->buf+4) <= 0 || AV_RL32(p->buf+4) > 0xFFFF) // channels
36  return 0;
37 
38  return AVPROBE_SCORE_MAX / 3 * 2;
39 }
40 
42 {
43  unsigned start_offset, header_size, codec, coef_type, coef[2];
45  av_unused unsigned coef_splitted[2];
46  int align, ch, ret;
47  AVStream *st;
48 
49  avio_skip(s->pb, 4);
50 
51  st = avformat_new_stream(s, NULL);
52  if (!st)
53  return AVERROR(ENOMEM);
54 
56  st->codec->channels = avio_rl32(s->pb);
57  if (st->codec->channels <= 0)
58  return AVERROR_INVALIDDATA;
59  if (st->codec->channels == 1)
61  else if (st->codec->channels == 2)
63  align =
64  c->interleave_size = avio_rl32(s->pb);
65  if (align < 0 || align > INT_MAX / st->codec->channels)
66  return AVERROR_INVALIDDATA;
67  st->codec->block_align = align * st->codec->channels;
68  st->codec->sample_rate = avio_rl32(s->pb);
69  avio_skip(s->pb, 4);
70  st->duration = avio_rl32(s->pb);
71 
72  codec = avio_rl32(s->pb);
73  switch (codec) {
74  case 0: st->codec->codec_id = AV_CODEC_ID_ADPCM_PSX; break;
75  case 1:
76  case 11: st->codec->bits_per_coded_sample = 4;
77  st->codec->block_align = 36 * st->codec->channels;
79  case 2: st->codec->codec_id = AV_CODEC_ID_ADPCM_DTK; break;
80  case 3: st->codec->codec_id = st->codec->block_align > 0 ?
82  AV_CODEC_ID_PCM_S16BE; break;
83  case 4: st->codec->codec_id = st->codec->block_align > 0 ?
85  AV_CODEC_ID_PCM_S16LE; break;
86  case 5: st->codec->codec_id = st->codec->block_align > 0 ?
88  AV_CODEC_ID_PCM_S8; break;
89  case 6: st->codec->codec_id = AV_CODEC_ID_SDX2_DPCM; break;
90  case 7: ret = ff_alloc_extradata(st->codec, 2);
91  if (ret < 0)
92  return ret;
93  AV_WL16(st->codec->extradata, 3);
95  case 10: st->codec->codec_id = AV_CODEC_ID_ADPCM_AICA; break;
96  case 12: st->codec->codec_id = AV_CODEC_ID_ADPCM_THP; break;
97  case 13: st->codec->codec_id = AV_CODEC_ID_PCM_U8; break;
98  case 17: st->codec->codec_id = AV_CODEC_ID_ADPCM_IMA_QT; break;
99  default:
100  avpriv_request_sample(s, "codec %d", codec);
101  return AVERROR_PATCHWELCOME;
102  }
103 
104  start_offset = avio_rl32(s->pb);
105  header_size = avio_rl32(s->pb);
106 
107  if (header_size > start_offset)
108  return AVERROR_INVALIDDATA;
109 
110  if (header_size == 0)
111  start_offset = 0x800;
112 
113  coef[0] = avio_rl32(s->pb);
114  coef[1] = avio_rl32(s->pb);
115  c->dsp_int_type = avio_rl32(s->pb);
116  coef_type = avio_rl32(s->pb);
117  coef_splitted[0] = avio_rl32(s->pb);
118  coef_splitted[1] = avio_rl32(s->pb);
119 
120  if (st->codec->codec_id == AV_CODEC_ID_ADPCM_THP) {
121  if (st->codec->channels > 2) {
122  avpriv_request_sample(s, "channels %d>2", st->codec->channels);
123  return AVERROR_PATCHWELCOME;
124  }
125 
126  ff_alloc_extradata(st->codec, 32 * st->codec->channels);
127  for (ch = 0; ch < st->codec->channels; ch++) {
128  if (coef_type & 1) {
129  avpriv_request_sample(s, "coef_type & 1");
130  return AVERROR_PATCHWELCOME;
131  } else {
132  avio_seek(s->pb, coef[ch], SEEK_SET);
133  avio_read(s->pb, st->codec->extradata + 32 * ch, 32);
134  }
135  }
136 
137  if (c->dsp_int_type == 1) {
138  st->codec->block_align = 8 * st->codec->channels;
139  if (c->interleave_size != 1 &&
140  c->interleave_size != 2 &&
141  c->interleave_size != 4)
142  return AVERROR_INVALIDDATA;
143  }
144  }
145 
146  avio_skip(s->pb, start_offset - avio_tell(s->pb));
147 
148  avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate);
149 
150  return 0;
151 }
152 
154 {
155  AVCodecContext *codec = s->streams[0]->codec;
157  int ret;
158 
159  if (c->dsp_int_type == 1 && codec->codec_id == AV_CODEC_ID_ADPCM_THP &&
160  codec->channels > 1) {
161  int i, ch;
162 
163  if (avio_feof(s->pb))
164  return AVERROR_EOF;
165  ret = av_new_packet(pkt, 8 * codec->channels);
166  if (ret < 0)
167  return ret;
168  for (i = 0; i < 8 / c->interleave_size; i++) {
169  for (ch = 0; ch < codec->channels; ch++) {
170  pkt->data[ch * 8 + i*c->interleave_size+0] = avio_r8(s->pb);
171  pkt->data[ch * 8 + i*c->interleave_size+1] = avio_r8(s->pb);
172  }
173  }
174  ret = 0;
175  } else if (codec->codec_id == AV_CODEC_ID_SDX2_DPCM) {
176  ret = av_get_packet(s->pb, pkt, codec->block_align * 1024);
177 
178  } else {
179  ret = av_get_packet(s->pb, pkt, codec->block_align ? codec->block_align : 1024 * codec->channels);
180  }
181 
182  pkt->stream_index = 0;
183  return ret;
184 }
185 
187  .name = "genh",
188  .long_name = NULL_IF_CONFIG_SMALL("GENeric Header"),
189  .priv_data_size = sizeof(GENHDemuxContext),
193  .extensions = "genh",
194 };
#define NULL
Definition: coverity.c:32
const char * s
Definition: avisynth_c.h:631
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:59
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:4149
static int genh_probe(AVProbeData *p)
Definition: genh.c:31
unsigned interleave_size
Definition: genh.c:28
int64_t avio_seek(AVIOContext *s, int64_t offset, int whence)
fseek() equivalent for AVIOContext.
Definition: aviobuf.c:208
int64_t avio_skip(AVIOContext *s, int64_t offset)
Skip given number of bytes forward.
Definition: aviobuf.c:282
static AVPacket pkt
#define AV_CH_LAYOUT_STEREO
unsigned dsp_int_type
Definition: genh.c:27
int block_align
number of bytes per packet if constant and known or 0 Used by some WAV based audio codecs...
Definition: avcodec.h:2324
Format I/O context.
Definition: avformat.h:1314
void void avpriv_request_sample(void *avc, const char *msg,...) av_printf_format(2
Log a generic warning message about a missing feature.
uint8_t * extradata
some codecs need / can use extradata like Huffman tables.
Definition: avcodec.h:1647
AVStream * avformat_new_stream(AVFormatContext *s, const AVCodec *c)
Add a new stream to a media file.
Definition: utils.c:3805
AVStream ** streams
A list of all streams in the file.
Definition: avformat.h:1382
uint8_t * data
Definition: avcodec.h:1467
AVInputFormat ff_genh_demuxer
Definition: genh.c:186
#define AVERROR_EOF
End of file.
Definition: error.h:55
int av_get_packet(AVIOContext *s, AVPacket *pkt, int size)
Allocate and read the payload of a packet and initialize its fields with default values.
Definition: utils.c:252
static av_always_inline int64_t avio_tell(AVIOContext *s)
ftell() equivalent for AVIOContext.
Definition: avio.h:442
int bits_per_coded_sample
bits per sample/pixel from the demuxer (needed for huffyuv).
Definition: avcodec.h:2917
int avio_read(AVIOContext *s, unsigned char *buf, int size)
Read size bytes from AVIOContext into buf.
Definition: aviobuf.c:545
int av_new_packet(AVPacket *pkt, int size)
Allocate the payload of a packet and initialize its fields with default values.
Definition: avpacket.c:86
unsigned int avio_rl32(AVIOContext *s)
Definition: aviobuf.c:667
#define AVERROR(e)
Definition: error.h:43
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Definition: internal.h:176
uint64_t channel_layout
Audio channel layout.
Definition: avcodec.h:2338
int avio_r8(AVIOContext *s)
Definition: aviobuf.c:536
AVCodecContext * codec
Codec context associated with this stream.
Definition: avformat.h:896
unsigned char * buf
Buffer must have AVPROBE_PADDING_SIZE of extra allocated bytes filled with zero.
Definition: avformat.h:462
static int read_probe(AVProbeData *pd)
Definition: jvdec.c:55
static int read_header(FFV1Context *f)
Definition: ffv1dec.c:638
Stream structure.
Definition: avformat.h:877
#define AVERROR_PATCHWELCOME
Not yet implemented in FFmpeg, patches welcome.
Definition: error.h:62
static int read_packet(void *opaque, uint8_t *buf, int buf_size)
Definition: avio_reading.c:42
const AVS_VideoInfo int align
Definition: avisynth_c.h:658
static int genh_read_packet(AVFormatContext *s, AVPacket *pkt)
Definition: genh.c:153
enum AVMediaType codec_type
Definition: avcodec.h:1540
enum AVCodecID codec_id
Definition: avcodec.h:1549
int sample_rate
samples per second
Definition: avcodec.h:2287
AVIOContext * pb
I/O context.
Definition: avformat.h:1356
main external API structure.
Definition: avcodec.h:1532
int ff_alloc_extradata(AVCodecContext *avctx, int size)
Allocate extradata with additional AV_INPUT_BUFFER_PADDING_SIZE at end which is always set to 0...
Definition: utils.c:2979
This structure contains the data a format has to probe a file.
Definition: avformat.h:460
int64_t duration
Decoding: duration of the stream, in stream time base.
Definition: avformat.h:936
#define AVPROBE_SCORE_MAX
maximum score
Definition: avformat.h:472
Main libavformat public API header.
static double c[64]
#define AV_WL16(p, v)
Definition: intreadwrite.h:412
static int genh_read_header(AVFormatContext *s)
Definition: genh.c:41
int channels
number of audio channels
Definition: avcodec.h:2288
void * priv_data
Format private data.
Definition: avformat.h:1342
const char * name
A comma separated list of short names for the format.
Definition: avformat.h:661
int avio_feof(AVIOContext *s)
feof() equivalent for AVIOContext.
Definition: aviobuf.c:306
int stream_index
Definition: avcodec.h:1469
#define AV_CH_LAYOUT_MONO
#define MKTAG(a, b, c, d)
Definition: common.h:342
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_RL32
Definition: bytestream.h:87
This structure stores compressed data.
Definition: avcodec.h:1444
#define av_unused
Definition: attributes.h:126