FFmpeg  4.2.3
hcom.c
Go to the documentation of this file.
1 /*
2  * HCOM audio decoder
3  *
4  * This file is part of FFmpeg.
5  *
6  * FFmpeg 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.
10  *
11  * FFmpeg 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.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with FFmpeg; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
21 #include "libavutil/intreadwrite.h"
22 
23 #include "avcodec.h"
24 #include "get_bits.h"
25 #include "internal.h"
26 
27 typedef struct HEntry {
28  int16_t l, r;
29 } HEntry;
30 
31 typedef struct HCOMContext {
33 
39 
41 } HCOMContext;
42 
43 static av_cold int hcom_init(AVCodecContext *avctx)
44 {
45  HCOMContext *s = avctx->priv_data;
46 
47  if (avctx->channels != 1) {
48  av_log(avctx, AV_LOG_ERROR, "invalid number of channels\n");
49  return AVERROR_INVALIDDATA;
50  }
51 
52  if (avctx->extradata_size <= 7)
53  return AVERROR_INVALIDDATA;
54  s->dict_entries = AV_RB16(avctx->extradata);
55  if (avctx->extradata_size < s->dict_entries * 4 + 7 ||
56  s->dict_entries == 0)
57  return AVERROR_INVALIDDATA;
58  s->delta_compression = AV_RB32(avctx->extradata + 2);
59  s->sample = s->first_sample = avctx->extradata[avctx->extradata_size - 1];
60 
61  s->dict = av_calloc(s->dict_entries, sizeof(*s->dict));
62  if (!s->dict)
63  return AVERROR(ENOMEM);
64  for (int i = 0; i < s->dict_entries; i++) {
65  s->dict[i].l = AV_RB16(avctx->extradata + 6 + 4 * i);
66  s->dict[i].r = AV_RB16(avctx->extradata + 6 + 4 * i + 2);
67  if (s->dict[i].l >= 0 &&
68  (s->dict[i].l >= s->dict_entries ||
69  s->dict[i].r >= s->dict_entries ||
70  s->dict[i].r < 0 )) {
71  av_freep(&s->dict);
72  return AVERROR_INVALIDDATA;
73  }
74  }
75  if (s->dict[0].l < 0) {
76  av_freep(&s->dict);
77  return AVERROR_INVALIDDATA;
78  }
79 
81  s->dict_entry = 0;
82 
83  return 0;
84 }
85 
86 static int hcom_decode(AVCodecContext *avctx, void *data,
87  int *got_frame, AVPacket *pkt)
88 {
89  HCOMContext *s = avctx->priv_data;
90  AVFrame *frame = data;
91  GetBitContext gb;
92  int ret, n = 0;
93 
94  if (pkt->size > INT16_MAX)
95  return AVERROR_INVALIDDATA;
96 
97  frame->nb_samples = pkt->size * 8;
98  if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
99  return ret;
100 
101  if ((ret = init_get_bits8(&gb, pkt->data, pkt->size)) < 0)
102  return ret;
103 
104  while (get_bits_left(&gb) > 0) {
105  if (get_bits1(&gb))
106  s->dict_entry = s->dict[s->dict_entry].r;
107  else
108  s->dict_entry = s->dict[s->dict_entry].l;
109 
110  if (s->dict[s->dict_entry].l < 0) {
111  int16_t datum;
112 
113  datum = s->dict[s->dict_entry].r;
114 
115  if (!s->delta_compression)
116  s->sample = 0;
117  s->sample = (s->sample + datum) & 0xFF;
118 
119  frame->data[0][n++] = s->sample;
120 
121  s->dict_entry = 0;
122  }
123  }
124 
125  frame->nb_samples = n;
126 
127  *got_frame = 1;
128 
129  return pkt->size;
130 }
131 
133 {
134  HCOMContext *s = avctx->priv_data;
135 
136  av_freep(&s->dict);
137 
138  return 0;
139 }
140 
142  .name = "hcom",
143  .long_name = NULL_IF_CONFIG_SMALL("HCOM Audio"),
144  .type = AVMEDIA_TYPE_AUDIO,
145  .id = AV_CODEC_ID_HCOM,
146  .priv_data_size = sizeof(HCOMContext),
147  .init = hcom_init,
148  .close = hcom_close,
149  .decode = hcom_decode,
150  .capabilities = AV_CODEC_CAP_DR1,
151 };
uint8_t sample
Definition: hcom.c:35
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:59
int16_t r
Definition: hcom.c:28
This structure describes decoded (raw) audio or video data.
Definition: frame.h:295
int dict_entry
Definition: hcom.c:37
static av_cold int init(AVCodecContext *avctx)
Definition: avrndec.c:35
AVCodecContext * avctx
Definition: hcom.c:32
int16_t l
Definition: hcom.c:28
int size
Definition: avcodec.h:1478
static AVPacket pkt
AVCodec.
Definition: avcodec.h:3481
static void decode(AVCodecContext *dec_ctx, AVPacket *pkt, AVFrame *frame, FILE *outfile)
Definition: decode_audio.c:42
void * av_calloc(size_t nmemb, size_t size)
Non-inlined equivalent of av_mallocz_array().
Definition: mem.c:244
static av_cold int hcom_init(AVCodecContext *avctx)
Definition: hcom.c:43
uint8_t first_sample
Definition: hcom.c:34
enum AVSampleFormat sample_fmt
audio sample format
Definition: avcodec.h:2233
uint8_t
#define av_cold
Definition: attributes.h:82
AV_SAMPLE_FMT_U8
#define AV_RB32
Definition: intreadwrite.h:130
uint8_t * extradata
some codecs need / can use extradata like Huffman tables.
Definition: avcodec.h:1666
static AVFrame * frame
const char data[16]
Definition: mxf.c:91
uint8_t * data
Definition: avcodec.h:1477
bitstream reader API header.
#define av_log(a,...)
static int get_bits_left(GetBitContext *gb)
Definition: get_bits.h:849
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:259
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
static av_cold int hcom_close(AVCodecContext *avctx)
Definition: hcom.c:132
#define AV_RB16
Definition: intreadwrite.h:53
#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
const char * name
Name of the codec implementation.
Definition: avcodec.h:3488
#define s(width, name)
Definition: cbs_vp9.c:257
int n
Definition: avisynth_c.h:760
static int hcom_decode(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *pkt)
Definition: hcom.c:86
Libavcodec external API header.
HEntry * dict
Definition: hcom.c:40
AVCodec ff_hcom_decoder
Definition: hcom.c:141
static int init_get_bits8(GetBitContext *s, const uint8_t *buffer, int byte_size)
Initialize GetBitContext.
Definition: get_bits.h:677
main external API structure.
Definition: avcodec.h:1565
int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags)
Get a buffer for a frame.
Definition: decode.c:1964
int extradata_size
Definition: avcodec.h:1667
static unsigned int get_bits1(GetBitContext *s)
Definition: get_bits.h:498
int dict_entries
Definition: hcom.c:36
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:309
Definition: hcom.c:27
common internal api header.
void * priv_data
Definition: avcodec.h:1592
int delta_compression
Definition: hcom.c:38
int channels
number of audio channels
Definition: avcodec.h:2226
#define av_freep(p)
This structure stores compressed data.
Definition: avcodec.h:1454
int nb_samples
number of audio samples (per channel) described by this frame
Definition: frame.h:361
#define AV_CODEC_CAP_DR1
Codec uses get_buffer() for allocating buffers and supports custom allocators.
Definition: avcodec.h:981