FFmpeg  4.2.1
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  return AVERROR_INVALIDDATA;
57  s->delta_compression = AV_RB32(avctx->extradata + 2);
58  s->sample = s->first_sample = avctx->extradata[avctx->extradata_size - 1];
59 
60  s->dict = av_calloc(s->dict_entries, sizeof(*s->dict));
61  if (!s->dict)
62  return AVERROR(ENOMEM);
63  for (int i = 0; i < s->dict_entries; i++) {
64  s->dict[i].l = AV_RB16(avctx->extradata + 6 + 4 * i);
65  s->dict[i].r = AV_RB16(avctx->extradata + 6 + 4 * i + 2);
66  if (s->dict[i].l >= 0 &&
67  (s->dict[i].l >= s->dict_entries ||
68  s->dict[i].r >= s->dict_entries))
69  return AVERROR_INVALIDDATA;
70  }
71 
73  s->dict_entry = 0;
74 
75  return 0;
76 }
77 
78 static int hcom_decode(AVCodecContext *avctx, void *data,
79  int *got_frame, AVPacket *pkt)
80 {
81  HCOMContext *s = avctx->priv_data;
82  AVFrame *frame = data;
83  GetBitContext gb;
84  int ret, n = 0;
85 
86  if (pkt->size > INT16_MAX)
87  return AVERROR_INVALIDDATA;
88 
89  frame->nb_samples = pkt->size * 8;
90  if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
91  return ret;
92 
93  if ((ret = init_get_bits8(&gb, pkt->data, pkt->size)) < 0)
94  return ret;
95 
96  while (get_bits_left(&gb) > 0) {
97  if (get_bits1(&gb))
98  s->dict_entry = s->dict[s->dict_entry].r;
99  else
100  s->dict_entry = s->dict[s->dict_entry].l;
101 
102  if (s->dict[s->dict_entry].l < 0) {
103  int16_t datum;
104 
105  datum = s->dict[s->dict_entry].r;
106 
107  if (!s->delta_compression)
108  s->sample = 0;
109  s->sample = (s->sample + datum) & 0xFF;
110 
111  frame->data[0][n++] = s->sample;
112 
113  s->dict_entry = 0;
114  }
115  }
116 
117  frame->nb_samples = n;
118 
119  *got_frame = 1;
120 
121  return pkt->size;
122 }
123 
125 {
126  HCOMContext *s = avctx->priv_data;
127 
128  av_freep(&s->dict);
129 
130  return 0;
131 }
132 
134  .name = "hcom",
135  .long_name = NULL_IF_CONFIG_SMALL("HCOM Audio"),
136  .type = AVMEDIA_TYPE_AUDIO,
137  .id = AV_CODEC_ID_HCOM,
138  .priv_data_size = sizeof(HCOMContext),
139  .init = hcom_init,
140  .close = hcom_close,
141  .decode = hcom_decode,
142  .capabilities = AV_CODEC_CAP_DR1,
143 };
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:124
#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:78
Libavcodec external API header.
HEntry * dict
Definition: hcom.c:40
AVCodec ff_hcom_decoder
Definition: hcom.c:133
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