FFmpeg  4.0
musx.c
Go to the documentation of this file.
1 /*
2  * MUSX demuxer
3  * Copyright (c) 2016 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/avassert.h"
23 #include "avformat.h"
24 #include "internal.h"
25 
26 static int musx_probe(AVProbeData *p)
27 {
28  if (memcmp(p->buf, "MUSX", 4))
29  return 0;
30 
31  return AVPROBE_SCORE_MAX / 5 * 2;
32 }
33 
35 {
36  unsigned type, version, coding, offset;
37  AVStream *st;
38 
39  avio_skip(s->pb, 8);
40  version = avio_rl32(s->pb);
41  if (version != 10 &&
42  version != 6 &&
43  version != 5 &&
44  version != 4 &&
45  version != 201) {
46  avpriv_request_sample(s, "Unsupported version: %d", version);
47  return AVERROR_PATCHWELCOME;
48  }
49  avio_skip(s->pb, 4);
50 
51  st = avformat_new_stream(s, NULL);
52  if (!st)
53  return AVERROR(ENOMEM);
54 
55  if (version == 201) {
56  avio_skip(s->pb, 8);
57  offset = avio_rl32(s->pb);
60  st->codecpar->channels = 2;
61  st->codecpar->sample_rate = 32000;
62  st->codecpar->block_align = 0x80 * st->codecpar->channels;
63  } else if (version == 10) {
64  type = avio_rl32(s->pb);
66  offset = 0x800;
67  switch (type) {
68  case MKTAG('P', 'S', '3', '_'):
69  st->codecpar->channels = 2;
70  st->codecpar->sample_rate = 44100;
71  avio_skip(s->pb, 44);
72  coding = avio_rl32(s->pb);
73  if (coding == MKTAG('D', 'A', 'T', '4') ||
74  coding == MKTAG('D', 'A', 'T', '8')) {
75  avio_skip(s->pb, 4);
76  st->codecpar->channels = avio_rl32(s->pb);
77  if (st->codecpar->channels <= 0 ||
78  st->codecpar->channels > INT_MAX / 0x20)
79  return AVERROR_INVALIDDATA;
80  st->codecpar->sample_rate = avio_rl32(s->pb);
81  }
83  st->codecpar->block_align = 0x20 * st->codecpar->channels;
84  break;
85  case MKTAG('W', 'I', 'I', '_'):
86  avio_skip(s->pb, 44);
87  coding = avio_rl32(s->pb);
88  if (coding != MKTAG('D', 'A', 'T', '4') &&
89  coding != MKTAG('D', 'A', 'T', '8')) {
90  avpriv_request_sample(s, "Unsupported coding: %X", coding);
91  return AVERROR_PATCHWELCOME;
92  }
93  avio_skip(s->pb, 4);
95  st->codecpar->channels = avio_rl32(s->pb);
96  if (st->codecpar->channels <= 0 ||
97  st->codecpar->channels > INT_MAX / 0x20)
98  return AVERROR_INVALIDDATA;
99  st->codecpar->sample_rate = avio_rl32(s->pb);
100  st->codecpar->block_align = 0x20 * st->codecpar->channels;
101  break;
102  case MKTAG('X', 'E', '_', '_'):
104  st->codecpar->channels = 2;
105  st->codecpar->sample_rate = 32000;
106  st->codecpar->block_align = 0x20 * st->codecpar->channels;
107  break;
108  case MKTAG('P', 'S', 'P', '_'):
110  st->codecpar->channels = 2;
111  st->codecpar->sample_rate = 32768;
112  st->codecpar->block_align = 0x80 * st->codecpar->channels;
113  break;
114  case MKTAG('P', 'S', '2', '_'):
116  st->codecpar->channels = 2;
117  st->codecpar->sample_rate = 32000;
118  st->codecpar->block_align = 0x80 * st->codecpar->channels;
119  break;
120  default:
121  avpriv_request_sample(s, "Unsupported type: %X", type);
122  return AVERROR_PATCHWELCOME;
123  }
124  } else if (version == 6 || version == 5 || version == 4) {
125  type = avio_rl32(s->pb);
126  avio_skip(s->pb, 20);
128  st->codecpar->channels = 2;
129  switch (type) {
130  case MKTAG('G', 'C', '_', '_'):
132  st->codecpar->block_align = 0x20 * st->codecpar->channels;
133  st->codecpar->sample_rate = 32000;
134  offset = avio_rb32(s->pb);
135  break;
136  case MKTAG('P', 'S', '2', '_'):
138  st->codecpar->block_align = 0x80 * st->codecpar->channels;
139  st->codecpar->sample_rate = 32000;
140  offset = avio_rl32(s->pb);
141  break;
142  case MKTAG('X', 'B', '_', '_'):
144  st->codecpar->block_align = 0x20 * st->codecpar->channels;
145  st->codecpar->sample_rate = 44100;
146  offset = avio_rl32(s->pb);
147  break;
148  default:
149  avpriv_request_sample(s, "Unsupported type: %X", type);
150  return AVERROR_PATCHWELCOME;
151  }
152  } else {
153  av_assert0(0);
154  }
155 
156  avio_seek(s->pb, offset, SEEK_SET);
157 
158  avpriv_set_pts_info(st, 64, 1, st->codecpar->sample_rate);
159 
160  return 0;
161 }
162 
164 {
165  AVCodecParameters *par = s->streams[0]->codecpar;
166 
167  return av_get_packet(s->pb, pkt, par->block_align);
168 }
169 
171  .name = "musx",
172  .long_name = NULL_IF_CONFIG_SMALL("Eurocom MUSX"),
173  .read_probe = musx_probe,
174  .read_header = musx_read_header,
175  .read_packet = musx_read_packet,
176  .extensions = "musx",
177 };
#define NULL
Definition: coverity.c:32
const char * s
Definition: avisynth_c.h:768
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:59
AVInputFormat ff_musx_demuxer
Definition: musx.c:170
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:4811
enum AVCodecID codec_id
Specific type of the encoded data (the codec used).
Definition: avcodec.h:3884
int64_t avio_seek(AVIOContext *s, int64_t offset, int whence)
fseek() equivalent for AVIOContext.
Definition: aviobuf.c:246
int64_t avio_skip(AVIOContext *s, int64_t offset)
Skip given number of bytes forward.
Definition: aviobuf.c:331
int version
Definition: avisynth_c.h:766
static AVPacket pkt
This struct describes the properties of an encoded stream.
Definition: avcodec.h:3876
Format I/O context.
Definition: avformat.h:1342
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:37
void void avpriv_request_sample(void *avc, const char *msg,...) av_printf_format(2
Log a generic warning message about a missing feature.
unsigned int avio_rb32(AVIOContext *s)
Definition: aviobuf.c:801
AVStream * avformat_new_stream(AVFormatContext *s, const AVCodec *c)
Add a new stream to a media file.
Definition: utils.c:4441
AVStream ** streams
A list of all streams in the file.
Definition: avformat.h:1410
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:310
static int musx_probe(AVProbeData *p)
Definition: musx.c:26
unsigned int avio_rl32(AVIOContext *s)
Definition: aviobuf.c:770
#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:186
enum AVMediaType codec_type
General type of the encoded data.
Definition: avcodec.h:3880
simple assert() macros that are a bit more flexible than ISO C assert().
static const uint8_t offset[127][2]
Definition: vf_spp.c:92
unsigned char * buf
Buffer must have AVPROBE_PADDING_SIZE of extra allocated bytes filled with zero.
Definition: avformat.h:450
int block_align
Audio only.
Definition: avcodec.h:4001
static int musx_read_header(AVFormatContext *s)
Definition: musx.c:34
Stream structure.
Definition: avformat.h:873
#define AVERROR_PATCHWELCOME
Not yet implemented in FFmpeg, patches welcome.
Definition: error.h:62
AVIOContext * pb
I/O context.
Definition: avformat.h:1384
cl_device_type type
This structure contains the data a format has to probe a file.
Definition: avformat.h:448
int sample_rate
Audio only.
Definition: avcodec.h:3994
#define AVPROBE_SCORE_MAX
maximum score
Definition: avformat.h:460
Main libavformat public API header.
static int musx_read_packet(AVFormatContext *s, AVPacket *pkt)
Definition: musx.c:163
int channels
Audio only.
Definition: avcodec.h:3990
const char * name
A comma separated list of short names for the format.
Definition: avformat.h:647
AVCodecParameters * codecpar
Codec parameters associated with this stream.
Definition: avformat.h:1020
#define MKTAG(a, b, c, d)
Definition: common.h:366
This structure stores compressed data.
Definition: avcodec.h:1407