FFmpeg
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
wsddec.c
Go to the documentation of this file.
1 /*
2  * Wideband Single-bit Data (WSD) demuxer
3  * Copyright (c) 2014 Peter Ross
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 "libavutil/timecode.h"
24 #include "avformat.h"
25 #include "internal.h"
26 #include "rawdec.h"
27 
28 static int wsd_probe(AVProbeData *p)
29 {
30  if (p->buf_size < 45 || memcmp(p->buf, "1bit", 4) ||
31  !AV_RB32(p->buf + 36) || !p->buf[44] ||
32  (p->buf[0] >= 0x10 && (AV_RB32(p->buf + 20) < 0x80 || AV_RB32(p->buf + 24) < 0x80)))
33  return 0;
34  return AVPROBE_SCORE_MAX;
35 }
36 
37 static int empty_string(const char *buf, unsigned size)
38 {
39  while (size--) {
40  if (*buf++ != ' ')
41  return 0;
42  }
43  return 1;
44 }
45 
47 {
48  switch (bit) {
49  case 2: return AV_CH_BACK_RIGHT;
50  case 3:
51  avpriv_request_sample(s, "Rr-middle");
52  break;
53  case 4: return AV_CH_BACK_CENTER;
54  case 5:
55  avpriv_request_sample(s, "Lr-middle");
56  break;
57  case 6: return AV_CH_BACK_LEFT;
58  case 24: return AV_CH_LOW_FREQUENCY;
59  case 26: return AV_CH_FRONT_RIGHT;
60  case 27: return AV_CH_FRONT_RIGHT_OF_CENTER;
61  case 28: return AV_CH_FRONT_CENTER;
62  case 29: return AV_CH_FRONT_LEFT_OF_CENTER;
63  case 30: return AV_CH_FRONT_LEFT;
64  default:
65  av_log(s, AV_LOG_WARNING, "reserved channel assignment\n");
66  break;
67  }
68  return 0;
69 }
70 
71 static int get_metadata(AVFormatContext *s, const char *const tag, const unsigned size)
72 {
73  uint8_t *buf;
74  if (!(size + 1))
75  return AVERROR(ENOMEM);
76 
77  buf = av_malloc(size + 1);
78  if (!buf)
79  return AVERROR(ENOMEM);
80 
81  if (avio_read(s->pb, buf, size) != size) {
82  av_free(buf);
83  return AVERROR(EIO);
84  }
85 
86  if (empty_string(buf, size)) {
87  av_free(buf);
88  return 0;
89  }
90 
91  buf[size] = 0;
93  return 0;
94 }
95 
97 {
98  AVIOContext *pb = s->pb;
99  AVStream *st;
100  int version;
101  uint32_t text_offset, data_offset, channel_assign;
102  char playback_time[AV_TIMECODE_STR_SIZE];
103 
104  st = avformat_new_stream(s, NULL);
105  if (!st)
106  return AVERROR(ENOMEM);
107 
108  avio_skip(pb, 8);
109  version = avio_r8(pb);
110  av_log(s, AV_LOG_DEBUG, "version: %i.%i\n", version >> 4, version & 0xF);
111  avio_skip(pb, 11);
112 
113  if (version < 0x10) {
114  text_offset = 0x80;
115  data_offset = 0x800;
116  avio_skip(pb, 8);
117  } else {
118  text_offset = avio_rb32(pb);
119  data_offset = avio_rb32(pb);
120  }
121 
122  avio_skip(pb, 4);
123  av_timecode_make_smpte_tc_string(playback_time, avio_rb32(pb), 0);
124  av_dict_set(&s->metadata, "playback_time", playback_time, 0);
125 
128  st->codecpar->sample_rate = avio_rb32(pb) / 8;
129  avio_skip(pb, 4);
130  st->codecpar->channels = avio_r8(pb) & 0xF;
131  st->codecpar->bit_rate = st->codecpar->channels * st->codecpar->sample_rate * 8LL;
132  if (!st->codecpar->channels)
133  return AVERROR_INVALIDDATA;
134 
135  avio_skip(pb, 3);
136  channel_assign = avio_rb32(pb);
137  if (!(channel_assign & 1)) {
138  int i;
139  for (i = 1; i < 32; i++)
140  if (channel_assign & (1 << i))
142  }
143 
144  avio_skip(pb, 16);
145  if (avio_rb32(pb))
146  avpriv_request_sample(s, "emphasis");
147 
148  if (avio_seek(pb, text_offset, SEEK_SET) >= 0) {
149  get_metadata(s, "title", 128);
150  get_metadata(s, "composer", 128);
151  get_metadata(s, "song_writer", 128);
152  get_metadata(s, "artist", 128);
153  get_metadata(s, "album", 128);
154  get_metadata(s, "genre", 32);
155  get_metadata(s, "date", 32);
156  get_metadata(s, "location", 32);
157  get_metadata(s, "comment", 512);
158  get_metadata(s, "user", 512);
159  }
160 
161  return avio_seek(pb, data_offset, SEEK_SET);
162 }
163 
165  .name = "wsd",
166  .long_name = NULL_IF_CONFIG_SMALL("Wideband Single-bit Data (WSD)"),
167  .read_probe = wsd_probe,
168  .read_header = wsd_read_header,
169  .read_packet = ff_raw_read_partial_packet,
170  .extensions = "wsd",
172  .raw_codec_id = AV_CODEC_ID_DSD_MSBF,
173 };
#define NULL
Definition: coverity.c:32
const char * s
Definition: avisynth_c.h:631
Bytestream IO Context.
Definition: avio.h:147
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:59
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:182
enum AVCodecID codec_id
Specific type of the encoded data (the codec used).
Definition: avcodec.h:3922
int64_t avio_seek(AVIOContext *s, int64_t offset, int whence)
fseek() equivalent for AVIOContext.
Definition: aviobuf.c:230
int64_t avio_skip(AVIOContext *s, int64_t offset)
Skip given number of bytes forward.
Definition: aviobuf.c:304
int version
Definition: avisynth_c.h:629
Format I/O context.
Definition: avformat.h:1325
static int wsd_read_header(AVFormatContext *s)
Definition: wsddec.c:96
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
#define av_malloc(s)
unsigned int avio_rb32(AVIOContext *s)
Definition: aviobuf.c:751
AVStream * avformat_new_stream(AVFormatContext *s, const AVCodec *c)
Add a new stream to a media file.
Definition: utils.c:4065
#define AV_CH_LOW_FREQUENCY
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_WB64 unsigned int_TMPL AV_RB32
Definition: bytestream.h:87
AVInputFormat ff_wsd_demuxer
Definition: wsddec.c:164
uint32_t tag
Definition: movenc.c:1367
#define AV_CH_BACK_LEFT
ptrdiff_t size
Definition: opengl_enc.c:101
uint64_t channel_layout
Audio only.
Definition: avcodec.h:4024
#define av_log(a,...)
int avio_read(AVIOContext *s, unsigned char *buf, int size)
Read size bytes from AVIOContext into buf.
Definition: aviobuf.c:598
int64_t bit_rate
The average bitrate of the encoded data (in bits per second).
Definition: avcodec.h:3951
AVDictionary * metadata
Metadata that applies to the whole file.
Definition: avformat.h:1539
#define AVERROR(e)
Definition: error.h:43
int ff_raw_read_partial_packet(AVFormatContext *s, AVPacket *pkt)
Definition: rawdec.c:35
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Definition: internal.h:176
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:197
enum AVMediaType codec_type
General type of the encoded data.
Definition: avcodec.h:3918
int avio_r8(AVIOContext *s)
Definition: aviobuf.c:589
int buf_size
Size of buf except extra allocated bytes.
Definition: avformat.h:462
unsigned char * buf
Buffer must have AVPROBE_PADDING_SIZE of extra allocated bytes filled with zero.
Definition: avformat.h:461
#define AV_DICT_DONT_STRDUP_VAL
Take ownership of a value that's been allocated with av_malloc() or another memory allocation functio...
Definition: dict.h:76
#define AV_CH_FRONT_LEFT_OF_CENTER
#define AV_CH_FRONT_CENTER
#define AV_CH_FRONT_RIGHT_OF_CENTER
Stream structure.
Definition: avformat.h:876
Timecode helpers header.
AVIOContext * pb
I/O context.
Definition: avformat.h:1367
#define AV_CH_FRONT_LEFT
static int wsd_to_av_channel_layoyt(AVFormatContext *s, int bit)
Definition: wsddec.c:46
void * buf
Definition: avisynth_c.h:553
int av_dict_set(AVDictionary **pm, const char *key, const char *value, int flags)
Set the given entry in *pm, overwriting an existing entry.
Definition: dict.c:69
static int get_metadata(AVFormatContext *s, const char *const tag, const unsigned size)
Definition: wsddec.c:71
#define AVFMT_GENERIC_INDEX
Use generic index building code.
Definition: avformat.h:485
This structure contains the data a format has to probe a file.
Definition: avformat.h:459
char * av_timecode_make_smpte_tc_string(char *buf, uint32_t tcsmpte, int prevent_df)
Get the timecode string from the SMPTE timecode format.
Definition: timecode.c:118
int raw_codec_id
Raw demuxers store their codec ID here.
Definition: avformat.h:706
#define AV_CH_BACK_CENTER
static int empty_string(const char *buf, unsigned size)
Definition: wsddec.c:37
int sample_rate
Audio only.
Definition: avcodec.h:4032
#define AVPROBE_SCORE_MAX
maximum score
Definition: avformat.h:471
Main libavformat public API header.
struct AVInputFormat * iformat
The input container format.
Definition: avformat.h:1337
#define av_free(p)
#define AVFMT_NO_BYTE_SEEK
Format does not allow seeking by bytes.
Definition: avformat.h:492
int channels
Audio only.
Definition: avcodec.h:4028
#define AV_CH_FRONT_RIGHT
const char * name
A comma separated list of short names for the format.
Definition: avformat.h:660
AVCodecParameters * codecpar
Definition: avformat.h:1006
#define AV_CH_BACK_RIGHT
#define AV_TIMECODE_STR_SIZE
Definition: timecode.h:33
static int wsd_probe(AVProbeData *p)
Definition: wsddec.c:28