3 * Copyright 2017 Steinar H. Gunderson
5 * This file is part of FFmpeg.
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.
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.
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
24 * NewTek SpeedHQ decoder.
27 #define BITSTREAM_READER_LE
30 #include "libavutil/attributes.h"
35 #include "libavutil/thread.h"
38 #include "mpeg12data.h"
39 #include "mpeg12vlc.h"
41 #define MAX_INDEX (64 - 1)
44 * 5 bits makes for very small tables, with no more than two lookups needed
45 * for the longest (10-bit) codes.
47 #define ALPHA_VLC_BITS 5
49 typedef struct SHQContext {
50 AVCodecContext *avctx;
53 ScanTable intra_scantable;
55 enum { SHQ_SUBSAMPLING_420, SHQ_SUBSAMPLING_422, SHQ_SUBSAMPLING_444 }
57 enum { SHQ_NO_ALPHA, SHQ_RLE_ALPHA, SHQ_DCT_ALPHA } alpha_type;
61 /* AC codes: Very similar but not identical to MPEG-2. */
62 static const uint16_t speedhq_vlc[123][2] = {
63 {0x0001, 2}, {0x0003, 3}, {0x000E, 4}, {0x0007, 5},
64 {0x0017, 5}, {0x0028, 6}, {0x0008, 6}, {0x006F, 7},
65 {0x001F, 7}, {0x00C4, 8}, {0x0044, 8}, {0x005F, 8},
66 {0x00DF, 8}, {0x007F, 8}, {0x00FF, 8}, {0x3E00, 14},
67 {0x1E00, 14}, {0x2E00, 14}, {0x0E00, 14}, {0x3600, 14},
68 {0x1600, 14}, {0x2600, 14}, {0x0600, 14}, {0x3A00, 14},
69 {0x1A00, 14}, {0x2A00, 14}, {0x0A00, 14}, {0x3200, 14},
70 {0x1200, 14}, {0x2200, 14}, {0x0200, 14}, {0x0C00, 15},
71 {0x7400, 15}, {0x3400, 15}, {0x5400, 15}, {0x1400, 15},
72 {0x6400, 15}, {0x2400, 15}, {0x4400, 15}, {0x0400, 15},
73 {0x0002, 3}, {0x000C, 5}, {0x004F, 7}, {0x00E4, 8},
74 {0x0004, 8}, {0x0D00, 13}, {0x1500, 13}, {0x7C00, 15},
75 {0x3C00, 15}, {0x5C00, 15}, {0x1C00, 15}, {0x6C00, 15},
76 {0x2C00, 15}, {0x4C00, 15}, {0xC800, 16}, {0x4800, 16},
77 {0x8800, 16}, {0x0800, 16}, {0x0300, 13}, {0x1D00, 13},
78 {0x0014, 5}, {0x0070, 7}, {0x003F, 8}, {0x00C0, 10},
79 {0x0500, 13}, {0x0180, 12}, {0x0280, 12}, {0x0C80, 12},
80 {0x0080, 12}, {0x0B00, 13}, {0x1300, 13}, {0x001C, 5},
81 {0x0064, 8}, {0x0380, 12}, {0x1900, 13}, {0x0D80, 12},
82 {0x0018, 6}, {0x00BF, 8}, {0x0480, 12}, {0x0B80, 12},
83 {0x0038, 6}, {0x0040, 9}, {0x0900, 13}, {0x0030, 7},
84 {0x0780, 12}, {0x2800, 16}, {0x0010, 7}, {0x0A80, 12},
85 {0x0050, 7}, {0x0880, 12}, {0x000F, 7}, {0x1100, 13},
86 {0x002F, 7}, {0x0100, 13}, {0x0084, 8}, {0x5800, 16},
87 {0x00A4, 8}, {0x9800, 16}, {0x0024, 8}, {0x1800, 16},
88 {0x0140, 9}, {0xE800, 16}, {0x01C0, 9}, {0x6800, 16},
89 {0x02C0, 10}, {0xA800, 16}, {0x0F80, 12}, {0x0580, 12},
90 {0x0980, 12}, {0x0E80, 12}, {0x0680, 12}, {0x1F00, 13},
91 {0x0F00, 13}, {0x1700, 13}, {0x0700, 13}, {0x1B00, 13},
92 {0xF800, 16}, {0x7800, 16}, {0xB800, 16}, {0x3800, 16},
94 {0x0020, 6}, /* escape */
98 static const uint8_t speedhq_level[121] = {
99 1, 2, 3, 4, 5, 6, 7, 8,
100 9, 10, 11, 12, 13, 14, 15, 16,
101 17, 18, 19, 20, 21, 22, 23, 24,
102 25, 26, 27, 28, 29, 30, 31, 32,
103 33, 34, 35, 36, 37, 38, 39, 40,
104 1, 2, 3, 4, 5, 6, 7, 8,
105 9, 10, 11, 12, 13, 14, 15, 16,
106 17, 18, 19, 20, 1, 2, 3, 4,
107 5, 6, 7, 8, 9, 10, 11, 1,
108 2, 3, 4, 5, 1, 2, 3, 4,
109 1, 2, 3, 1, 2, 3, 1, 2,
110 1, 2, 1, 2, 1, 2, 1, 2,
111 1, 2, 1, 2, 1, 2, 1, 2,
112 1, 2, 1, 1, 1, 1, 1, 1,
113 1, 1, 1, 1, 1, 1, 1, 1,
117 static const uint8_t speedhq_run[121] = {
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 0, 0, 0, 0, 0, 0, 0, 0,
123 1, 1, 1, 1, 1, 1, 1, 1,
124 1, 1, 1, 1, 1, 1, 1, 1,
125 1, 1, 1, 1, 2, 2, 2, 2,
126 2, 2, 2, 2, 2, 2, 2, 3,
127 3, 3, 3, 3, 4, 4, 4, 4,
128 5, 5, 5, 6, 6, 6, 7, 7,
129 8, 8, 9, 9, 10, 10, 11, 11,
130 12, 12, 13, 13, 14, 14, 15, 15,
131 16, 16, 17, 18, 19, 20, 21, 22,
132 23, 24, 25, 26, 27, 28, 29, 30,
136 RLTable ff_rl_speedhq = {
144 #if CONFIG_SPEEDHQ_DECODER
145 /* NOTE: The first element is always 16, unscaled. */
146 static const uint8_t unscaled_quant_matrix[64] = {
147 16, 16, 19, 22, 26, 27, 29, 34,
148 16, 16, 22, 24, 27, 29, 34, 37,
149 19, 22, 26, 27, 29, 34, 34, 38,
150 22, 22, 26, 27, 29, 34, 37, 40,
151 22, 26, 27, 29, 32, 35, 40, 48,
152 26, 27, 29, 32, 35, 40, 48, 58,
153 26, 27, 29, 34, 38, 46, 56, 69,
154 27, 29, 35, 38, 46, 56, 69, 83
157 static uint8_t speedhq_static_rl_table_store[2][2*MAX_RUN + MAX_LEVEL + 3];
159 static VLC dc_lum_vlc_le;
160 static VLC dc_chroma_vlc_le;
161 static VLC dc_alpha_run_vlc_le;
162 static VLC dc_alpha_level_vlc_le;
164 static inline int decode_dc_le(GetBitContext *gb, int component)
168 if (component == 0 || component == 3) {
169 code = get_vlc2(gb, dc_lum_vlc_le.table, DC_VLC_BITS, 2);
171 code = get_vlc2(gb, dc_chroma_vlc_le.table, DC_VLC_BITS, 2);
176 diff = get_xbits_le(gb, code);
181 static inline int decode_alpha_block(const SHQContext *s, GetBitContext *gb, uint8_t last_alpha[16], uint8_t *dest, int linesize)
186 memset(block, 0, sizeof(block));
194 UPDATE_CACHE_LE(re, gb);
195 GET_VLC(run, re, gb, dc_alpha_run_vlc_le.table, ALPHA_VLC_BITS, 2);
200 return AVERROR_INVALIDDATA;
202 UPDATE_CACHE_LE(re, gb);
203 GET_VLC(level, re, gb, dc_alpha_level_vlc_le.table, ALPHA_VLC_BITS, 2);
207 CLOSE_READER(re, gb);
210 for (y = 0; y < 8; y++) {
211 for (x = 0; x < 16; x++) {
212 last_alpha[x] -= block[y * 16 + x];
214 memcpy(dest, last_alpha, 16);
221 static inline int decode_dct_block(const SHQContext *s, GetBitContext *gb, int last_dc[4], int component, uint8_t *dest, int linesize)
223 const int *quant_matrix = s->quant_matrix;
224 const uint8_t *scantable = s->intra_scantable.permutated;
225 LOCAL_ALIGNED_32(int16_t, block, [64]);
228 s->bdsp.clear_block(block);
230 dc_offset = decode_dc_le(gb, component);
231 last_dc[component] -= dc_offset; /* Note: Opposite of most codecs. */
232 block[scantable[0]] = last_dc[component]; /* quant_matrix[0] is always 16. */
234 /* Read AC coefficients. */
240 UPDATE_CACHE_LE(re, gb);
241 GET_RL_VLC(level, run, re, gb, ff_rl_speedhq.rl_vlc[0],
248 return AVERROR_INVALIDDATA;
249 /* If next bit is 1, level = -level */
250 level = (level ^ SHOW_SBITS(re, gb, 1)) -
251 SHOW_SBITS(re, gb, 1);
252 LAST_SKIP_BITS(re, gb, 1);
255 #if MIN_CACHE_BITS < 6 + 6 + 12
256 #error MIN_CACHE_BITS is too small for the escape code, add UPDATE_CACHE
258 run = SHOW_UBITS(re, gb, 6) + 1;
259 SKIP_BITS(re, gb, 6);
260 level = SHOW_UBITS(re, gb, 12) - 2048;
261 LAST_SKIP_BITS(re, gb, 12);
265 return AVERROR_INVALIDDATA;
268 block[scantable[i]] = (level * quant_matrix[i]) >> 4;
270 CLOSE_READER(re, gb);
273 s->idsp.idct_put(dest, linesize, block);
278 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)
280 int ret, slice_number, slice_offsets[5];
281 int linesize_y = frame->linesize[0] * line_stride;
282 int linesize_cb = frame->linesize[1] * line_stride;
283 int linesize_cr = frame->linesize[2] * line_stride;
286 if (s->alpha_type != SHQ_NO_ALPHA)
287 linesize_a = frame->linesize[3] * line_stride;
289 if (end < start || end - start < 3 || end > buf_size)
290 return AVERROR_INVALIDDATA;
292 slice_offsets[0] = start;
293 slice_offsets[4] = end;
294 for (slice_number = 1; slice_number < 4; slice_number++) {
295 uint32_t last_offset, slice_len;
297 last_offset = slice_offsets[slice_number - 1];
298 slice_len = AV_RL24(buf + last_offset);
299 slice_offsets[slice_number] = last_offset + slice_len;
301 if (slice_len < 3 || slice_offsets[slice_number] > end - 3)
302 return AVERROR_INVALIDDATA;
305 for (slice_number = 0; slice_number < 4; slice_number++) {
307 uint32_t slice_begin, slice_end;
310 slice_begin = slice_offsets[slice_number];
311 slice_end = slice_offsets[slice_number + 1];
313 if ((ret = init_get_bits8(&gb, buf + slice_begin + 3, slice_end - slice_begin - 3)) < 0)
316 for (y = slice_number * 16 * line_stride; y < frame->height; y += line_stride * 64) {
317 uint8_t *dest_y, *dest_cb, *dest_cr, *dest_a;
318 int last_dc[4] = { 1024, 1024, 1024, 1024 };
319 uint8_t last_alpha[16];
321 memset(last_alpha, 255, sizeof(last_alpha));
323 dest_y = frame->data[0] + frame->linesize[0] * (y + field_number);
324 if (s->subsampling == SHQ_SUBSAMPLING_420) {
325 dest_cb = frame->data[1] + frame->linesize[1] * (y/2 + field_number);
326 dest_cr = frame->data[2] + frame->linesize[2] * (y/2 + field_number);
328 dest_cb = frame->data[1] + frame->linesize[1] * (y + field_number);
329 dest_cr = frame->data[2] + frame->linesize[2] * (y + field_number);
331 if (s->alpha_type != SHQ_NO_ALPHA) {
332 dest_a = frame->data[3] + frame->linesize[3] * (y + field_number);
335 for (x = 0; x < frame->width; x += 16) {
336 /* Decode the four luma blocks. */
337 if ((ret = decode_dct_block(s, &gb, last_dc, 0, dest_y, linesize_y)) < 0)
339 if ((ret = decode_dct_block(s, &gb, last_dc, 0, dest_y + 8, linesize_y)) < 0)
341 if ((ret = decode_dct_block(s, &gb, last_dc, 0, dest_y + 8 * linesize_y, linesize_y)) < 0)
343 if ((ret = decode_dct_block(s, &gb, last_dc, 0, dest_y + 8 * linesize_y + 8, linesize_y)) < 0)
347 * Decode the first chroma block. For 4:2:0, this is the only one;
348 * for 4:2:2, it's the top block; for 4:4:4, it's the top-left block.
350 if ((ret = decode_dct_block(s, &gb, last_dc, 1, dest_cb, linesize_cb)) < 0)
352 if ((ret = decode_dct_block(s, &gb, last_dc, 2, dest_cr, linesize_cr)) < 0)
355 if (s->subsampling != SHQ_SUBSAMPLING_420) {
356 /* For 4:2:2, this is the bottom block; for 4:4:4, it's the bottom-left block. */
357 if ((ret = decode_dct_block(s, &gb, last_dc, 1, dest_cb + 8 * linesize_cb, linesize_cb)) < 0)
359 if ((ret = decode_dct_block(s, &gb, last_dc, 2, dest_cr + 8 * linesize_cr, linesize_cr)) < 0)
362 if (s->subsampling == SHQ_SUBSAMPLING_444) {
363 /* Top-right and bottom-right blocks. */
364 if ((ret = decode_dct_block(s, &gb, last_dc, 1, dest_cb + 8, linesize_cb)) < 0)
366 if ((ret = decode_dct_block(s, &gb, last_dc, 2, dest_cr + 8, linesize_cr)) < 0)
368 if ((ret = decode_dct_block(s, &gb, last_dc, 1, dest_cb + 8 * linesize_cb + 8, linesize_cb)) < 0)
370 if ((ret = decode_dct_block(s, &gb, last_dc, 2, dest_cr + 8 * linesize_cr + 8, linesize_cr)) < 0)
381 if (s->alpha_type == SHQ_RLE_ALPHA) {
382 /* Alpha coded using 16x8 RLE blocks. */
383 if ((ret = decode_alpha_block(s, &gb, last_alpha, dest_a, linesize_a)) < 0)
385 if ((ret = decode_alpha_block(s, &gb, last_alpha, dest_a + 8 * linesize_a, linesize_a)) < 0)
388 } else if (s->alpha_type == SHQ_DCT_ALPHA) {
389 /* Alpha encoded exactly like luma. */
390 if ((ret = decode_dct_block(s, &gb, last_dc, 3, dest_a, linesize_a)) < 0)
392 if ((ret = decode_dct_block(s, &gb, last_dc, 3, dest_a + 8, linesize_a)) < 0)
394 if ((ret = decode_dct_block(s, &gb, last_dc, 3, dest_a + 8 * linesize_a, linesize_a)) < 0)
396 if ((ret = decode_dct_block(s, &gb, last_dc, 3, dest_a + 8 * linesize_a + 8, linesize_a)) < 0)
407 static void compute_quant_matrix(int *output, int qscale)
410 for (i = 0; i < 64; i++) output[i] = unscaled_quant_matrix[ff_zigzag_direct[i]] * qscale;
413 static int speedhq_decode_frame(AVCodecContext *avctx,
414 void *data, int *got_frame,
417 SHQContext * const s = avctx->priv_data;
418 const uint8_t *buf = avpkt->data;
419 int buf_size = avpkt->size;
420 AVFrame *frame = data;
422 uint32_t second_field_offset;
426 return AVERROR_INVALIDDATA;
429 if (quality >= 100) {
430 return AVERROR_INVALIDDATA;
433 compute_quant_matrix(s->quant_matrix, 100 - quality);
435 second_field_offset = AV_RL24(buf + 1);
436 if (second_field_offset >= buf_size - 3) {
437 return AVERROR_INVALIDDATA;
440 avctx->coded_width = FFALIGN(avctx->width, 16);
441 avctx->coded_height = FFALIGN(avctx->height, 16);
443 if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
446 frame->key_frame = 1;
448 if (second_field_offset == 4 || second_field_offset == (buf_size-4)) {
450 * Overlapping first and second fields is used to signal
451 * encoding only a single field. In this case, "height"
452 * is ambiguous; it could mean either the height of the
453 * frame as a whole, or of the field. The former would make
454 * more sense for compatibility with legacy decoders,
455 * but this matches the convention used in NDI, which is
456 * the primary user of this trick.
458 if ((ret = decode_speedhq_field(s, buf, buf_size, frame, 0, 4, buf_size, 1)) < 0)
461 if ((ret = decode_speedhq_field(s, buf, buf_size, frame, 0, 4, second_field_offset, 2)) < 0)
463 if ((ret = decode_speedhq_field(s, buf, buf_size, frame, 1, second_field_offset, buf_size, 2)) < 0)
472 * Alpha VLC. Run and level are independently coded, and would be
473 * outside the default limits for MAX_RUN/MAX_LEVEL, so we don't
474 * bother with combining them into one table.
476 static av_cold void compute_alpha_vlcs(void)
478 uint16_t run_code[134], level_code[266];
479 uint8_t run_bits[134], level_bits[266];
480 int16_t run_symbols[134], level_symbols[266];
483 /* Initialize VLC for alpha run. */
489 run_symbols[entry] = 0;
492 /* 10xx -> xx plus 1. */
493 for (i = 0; i < 4; ++i) {
494 run_code[entry] = (i << 2) | 1;
496 run_symbols[entry] = i + 1;
500 /* 111xxxxxxx -> xxxxxxx. */
501 for (i = 0; i < 128; ++i) {
502 run_code[entry] = (i << 3) | 7;
503 run_bits[entry] = 10;
504 run_symbols[entry] = i;
511 run_symbols[entry] = -1;
514 av_assert0(entry == FF_ARRAY_ELEMS(run_code));
516 INIT_LE_VLC_SPARSE_STATIC(&dc_alpha_run_vlc_le, ALPHA_VLC_BITS,
517 FF_ARRAY_ELEMS(run_code),
520 run_symbols, 2, 2, 160);
522 /* Initialize VLC for alpha level. */
525 for (sign = 0; sign <= 1; ++sign) {
526 /* 1s -> -1 or +1 (depending on sign bit). */
527 level_code[entry] = (sign << 1) | 1;
528 level_bits[entry] = 2;
529 level_symbols[entry] = sign ? -1 : 1;
532 /* 01sxx -> xx plus 2 (2..5 or -2..-5, depending on sign bit). */
533 for (i = 0; i < 4; ++i) {
534 level_code[entry] = (i << 3) | (sign << 2) | 2;
535 level_bits[entry] = 5;
536 level_symbols[entry] = sign ? -(i + 2) : (i + 2);
542 * 00xxxxxxxx -> xxxxxxxx, in two's complement. There are many codes
543 * here that would better be encoded in other ways (e.g. 0 would be
544 * encoded by increasing run, and +/- 1 would be encoded with a
545 * shorter code), but it doesn't hurt to allow everything.
547 for (i = 0; i < 256; ++i) {
548 level_code[entry] = i << 2;
549 level_bits[entry] = 10;
550 level_symbols[entry] = i;
554 av_assert0(entry == FF_ARRAY_ELEMS(level_code));
556 INIT_LE_VLC_SPARSE_STATIC(&dc_alpha_level_vlc_le, ALPHA_VLC_BITS,
557 FF_ARRAY_ELEMS(level_code),
560 level_symbols, 2, 2, 288);
563 static av_cold void speedhq_static_init(void)
565 /* Exactly the same as MPEG-2, except for a little-endian reader. */
566 INIT_CUSTOM_VLC_STATIC(&dc_lum_vlc_le, DC_VLC_BITS, 12,
567 ff_mpeg12_vlc_dc_lum_bits, 1, 1,
568 ff_mpeg12_vlc_dc_lum_code, 2, 2,
569 INIT_VLC_OUTPUT_LE, 512);
570 INIT_CUSTOM_VLC_STATIC(&dc_chroma_vlc_le, DC_VLC_BITS, 12,
571 ff_mpeg12_vlc_dc_chroma_bits, 1, 1,
572 ff_mpeg12_vlc_dc_chroma_code, 2, 2,
573 INIT_VLC_OUTPUT_LE, 514);
575 ff_rl_init(&ff_rl_speedhq, speedhq_static_rl_table_store);
576 INIT_2D_VLC_RL(ff_rl_speedhq, 674, INIT_VLC_LE);
578 compute_alpha_vlcs();
581 static av_cold int speedhq_decode_init(AVCodecContext *avctx)
584 static AVOnce init_once = AV_ONCE_INIT;
585 SHQContext * const s = avctx->priv_data;
589 ret = ff_thread_once(&init_once, speedhq_static_init);
591 return AVERROR_UNKNOWN;
593 ff_blockdsp_init(&s->bdsp, avctx);
594 ff_idctdsp_init(&s->idsp, avctx);
595 ff_init_scantable(s->idsp.idct_permutation, &s->intra_scantable, ff_zigzag_direct);
597 switch (avctx->codec_tag) {
598 case MKTAG('S', 'H', 'Q', '0'):
599 s->subsampling = SHQ_SUBSAMPLING_420;
600 s->alpha_type = SHQ_NO_ALPHA;
601 avctx->pix_fmt = AV_PIX_FMT_YUV420P;
603 case MKTAG('S', 'H', 'Q', '1'):
604 s->subsampling = SHQ_SUBSAMPLING_420;
605 s->alpha_type = SHQ_RLE_ALPHA;
606 avctx->pix_fmt = AV_PIX_FMT_YUVA420P;
608 case MKTAG('S', 'H', 'Q', '2'):
609 s->subsampling = SHQ_SUBSAMPLING_422;
610 s->alpha_type = SHQ_NO_ALPHA;
611 avctx->pix_fmt = AV_PIX_FMT_YUV422P;
613 case MKTAG('S', 'H', 'Q', '3'):
614 s->subsampling = SHQ_SUBSAMPLING_422;
615 s->alpha_type = SHQ_RLE_ALPHA;
616 avctx->pix_fmt = AV_PIX_FMT_YUVA422P;
618 case MKTAG('S', 'H', 'Q', '4'):
619 s->subsampling = SHQ_SUBSAMPLING_444;
620 s->alpha_type = SHQ_NO_ALPHA;
621 avctx->pix_fmt = AV_PIX_FMT_YUV444P;
623 case MKTAG('S', 'H', 'Q', '5'):
624 s->subsampling = SHQ_SUBSAMPLING_444;
625 s->alpha_type = SHQ_RLE_ALPHA;
626 avctx->pix_fmt = AV_PIX_FMT_YUVA444P;
628 case MKTAG('S', 'H', 'Q', '7'):
629 s->subsampling = SHQ_SUBSAMPLING_422;
630 s->alpha_type = SHQ_DCT_ALPHA;
631 avctx->pix_fmt = AV_PIX_FMT_YUVA422P;
633 case MKTAG('S', 'H', 'Q', '9'):
634 s->subsampling = SHQ_SUBSAMPLING_444;
635 s->alpha_type = SHQ_DCT_ALPHA;
636 avctx->pix_fmt = AV_PIX_FMT_YUVA444P;
639 av_log(avctx, AV_LOG_ERROR, "Unknown NewTek SpeedHQ FOURCC provided (%08X)\n",
641 return AVERROR_INVALIDDATA;
644 /* This matches what NDI's RGB -> Y'CbCr 4:2:2 converter uses. */
645 avctx->colorspace = AVCOL_SPC_BT470BG;
646 avctx->chroma_sample_location = AVCHROMA_LOC_CENTER;
651 AVCodec ff_speedhq_decoder = {
653 .long_name = NULL_IF_CONFIG_SMALL("NewTek SpeedHQ"),
654 .type = AVMEDIA_TYPE_VIDEO,
655 .id = AV_CODEC_ID_SPEEDHQ,
656 .priv_data_size = sizeof(SHQContext),
657 .init = speedhq_decode_init,
658 .decode = speedhq_decode_frame,
659 .capabilities = AV_CODEC_CAP_DR1,
661 #endif /* CONFIG_SPEEDHQ_DECODER */