History

avcodec: add Newtek SpeedHQ decoder

This decoder can decode all existing SpeedHQ formats (SHQ0–5, 7, and 9), including correct decoding of the alpha channel. 1080p is decoded in 142 fps on one core of my i7-4600U (2.1 GHz Haswell), about evenly split between bitstream reader and IDCT. There is currently no attempt at slice or frame threading, even though the format trivially supports both. NewTek very helpfully provided a full set of SHQ samples, as well as source code for an SHQ2 encoder (not included) and assistance with understanding some details of the format.

Steinar H. Gunderson committed 9 years ago

Commit 2a293ec1 parent eaff1aa12 files · +716 −13Browse files

Unified · Split

12 files
  1. Changelog +1 −0
  2. libavcodec/Makefile +1 −0
  3. libavcodec/allcodecs.c +1 −0
  4. libavcodec/avcodec.h +1 −0
  5. libavcodec/codec_desc.c +7 −0
  6. libavcodec/get_bits.h +14 −0
  7. libavcodec/mpeg12.c +4 −11
  8. libavcodec/mpeg12.h +9 −0
  9. libavcodec/speedhq.c +659 −0
  10. libavcodec/version.h +2 −2
  11. libavcodec/vlc.h +9 −0
  12. libavformat/riff.c +8 −0
Changelog+1−0
@@ -13,6 +13,7 @@ version <next>: · 12 unmodified lines
1313 - 24.0 floating point pcm decoder
1414 - Apple Pixlet decoder
1515 - QDMC audio decoder
16+- NewTek SpeedHQ decoder
1617
1718 version 3.2:
1819 - libopenmpt demuxer
libavcodec/Makefile+1−0
@@ -521,6 +521,7 @@ OBJS-$(CONFIG_SOL_DPCM_DECODER) += dpcm.o · 520 unmodified lines
521521 OBJS-$(CONFIG_SONIC_DECODER) += sonic.o
522522 OBJS-$(CONFIG_SONIC_ENCODER) += sonic.o
523523 OBJS-$(CONFIG_SONIC_LS_ENCODER) += sonic.o
524+OBJS-$(CONFIG_SPEEDHQ_DECODER) += speedhq.o simple_idct.o
524525 OBJS-$(CONFIG_SP5X_DECODER) += sp5xdec.o
525526 OBJS-$(CONFIG_SRT_DECODER) += srtdec.o ass.o htmlsubtitles.o
526527 OBJS-$(CONFIG_SRT_ENCODER) += srtenc.o ass_split.o
libavcodec/allcodecs.c+1−0
@@ -316,6 +316,7 @@ void avcodec_register_all(void) · 315 unmodified lines
316316 REGISTER_DECODER(SMVJPEG, smvjpeg);
317317 REGISTER_ENCDEC (SNOW, snow);
318318 REGISTER_DECODER(SP5X, sp5x);
319+ REGISTER_DECODER(SPEEDHQ, speedhq);
319320 REGISTER_ENCDEC (SUNRAST, sunrast);
320321 REGISTER_ENCDEC (SVQ1, svq1);
321322 REGISTER_DECODER(SVQ3, svq3);
libavcodec/avcodec.h+1−0
@@ -413,6 +413,7 @@ enum AVCodecID { · 412 unmodified lines
413413 AV_CODEC_ID_YLC,
414414 AV_CODEC_ID_PSD,
415415 AV_CODEC_ID_PIXLET,
416+ AV_CODEC_ID_SPEEDHQ,
416417
417418 /* various PCM "codecs" */
418419 AV_CODEC_ID_FIRST_AUDIO = 0x10000, ///< A dummy id pointing at the start of audio codecs
libavcodec/codec_desc.c+7−0
@@ -1290,6 +1290,13 @@ static const AVCodecDescriptor codec_descriptors[] = { · 1289 unmodified lines
12901290 .long_name = NULL_IF_CONFIG_SMALL("Screenpresso"),
12911291 .props = AV_CODEC_PROP_LOSSLESS,
12921292 },
1293+ {
1294+ .id = AV_CODEC_ID_SPEEDHQ,
1295+ .type = AVMEDIA_TYPE_VIDEO,
1296+ .name = "speedhq",
1297+ .long_name = NULL_IF_CONFIG_SMALL("NewTek SpeedHQ"),
1298+ .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY,
1299+ },
12931300 {
12941301 .id = AV_CODEC_ID_WRAPPED_AVFRAME,
12951302 .type = AVMEDIA_TYPE_VIDEO,
libavcodec/get_bits.h+14−0
@@ -229,6 +229,20 @@ static inline int get_xbits(GetBitContext *s, int n) · 228 unmodified lines
229229 return (NEG_USR32(sign ^ cache, n) ^ sign) - sign;
230230 }
231231
232+static inline int get_xbits_le(GetBitContext *s, int n)
233+{
234+ register int sign;
235+ register int32_t cache;
236+ OPEN_READER(re, s);
237+ av_assert2(n>0 && n<=25);
238+ UPDATE_CACHE_LE(re, s);
239+ cache = GET_CACHE(re, s);
240+ sign = sign_extend(~cache, n) >> 31;
241+ LAST_SKIP_BITS(re, s, n);
242+ CLOSE_READER(re, s);
243+ return (zero_extend(sign ^ cache, n) ^ sign) - sign;
244+}
245+
232246 static inline int get_sbits(GetBitContext *s, int n)
233247 {
234248 register int tmp;
libavcodec/mpeg12.c+4−11
@@ -67,20 +67,13 @@ static const uint8_t table_mb_btype[11][2] = { · 66 unmodified lines
6767 { 2, 5 }, // 0x1E MB_QUANT|MB_FOR|MB_BACK|MB_PAT
6868 };
6969
70−#define INIT_2D_VLC_RL(rl, static_size)\
71−{\
72− static RL_VLC_ELEM rl_vlc_table[static_size];\
73− rl.rl_vlc[0] = rl_vlc_table;\
74− init_2d_vlc_rl(&rl, static_size);\
75−}
76−
77−static av_cold void init_2d_vlc_rl(RLTable *rl, unsigned static_size)
70+av_cold void ff_init_2d_vlc_rl(RLTable *rl, unsigned static_size, int flags)
7871 {
7972 int i;
8073 VLC_TYPE table[680][2] = {{0}};
8174 VLC vlc = { .table = table, .table_allocated = static_size };
8275 av_assert0(static_size <= FF_ARRAY_ELEMS(table));
83− init_vlc(&vlc, TEX_VLC_BITS, rl->n + 2, &rl->table_vlc[0][1], 4, 2, &rl->table_vlc[0][0], 4, 2, INIT_VLC_USE_NEW_STATIC);
76+ init_vlc(&vlc, TEX_VLC_BITS, rl->n + 2, &rl->table_vlc[0][1], 4, 2, &rl->table_vlc[0][0], 4, 2, INIT_VLC_USE_NEW_STATIC | flags);
8477
8578 for (i = 0; i < vlc.table_size; i++) {
8679 int code = vlc.table[i][0];
@@ -173,8 +166,8 @@ av_cold void ff_mpeg12_init_vlcs(void) · 86 unmodified lines
173166 ff_rl_init(&ff_rl_mpeg1, ff_mpeg12_static_rl_table_store[0]);
174167 ff_rl_init(&ff_rl_mpeg2, ff_mpeg12_static_rl_table_store[1]);
175168
176− INIT_2D_VLC_RL(ff_rl_mpeg1, 680);
177− INIT_2D_VLC_RL(ff_rl_mpeg2, 674);
169+ INIT_2D_VLC_RL(ff_rl_mpeg1, 680, 0);
170+ INIT_2D_VLC_RL(ff_rl_mpeg2, 674, 0);
178171 }
179172 }
180173
libavcodec/mpeg12.h+9−0
@@ -29,6 +29,15 @@ extern uint8_t ff_mpeg12_static_rl_table_store[2][2][2*MAX_RUN + MAX_LEVEL + 3]; · 28 unmodified lines
2929
3030 void ff_mpeg12_common_init(MpegEncContext *s);
3131
32+#define INIT_2D_VLC_RL(rl, static_size, flags)\
33+{\
34+ static RL_VLC_ELEM rl_vlc_table[static_size];\
35+ rl.rl_vlc[0] = rl_vlc_table;\
36+ ff_init_2d_vlc_rl(&rl, static_size, flags);\
37+}
38+
39+void ff_init_2d_vlc_rl(RLTable *rl, unsigned static_size, int flags);
40+
3241 static inline int decode_dc(GetBitContext *gb, int component)
3342 {
3443 int code, diff;
libavcodec/speedhq.c+659−0
@@ -0,0 +1,659 @@
1+/*
2+ * NewTek SpeedHQ codec
3+ * Copyright 2017 Steinar H. Gunderson
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+/**
23+ * @file
24+ * NewTek SpeedHQ decoder.
25+ */
26+
27+#define BITSTREAM_READER_LE
28+
29+#include "libavutil/attributes.h"
30+
31+#include "avcodec.h"
32+#include "get_bits.h"
33+#include "internal.h"
34+#include "libavutil/thread.h"
35+#include "mathops.h"
36+#include "mpeg12.h"
37+#include "mpeg12data.h"
38+#include "mpeg12vlc.h"
39+
40+#define MAX_INDEX (64 - 1)
41+
42+/*
43+ * 5 bits makes for very small tables, with no more than two lookups needed
44+ * for the longest (10-bit) codes.
45+ */
46+#define ALPHA_VLC_BITS 5
47+
48+typedef struct SHQContext {
49+ AVCodecContext *avctx;
50+ BlockDSPContext bdsp;
51+ IDCTDSPContext idsp;
52+ ScanTable intra_scantable;
53+ int quant_matrix[64];
54+ enum { SHQ_SUBSAMPLING_420, SHQ_SUBSAMPLING_422, SHQ_SUBSAMPLING_444 }
55+ subsampling;
56+ enum { SHQ_NO_ALPHA, SHQ_RLE_ALPHA, SHQ_DCT_ALPHA } alpha_type;
57+} SHQContext;
58+
59+
60+/* AC codes: Very similar but not identical to MPEG-2. */
61+static uint16_t speedhq_vlc[123][2] = {
62+ {0x02, 2}, {0x06, 3}, {0x07, 4}, {0x1c, 5},
63+ {0x1d, 5}, {0x05, 6}, {0x04, 6}, {0x7b, 7},
64+ {0x7c, 7}, {0x23, 8}, {0x22, 8}, {0xfa, 8},
65+ {0xfb, 8}, {0xfe, 8}, {0xff, 8}, {0x1f,14},
66+ {0x1e,14}, {0x1d,14}, {0x1c,14}, {0x1b,14},
67+ {0x1a,14}, {0x19,14}, {0x18,14}, {0x17,14},
68+ {0x16,14}, {0x15,14}, {0x14,14}, {0x13,14},
69+ {0x12,14}, {0x11,14}, {0x10,14}, {0x18,15},
70+ {0x17,15}, {0x16,15}, {0x15,15}, {0x14,15},
71+ {0x13,15}, {0x12,15}, {0x11,15}, {0x10,15},
72+ {0x02, 3}, {0x06, 5}, {0x79, 7}, {0x27, 8},
73+ {0x20, 8}, {0x16,13}, {0x15,13}, {0x1f,15},
74+ {0x1e,15}, {0x1d,15}, {0x1c,15}, {0x1b,15},
75+ {0x1a,15}, {0x19,15}, {0x13,16}, {0x12,16},
76+ {0x11,16}, {0x10,16}, {0x18,13}, {0x17,13},
77+ {0x05, 5}, {0x07, 7}, {0xfc, 8}, {0x0c,10},
78+ {0x14,13}, {0x18,12}, {0x14,12}, {0x13,12},
79+ {0x10,12}, {0x1a,13}, {0x19,13}, {0x07, 5},
80+ {0x26, 8}, {0x1c,12}, {0x13,13}, {0x1b,12},
81+ {0x06, 6}, {0xfd, 8}, {0x12,12}, {0x1d,12},
82+ {0x07, 6}, {0x04, 9}, {0x12,13}, {0x06, 7},
83+ {0x1e,12}, {0x14,16}, {0x04, 7}, {0x15,12},
84+ {0x05, 7}, {0x11,12}, {0x78, 7}, {0x11,13},
85+ {0x7a, 7}, {0x10,13}, {0x21, 8}, {0x1a,16},
86+ {0x25, 8}, {0x19,16}, {0x24, 8}, {0x18,16},
87+ {0x05, 9}, {0x17,16}, {0x07, 9}, {0x16,16},
88+ {0x0d,10}, {0x15,16}, {0x1f,12}, {0x1a,12},
89+ {0x19,12}, {0x17,12}, {0x16,12}, {0x1f,13},
90+ {0x1e,13}, {0x1d,13}, {0x1c,13}, {0x1b,13},
91+ {0x1f,16}, {0x1e,16}, {0x1d,16}, {0x1c,16},
92+ {0x1b,16},
93+ {0x01,6}, /* escape */
94+ {0x06,4}, /* EOB */
95+};
96+
97+static const uint8_t speedhq_level[121] = {
98+ 1, 2, 3, 4, 5, 6, 7, 8,
99+ 9, 10, 11, 12, 13, 14, 15, 16,
100+ 17, 18, 19, 20, 21, 22, 23, 24,
101+ 25, 26, 27, 28, 29, 30, 31, 32,
102+ 33, 34, 35, 36, 37, 38, 39, 40,
103+ 1, 2, 3, 4, 5, 6, 7, 8,
104+ 9, 10, 11, 12, 13, 14, 15, 16,
105+ 17, 18, 19, 20, 1, 2, 3, 4,
106+ 5, 6, 7, 8, 9, 10, 11, 1,
107+ 2, 3, 4, 5, 1, 2, 3, 4,
108+ 1, 2, 3, 1, 2, 3, 1, 2,
109+ 1, 2, 1, 2, 1, 2, 1, 2,
110+ 1, 2, 1, 2, 1, 2, 1, 2,
111+ 1, 2, 1, 1, 1, 1, 1, 1,
112+ 1, 1, 1, 1, 1, 1, 1, 1,
113+ 1,
114+};
115+
116+static const uint8_t speedhq_run[121] = {
117+ 0, 0, 0, 0, 0, 0, 0, 0,
118+ 0, 0, 0, 0, 0, 0, 0, 0,
119+ 0, 0, 0, 0, 0, 0, 0, 0,
120+ 0, 0, 0, 0, 0, 0, 0, 0,
121+ 0, 0, 0, 0, 0, 0, 0, 0,
122+ 1, 1, 1, 1, 1, 1, 1, 1,
123+ 1, 1, 1, 1, 1, 1, 1, 1,
124+ 1, 1, 1, 1, 2, 2, 2, 2,
125+ 2, 2, 2, 2, 2, 2, 2, 3,
126+ 3, 3, 3, 3, 4, 4, 4, 4,
127+ 5, 5, 5, 6, 6, 6, 7, 7,
128+ 8, 8, 9, 9, 10, 10, 11, 11,
129+ 12, 12, 13, 13, 14, 14, 15, 15,
130+ 16, 16, 17, 18, 19, 20, 21, 22,
131+ 23, 24, 25, 26, 27, 28, 29, 30,
132+ 31,
133+};
134+
135+static RLTable ff_rl_speedhq = {
136+ 121,
137+ 121,
138+ speedhq_vlc,
139+ speedhq_run,
140+ speedhq_level,
141+};
142+
143+/* NOTE: The first element is always 16, unscaled. */
144+static const uint8_t unscaled_quant_matrix[64] = {
145+ 16, 16, 19, 22, 26, 27, 29, 34,
146+ 16, 16, 22, 24, 27, 29, 34, 37,
147+ 19, 22, 26, 27, 29, 34, 34, 38,
148+ 22, 22, 26, 27, 29, 34, 37, 40,
149+ 22, 26, 27, 29, 32, 35, 40, 48,
150+ 26, 27, 29, 32, 35, 40, 48, 58,
151+ 26, 27, 29, 34, 38, 46, 56, 69,
152+ 27, 29, 35, 38, 46, 56, 69, 83
153+};
154+
155+static uint8_t ff_speedhq_static_rl_table_store[2][2*MAX_RUN + MAX_LEVEL + 3];
156+
157+static VLC ff_dc_lum_vlc_le;
158+static VLC ff_dc_chroma_vlc_le;
159+static VLC ff_dc_alpha_run_vlc_le;
160+static VLC ff_dc_alpha_level_vlc_le;
161+
162+static inline int decode_dc_le(GetBitContext *gb, int component)
163+{
164+ int code, diff;
165+
166+ if (component == 0 || component == 3) {
167+ code = get_vlc2(gb, ff_dc_lum_vlc_le.table, DC_VLC_BITS, 2);
168+ } else {
169+ code = get_vlc2(gb, ff_dc_chroma_vlc_le.table, DC_VLC_BITS, 2);
170+ }
171+ if (code < 0) {
172+ av_log(NULL, AV_LOG_ERROR, "invalid dc code at\n");
173+ return 0xffff;
174+ }
175+ if (!code) {
176+ diff = 0;
177+ } else {
178+ diff = get_xbits_le(gb, code);
179+ }
180+ return diff;
181+}
182+
183+static inline int decode_alpha_block(const SHQContext *s, GetBitContext *gb, uint8_t last_alpha[16], uint8_t *dest, int linesize)
184+{
185+ uint8_t block[128];
186+ int i = 0, x, y;
187+
188+ memset(block, 0, sizeof(block));
189+
190+ {
191+ OPEN_READER(re, gb);
192+
193+ for ( ;; ) {
194+ int run, level;
195+
196+ UPDATE_CACHE_LE(re, gb);
197+ GET_VLC(run, re, gb, ff_dc_alpha_run_vlc_le.table, ALPHA_VLC_BITS, 2);
198+
199+ if (run == 128) break;
200+ i += run;
201+ if (i >= 128)
202+ return AVERROR_INVALIDDATA;
203+
204+ UPDATE_CACHE_LE(re, gb);
205+ GET_VLC(level, re, gb, ff_dc_alpha_level_vlc_le.table, ALPHA_VLC_BITS, 2);
206+ block[i++] = level;
207+ }
208+
209+ CLOSE_READER(re, gb);
210+ }
211+
212+ for (y = 0; y < 8; y++) {
213+ for (x = 0; x < 16; x++) {
214+ last_alpha[x] -= block[y * 16 + x];
215+ }
216+ memcpy(dest, last_alpha, 16);
217+ dest += linesize;
218+ }
219+
220+ return 0;
221+}
222+
223+static inline int decode_dct_block(const SHQContext *s, GetBitContext *gb, int last_dc[4], int component, uint8_t *dest, int linesize)
224+{
225+ const int *quant_matrix = s->quant_matrix;
226+ const uint8_t *scantable = s->intra_scantable.permutated;
227+ int16_t block[64];
228+ int dc_offset;
229+
230+ s->bdsp.clear_block(block);
231+
232+ dc_offset = decode_dc_le(gb, component);
233+ last_dc[component] -= dc_offset; /* Note: Opposite of most codecs. */
234+ block[scantable[0]] = last_dc[component]; /* quant_matrix[0] is always 16. */
235+
236+ /* Read AC coefficients. */
237+ {
238+ int i = 0;
239+ OPEN_READER(re, gb);
240+ for ( ;; ) {
241+ int level, run;
242+ UPDATE_CACHE_LE(re, gb);
243+ GET_RL_VLC(level, run, re, gb, ff_rl_speedhq.rl_vlc[0],
244+ TEX_VLC_BITS, 2, 0);
245+ if (level == 127) {
246+ break;
247+ } else if (level) {
248+ i += run;
249+ if (i > MAX_INDEX)
250+ return AVERROR_INVALIDDATA;
251+ /* If next bit is 1, level = -level */
252+ level = (level ^ SHOW_SBITS(re, gb, 1)) -
253+ SHOW_SBITS(re, gb, 1);
254+ LAST_SKIP_BITS(re, gb, 1);
255+ } else {
256+ /* Escape. */
257+#if MIN_CACHE_BITS < 6 + 6 + 12
258+#error MIN_CACHE_BITS is too small for the escape code, add UPDATE_CACHE
259+#endif
260+ run = SHOW_UBITS(re, gb, 6) + 1;
261+ SKIP_BITS(re, gb, 6);
262+ level = SHOW_UBITS(re, gb, 12) - 2048;
263+ LAST_SKIP_BITS(re, gb, 12);
264+
265+ i += run;
266+ if (i > MAX_INDEX)
267+ return AVERROR_INVALIDDATA;
268+ }
269+
270+ block[scantable[i]] = (level * quant_matrix[i]) >> 4;
271+ }
272+ CLOSE_READER(re, gb);
273+ }
274+
275+ s->idsp.idct_put(dest, linesize, block);
276+
277+ return 0;
278+}
279+
280+static int decode_speedhq_field(const SHQContext *s, const uint8_t *buf, int buf_size, AVFrame *frame, int field_number, int start, int end, int line_stride)
281+{
282+ int ret, slice_number, slice_offsets[5];
283+ int linesize_y = frame->linesize[0] * line_stride;
284+ int linesize_cb = frame->linesize[1] * line_stride;
285+ int linesize_cr = frame->linesize[2] * line_stride;
286+ int linesize_a;
287+
288+ if (s->alpha_type != SHQ_NO_ALPHA)
289+ linesize_a = frame->linesize[3] * line_stride;
290+
291+ if (end < start || end - start < 3 || end > buf_size)
292+ return AVERROR_INVALIDDATA;
293+
294+ slice_offsets[0] = start;
295+ slice_offsets[4] = end;
296+ for (slice_number = 1; slice_number < 4; slice_number++) {
297+ uint32_t last_offset, slice_len;
298+
299+ last_offset = slice_offsets[slice_number - 1];
300+ slice_len = AV_RL24(buf + last_offset);
301+ slice_offsets[slice_number] = last_offset + slice_len;
302+
303+ if (slice_len < 3 || slice_offsets[slice_number] > end - 3)
304+ return AVERROR_INVALIDDATA;
305+ }
306+
307+ for (slice_number = 0; slice_number < 4; slice_number++) {
308+ GetBitContext gb;
309+ uint32_t slice_begin, slice_end;
310+ int x, y;
311+
312+ slice_begin = slice_offsets[slice_number];
313+ slice_end = slice_offsets[slice_number + 1];
314+
315+ if ((ret = init_get_bits8(&gb, buf + slice_begin + 3, slice_end - slice_begin - 3)) < 0)
316+ return ret;
317+
318+ for (y = slice_number * 16 * line_stride; y < frame->height; y += line_stride * 64) {
319+ uint8_t *dest_y, *dest_cb, *dest_cr, *dest_a;
320+ int last_dc[4] = { 1024, 1024, 1024, 1024 };
321+ uint8_t last_alpha[16];
322+
323+ memset(last_alpha, 255, sizeof(last_alpha));
324+
325+ dest_y = frame->data[0] + frame->linesize[0] * (y + field_number);
326+ if (s->subsampling == SHQ_SUBSAMPLING_420) {
327+ dest_cb = frame->data[1] + frame->linesize[1] * (y/2 + field_number);
328+ dest_cr = frame->data[2] + frame->linesize[2] * (y/2 + field_number);
329+ } else {
330+ dest_cb = frame->data[1] + frame->linesize[1] * (y + field_number);
331+ dest_cr = frame->data[2] + frame->linesize[2] * (y + field_number);
332+ }
333+ if (s->alpha_type != SHQ_NO_ALPHA) {
334+ dest_a = frame->data[3] + frame->linesize[3] * (y + field_number);
335+ }
336+
337+ for (x = 0; x < frame->width; x += 16) {
338+ /* Decode the four luma blocks. */
339+ if ((ret = decode_dct_block(s, &gb, last_dc, 0, dest_y, linesize_y)) < 0)
340+ return ret;
341+ if ((ret = decode_dct_block(s, &gb, last_dc, 0, dest_y + 8, linesize_y)) < 0)
342+ return ret;
343+ if ((ret = decode_dct_block(s, &gb, last_dc, 0, dest_y + 8 * linesize_y, linesize_y)) < 0)
344+ return ret;
345+ if ((ret = decode_dct_block(s, &gb, last_dc, 0, dest_y + 8 * linesize_y + 8, linesize_y)) < 0)
346+ return ret;
347+
348+ /*
349+ * Decode the first chroma block. For 4:2:0, this is the only one;
350+ * for 4:2:2, it's the top block; for 4:4:4, it's the top-left block.
351+ */
352+ if ((ret = decode_dct_block(s, &gb, last_dc, 1, dest_cb, linesize_cb)) < 0)
353+ return ret;
354+ if ((ret = decode_dct_block(s, &gb, last_dc, 2, dest_cr, linesize_cr)) < 0)
355+ return ret;
356+
357+ if (s->subsampling != SHQ_SUBSAMPLING_420) {
358+ /* For 4:2:2, this is the bottom block; for 4:4:4, it's the bottom-left block. */
359+ if ((ret = decode_dct_block(s, &gb, last_dc, 1, dest_cb + 8 * linesize_cb, linesize_cb)) < 0)
360+ return ret;
361+ if ((ret = decode_dct_block(s, &gb, last_dc, 2, dest_cr + 8 * linesize_cr, linesize_cr)) < 0)
362+ return ret;
363+
364+ if (s->subsampling == SHQ_SUBSAMPLING_444) {
365+ /* Top-right and bottom-right blocks. */
366+ if ((ret = decode_dct_block(s, &gb, last_dc, 1, dest_cb + 8, linesize_cb)) < 0)
367+ return ret;
368+ if ((ret = decode_dct_block(s, &gb, last_dc, 2, dest_cr + 8, linesize_cr)) < 0)
369+ return ret;
370+ if ((ret = decode_dct_block(s, &gb, last_dc, 1, dest_cb + 8 * linesize_cb + 8, linesize_cb)) < 0)
371+ return ret;
372+ if ((ret = decode_dct_block(s, &gb, last_dc, 2, dest_cr + 8 * linesize_cr + 8, linesize_cr)) < 0)
373+ return ret;
374+
375+ dest_cb += 8;
376+ dest_cr += 8;
377+ }
378+ }
379+ dest_y += 16;
380+ dest_cb += 8;
381+ dest_cr += 8;
382+
383+ if (s->alpha_type == SHQ_RLE_ALPHA) {
384+ /* Alpha coded using 16x8 RLE blocks. */
385+ if ((ret = decode_alpha_block(s, &gb, last_alpha, dest_a, linesize_a)) < 0)
386+ return ret;
387+ if ((ret = decode_alpha_block(s, &gb, last_alpha, dest_a + 8 * linesize_a, linesize_a)) < 0)
388+ return ret;
389+ dest_a += 16;
390+ } else if (s->alpha_type == SHQ_DCT_ALPHA) {
391+ /* Alpha encoded exactly like luma. */
392+ if ((ret = decode_dct_block(s, &gb, last_dc, 3, dest_a, linesize_a)) < 0)
393+ return ret;
394+ if ((ret = decode_dct_block(s, &gb, last_dc, 3, dest_a + 8, linesize_a)) < 0)
395+ return ret;
396+ if ((ret = decode_dct_block(s, &gb, last_dc, 3, dest_a + 8 * linesize_a, linesize_a)) < 0)
397+ return ret;
398+ if ((ret = decode_dct_block(s, &gb, last_dc, 3, dest_a + 8 * linesize_a + 8, linesize_a)) < 0)
399+ return ret;
400+ dest_a += 16;
401+ }
402+ }
403+ }
404+ }
405+
406+ return 0;
407+}
408+
409+static void compute_quant_matrix(int *output, int qscale)
410+{
411+ int i;
412+ for (i = 0; i < 64; i++) output[i] = unscaled_quant_matrix[i] * qscale;
413+}
414+
415+static int speedhq_decode_frame(AVCodecContext *avctx,
416+ void *data, int *got_frame,
417+ AVPacket *avpkt)
418+{
419+ SHQContext * const s = avctx->priv_data;
420+ const uint8_t *buf = avpkt->data;
421+ int buf_size = avpkt->size;
422+ AVFrame *frame = data;
423+ uint8_t quality;
424+ uint32_t second_field_offset;
425+ int ret;
426+
427+ if (buf_size < 4)
428+ return AVERROR_INVALIDDATA;
429+
430+ quality = buf[0];
431+ if (quality >= 100) {
432+ return AVERROR_INVALIDDATA;
433+ }
434+
435+ compute_quant_matrix(s->quant_matrix, 100 - quality);
436+
437+ second_field_offset = AV_RL24(buf + 1);
438+ if (second_field_offset >= buf_size - 3) {
439+ return AVERROR_INVALIDDATA;
440+ }
441+
442+ avctx->coded_width = FFALIGN(avctx->width, 16);
443+ avctx->coded_height = FFALIGN(avctx->height, 16);
444+
445+ if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
446+ return ret;
447+ }
448+ frame->key_frame = 1;
449+
450+ if (second_field_offset == 4) {
451+ /*
452+ * Overlapping first and second fields is used to signal
453+ * encoding only a single field (the second field then comes
454+ * as a separate, later frame).
455+ */
456+ frame->height >>= 1;
457+ if ((ret = decode_speedhq_field(s, buf, buf_size, frame, 0, 4, buf_size, 1)) < 0)
458+ return ret;
459+ } else {
460+ if ((ret = decode_speedhq_field(s, buf, buf_size, frame, 0, 4, second_field_offset, 2)) < 0)
461+ return ret;
462+ if ((ret = decode_speedhq_field(s, buf, buf_size, frame, 1, second_field_offset, buf_size, 2)) < 0)
463+ return ret;
464+ }
465+
466+ *got_frame = 1;
467+ return buf_size;
468+}
469+
470+/*
471+ * Alpha VLC. Run and level are independently coded, and would be
472+ * outside the default limits for MAX_RUN/MAX_LEVEL, so we don't
473+ * bother with combining them into one table.
474+ */
475+static av_cold void compute_alpha_vlcs(void)
476+{
477+ uint16_t run_code[129], level_code[256];
478+ uint8_t run_bits[129], level_bits[256];
479+ int run, level;
480+
481+ for (run = 0; run < 128; run++) {
482+ if (!run) {
483+ /* 0 -> 0. */
484+ run_code[run] = 0;
485+ run_bits[run] = 1;
486+ } else if (run <= 4) {
487+ /* 10xx -> xx plus 1. */
488+ run_code[run] = ((run - 1) << 2) | 1;
489+ run_bits[run] = 4;
490+ } else {
491+ /* 111xxxxxxx -> xxxxxxxx. */
492+ run_code[run] = (run << 3) | 7;
493+ run_bits[run] = 10;
494+ }
495+ }
496+
497+ /* 110 -> EOB. */
498+ run_code[128] = 3;
499+ run_bits[128] = 3;
500+
501+ INIT_LE_VLC_STATIC(&ff_dc_alpha_run_vlc_le, ALPHA_VLC_BITS, 129,
502+ run_bits, 1, 1,
503+ run_code, 2, 2, 160);
504+
505+ for (level = 0; level < 256; level++) {
506+ int8_t signed_level = (int8_t)level;
507+ int abs_signed_level = abs(signed_level);
508+ int sign = (signed_level < 0) ? 1 : 0;
509+
510+ if (abs_signed_level == 1) {
511+ /* 1s -> -1 or +1 (depending on sign bit). */
512+ level_code[level] = (sign << 1) | 1;
513+ level_bits[level] = 2;
514+ } else if (abs_signed_level >= 2 && abs_signed_level <= 5) {
515+ /* 01sxx -> xx plus 2 (2..5 or -2..-5, depending on sign bit). */
516+ level_code[level] = ((abs_signed_level - 2) << 3) | (sign << 2) | 2;
517+ level_bits[level] = 5;
518+ } else {
519+ /*
520+ * 00xxxxxxxx -> xxxxxxxx, in two's complement. 0 is technically an
521+ * illegal code (that would be encoded by increasing run), but it
522+ * doesn't hurt and simplifies indexing.
523+ */
524+ level_code[level] = level << 2;
525+ level_bits[level] = 10;
526+ }
527+ }
528+
529+ INIT_LE_VLC_STATIC(&ff_dc_alpha_level_vlc_le, ALPHA_VLC_BITS, 256,
530+ level_bits, 1, 1,
531+ level_code, 2, 2, 288);
532+}
533+
534+static uint32_t reverse(uint32_t num, int bits)
535+{
536+ return bitswap_32(num) >> (32 - bits);
537+}
538+
539+static void reverse_code(const uint16_t *code, const uint8_t *bits,
540+ uint16_t *reversed_code, int num_entries)
541+{
542+ int i;
543+ for (i = 0; i < num_entries; i++) {
544+ reversed_code[i] = reverse(code[i], bits[i]);
545+ }
546+}
547+
548+static av_cold void speedhq_static_init(void)
549+{
550+ uint16_t ff_mpeg12_vlc_dc_lum_code_reversed[12];
551+ uint16_t ff_mpeg12_vlc_dc_chroma_code_reversed[12];
552+ int i;
553+
554+ /* Exactly the same as MPEG-2, except little-endian. */
555+ reverse_code(ff_mpeg12_vlc_dc_lum_code,
556+ ff_mpeg12_vlc_dc_lum_bits,
557+ ff_mpeg12_vlc_dc_lum_code_reversed,
558+ 12);
559+ INIT_LE_VLC_STATIC(&ff_dc_lum_vlc_le, DC_VLC_BITS, 12,
560+ ff_mpeg12_vlc_dc_lum_bits, 1, 1,
561+ ff_mpeg12_vlc_dc_lum_code_reversed, 2, 2, 512);
562+ reverse_code(ff_mpeg12_vlc_dc_chroma_code,
563+ ff_mpeg12_vlc_dc_chroma_bits,
564+ ff_mpeg12_vlc_dc_chroma_code_reversed,
565+ 12);
566+ INIT_LE_VLC_STATIC(&ff_dc_chroma_vlc_le, DC_VLC_BITS, 12,
567+ ff_mpeg12_vlc_dc_chroma_bits, 1, 1,
568+ ff_mpeg12_vlc_dc_chroma_code_reversed, 2, 2, 514);
569+
570+ /* Reverse the AC VLC, because INIT_VLC_LE wants it in that order. */
571+ for (i = 0; i < FF_ARRAY_ELEMS(speedhq_vlc); ++i) {
572+ speedhq_vlc[i][0] = reverse(speedhq_vlc[i][0], speedhq_vlc[i][1]);
573+ }
574+ ff_rl_init(&ff_rl_speedhq, ff_speedhq_static_rl_table_store);
575+ INIT_2D_VLC_RL(ff_rl_speedhq, 674, INIT_VLC_LE);
576+
577+ compute_alpha_vlcs();
578+}
579+
580+static av_cold int speedhq_decode_init(AVCodecContext *avctx)
581+{
582+ int ret;
583+ static AVOnce init_once = AV_ONCE_INIT;
584+ SHQContext * const s = avctx->priv_data;
585+
586+ s->avctx = avctx;
587+
588+ ret = ff_thread_once(&init_once, speedhq_static_init);
589+ if (ret)
590+ return AVERROR_UNKNOWN;
591+
592+ ff_blockdsp_init(&s->bdsp, avctx);
593+ ff_idctdsp_init(&s->idsp, avctx);
594+ ff_init_scantable(s->idsp.idct_permutation, &s->intra_scantable, ff_zigzag_direct);
595+
596+ switch (avctx->codec_tag) {
597+ case MKTAG('S', 'H', 'Q', '0'):
598+ s->subsampling = SHQ_SUBSAMPLING_420;
599+ s->alpha_type = SHQ_NO_ALPHA;
600+ avctx->pix_fmt = AV_PIX_FMT_YUV420P;
601+ break;
602+ case MKTAG('S', 'H', 'Q', '1'):
603+ s->subsampling = SHQ_SUBSAMPLING_420;
604+ s->alpha_type = SHQ_RLE_ALPHA;
605+ avctx->pix_fmt = AV_PIX_FMT_YUVA420P;
606+ break;
607+ case MKTAG('S', 'H', 'Q', '2'):
608+ s->subsampling = SHQ_SUBSAMPLING_422;
609+ s->alpha_type = SHQ_NO_ALPHA;
610+ avctx->pix_fmt = AV_PIX_FMT_YUV422P;
611+ break;
612+ case MKTAG('S', 'H', 'Q', '3'):
613+ s->subsampling = SHQ_SUBSAMPLING_422;
614+ s->alpha_type = SHQ_RLE_ALPHA;
615+ avctx->pix_fmt = AV_PIX_FMT_YUVA422P;
616+ break;
617+ case MKTAG('S', 'H', 'Q', '4'):
618+ s->subsampling = SHQ_SUBSAMPLING_444;
619+ s->alpha_type = SHQ_NO_ALPHA;
620+ avctx->pix_fmt = AV_PIX_FMT_YUV444P;
621+ break;
622+ case MKTAG('S', 'H', 'Q', '5'):
623+ s->subsampling = SHQ_SUBSAMPLING_444;
624+ s->alpha_type = SHQ_RLE_ALPHA;
625+ avctx->pix_fmt = AV_PIX_FMT_YUVA444P;
626+ break;
627+ case MKTAG('S', 'H', 'Q', '7'):
628+ s->subsampling = SHQ_SUBSAMPLING_422;
629+ s->alpha_type = SHQ_DCT_ALPHA;
630+ avctx->pix_fmt = AV_PIX_FMT_YUVA422P;
631+ break;
632+ case MKTAG('S', 'H', 'Q', '9'):
633+ s->subsampling = SHQ_SUBSAMPLING_444;
634+ s->alpha_type = SHQ_DCT_ALPHA;
635+ avctx->pix_fmt = AV_PIX_FMT_YUVA444P;
636+ break;
637+ default:
638+ av_log(avctx, AV_LOG_ERROR, "Unknown NewTek SpeedHQ FOURCC provided (%08X)\n",
639+ avctx->codec_tag);
640+ return AVERROR_INVALIDDATA;
641+ }
642+
643+ /* This matches what NDI's RGB -> Y'CbCr 4:2:2 converter uses. */
644+ avctx->colorspace = AVCOL_SPC_BT470BG;
645+ avctx->chroma_sample_location = AVCHROMA_LOC_CENTER;
646+
647+ return 0;
648+}
649+
650+AVCodec ff_speedhq_decoder = {
651+ .name = "speedhq",
652+ .long_name = NULL_IF_CONFIG_SMALL("NewTek SpeedHQ"),
653+ .type = AVMEDIA_TYPE_VIDEO,
654+ .id = AV_CODEC_ID_SPEEDHQ,
655+ .priv_data_size = sizeof(SHQContext),
656+ .init = speedhq_decode_init,
657+ .decode = speedhq_decode_frame,
658+ .capabilities = AV_CODEC_CAP_DR1,
659+};
libavcodec/version.h+2−2
@@ -28,8 +28,8 @@ · 27 unmodified lines
2828 #include "libavutil/version.h"
2929
3030 #define LIBAVCODEC_VERSION_MAJOR 57
31−#define LIBAVCODEC_VERSION_MINOR 71
32−#define LIBAVCODEC_VERSION_MICRO 101
31+#define LIBAVCODEC_VERSION_MINOR 72
32+#define LIBAVCODEC_VERSION_MICRO 100
3333
3434 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
3535 LIBAVCODEC_VERSION_MINOR, \
libavcodec/vlc.h+9−0
@@ -62,4 +62,13 @@ void ff_free_vlc(VLC *vlc); · 61 unmodified lines
6262 init_vlc(vlc, bits, a, b, c, d, e, f, g, INIT_VLC_USE_NEW_STATIC); \
6363 } while (0)
6464
65+#define INIT_LE_VLC_STATIC(vlc, bits, a, b, c, d, e, f, g, static_size) \
66+ do { \
67+ static VLC_TYPE table[static_size][2]; \
68+ (vlc)->table = table; \
69+ (vlc)->table_allocated = static_size; \
70+ init_vlc(vlc, bits, a, b, c, d, e, f, g, \
71+ INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE); \
72+ } while (0)
73+
6574 #endif /* AVCODEC_VLC_H */
libavformat/riff.c+8−0
@@ -440,6 +440,14 @@ const AVCodecTag ff_codec_bmp_tags[] = { · 439 unmodified lines
440440 { AV_CODEC_ID_MAGICYUV, MKTAG('M', '0', 'G', '0') },
441441 { AV_CODEC_ID_MAGICYUV, MKTAG('M', '0', 'Y', '2') },
442442 { AV_CODEC_ID_YLC, MKTAG('Y', 'L', 'C', '0') },
443+ { AV_CODEC_ID_SPEEDHQ, MKTAG('S', 'H', 'Q', '0') },
444+ { AV_CODEC_ID_SPEEDHQ, MKTAG('S', 'H', 'Q', '1') },
445+ { AV_CODEC_ID_SPEEDHQ, MKTAG('S', 'H', 'Q', '2') },
446+ { AV_CODEC_ID_SPEEDHQ, MKTAG('S', 'H', 'Q', '3') },
447+ { AV_CODEC_ID_SPEEDHQ, MKTAG('S', 'H', 'Q', '4') },
448+ { AV_CODEC_ID_SPEEDHQ, MKTAG('S', 'H', 'Q', '5') },
449+ { AV_CODEC_ID_SPEEDHQ, MKTAG('S', 'H', 'Q', '7') },
450+ { AV_CODEC_ID_SPEEDHQ, MKTAG('S', 'H', 'Q', '9') },
443451
444452 { AV_CODEC_ID_NONE, 0 }
445453 };

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t