1 /*
2 * Copyright (c) 2015-2016 Kieran Kunhya <kieran@kunhya.com>
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 /**
22 * @file
23 * CFHD Video Decoder
24 */
25
31
37
38 #define SUBBAND_COUNT 10
39
41 {
43
46
48 }
49
51 {
55 }
56
58 {
71 }
72
73 /* TODO: merge with VLC tables or use LUT */
75 {
76 int64_t abslevel = abs(level);
77 return (abslevel + ((768 * abslevel * abslevel * abslevel) / (255 * 255 * 255))) *
FFSIGN(level) * quantisation;
78 }
79
80 static inline void filter(int16_t *output, ptrdiff_t out_stride, int16_t *low, ptrdiff_t low_stride,
82 {
84
85 int i;
86 for (i = 0; i <
len; i++) {
87 if (i == 0) {
88 tmp = (11*low[0*low_stride] - 4*low[1*low_stride] + low[2*low_stride] + 4) >> 3;
89 output[(2*i+0)*out_stride] = (tmp + high[0*high_stride]) >> 1;
90 if (clip)
92
93 tmp = ( 5*low[0*low_stride] + 4*low[1*low_stride] - low[2*low_stride] + 4) >> 3;
94 output[(2*i+1)*out_stride] = (tmp - high[0*high_stride]) >> 1;
95 if (clip)
97 } else if (i == len-1) {
98 tmp = ( 5*low[i*low_stride] + 4*low[(i-1)*low_stride] - low[(i-2)*low_stride] + 4) >> 3;
99 output[(2*i+0)*out_stride] = (tmp + high[i*high_stride]) >> 1;
100 if (clip)
102
103 tmp = (11*low[i*low_stride] - 4*low[(i-1)*low_stride] + low[(i-2)*low_stride] + 4) >> 3;
104 output[(2*i+1)*out_stride] = (tmp - high[i*high_stride]) >> 1;
105 if (clip)
107 } else {
108 tmp = (low[(i-1)*low_stride] - low[(i+1)*low_stride] + 4) >> 3;
109 output[(2*i+0)*out_stride] = (tmp + low[i*low_stride] + high[i*high_stride]) >> 1;
110 if (clip)
112
113 tmp = (low[(i+1)*low_stride] - low[(i-1)*low_stride] + 4) >> 3;
114 output[(2*i+1)*out_stride] = (tmp + low[i*low_stride] - high[i*high_stride]) >> 1;
115 if (clip)
117 }
118 }
119 }
120
122 {
123 filter(output, 1, low, 1, high, 1, width, 0);
124 }
125
127 {
128 filter(output, 1, low, 1, high, 1, width, clip);
129 }
130
131 static void vert_filter(int16_t *output,
int out_stride, int16_t *low,
int low_stride,
132 int16_t *high,
int high_stride,
int len)
133 {
134 filter(output, out_stride, low, low_stride, high, high_stride, len, 0);
135 }
136
138 {
140 int i, j;
141
142 for (i = 0; i < 4; i++) {
145
146 for (j = 0; j < 9; j++)
148
149 for (j = 0; j < 8; j++)
151 }
154 }
155
157 {
159 int i, j, k, ret, planes;
160
162 return ret;
164
167
168 for (i = 0; i < planes; i++) {
172 int w8, h8, w4, h4, w2, h2;
173 height =
FFALIGN(height / 8, 2) * 8;
177
180 w4 = w8 * 2;
181 h4 = h8 * 2;
182 w2 = w4 * 2;
183 h2 = h4 * 2;
184
189 }
190
201
203 for(k = 0; k < 4; k++) {
206 }
207 }
208
209 /* ll2 and ll1 commented out because they are done in-place */
212 //s->plane[i].l_h[2] = ll2;
215 //s->plane[i].l_h[5] = ll1;
218 }
219
223
224 return 0;
225 }
226
229 {
234 int ret = 0, i, j, planes,
plane, got_buffer = 0;
235 int16_t *coeff_data;
236
240
242
244 /* Bit weird but implement the tag parsing as the spec says */
245 uint16_t tagu = bytestream2_get_be16(&gb);
246 int16_t
tag = (int16_t)tagu;
247 int8_t tag8 = (int8_t)(tagu >> 8);
248 uint16_t abstag = abs(tag);
249 int8_t abs_tag8 = abs(tag8);
250 uint16_t data = bytestream2_get_be16(&gb);
251 if (abs_tag8 >= 0x60 && abs_tag8 <= 0x6f) {
253 } else if (tag == 20) {
256 } else if (tag == 21) {
259 } else if (tag == 101) {
264 break;
265 }
267 } else if (tag == 12) {
270 if (data > 4) {
273 break;
274 }
275 } else if (tag == 14) {
280 break;
281 }
282 } else if (tag == 62) {
288 break;
289 }
291 } else if (tag == 48) {
299 break;
300 }
304 break;
305 }
306 } else if (tag == 51) {
312 break;
313 }
314 } else if (tag == 35)
316 else if (tag == 53) {
319 } else if (tag == 109) {
324 } else if (tag == 27) {
329 break;
330 }
333 } else if (tag == 28) {
338 break;
339 }
341 } else if (tag == 1)
343 else if (tag == 10) {
344 if (data != 0) {
347 break;
348 }
350 } else if (abstag >= 0x4000 && abstag <= 0x40ff) {
351 av_log(avctx,
AV_LOG_DEBUG,
"Small chunk length %d %s\n", data * 4, tag < 0 ?
"optional" :
"required");
353 } else if (tag == 23) {
357 break;
358 } else if (tag == 2) {
363 break;
364 }
365 for (i = 0; i <
data; i++) {
366 uint16_t tag2 = bytestream2_get_be16(&gb);
367 uint16_t val2 = bytestream2_get_be16(&gb);
369 }
370 } else if (tag == 41) {
372 if (data < 3) {
375 break;
376 }
379 } else if (tag == 42) {
381 if (data < 3) {
384 break;
385 }
387 } else if (tag == 49) {
389 if (data < 3) {
392 break;
393 }
396 } else if (tag == 50) {
398 if (data < 3) {
401 break;
402 }
404 } else if (tag == 71) {
407 } else if (tag == 72) {
410 } else if (tag == 70) {
412 if (!(data == 10 || data == 12)) {
415 break;
416 }
418 } else if (tag == 84) {
420 if (data == 1)
422 else if (data == 3)
424 else if (data == 4)
426 else {
429 break;
430 }
432 } else
434
435 /* Some kind of end of header tag */
443 return ret;
444 }
445 }
447 if (ret < 0)
448 return ret;
451
453 return ret;
454
458 got_buffer = 1;
459 }
461
462 /* Lowpass coefficients */
468
469 if (!got_buffer) {
473 }
474
475 if (lowpass_height > lowpass_a_height || lowpass_width > lowpass_a_width ||
480 }
481
483 for (i = 0; i < lowpass_height; i++) {
484 for (j = 0; j < lowpass_width; j++)
485 coeff_data[j] = bytestream2_get_be16u(&gb);
486
487 coeff_data += lowpass_width;
488 }
489
490 /* Align to mod-4 position to continue reading tags */
492
493 /* Copy last line of coefficients if odd height */
494 if (lowpass_height & 1) {
495 memcpy(&coeff_data[lowpass_height * lowpass_width],
496 &coeff_data[(lowpass_height - 1) * lowpass_width],
497 lowpass_width * sizeof(*coeff_data));
498 }
499
500 av_log(avctx,
AV_LOG_DEBUG,
"Lowpass coefficients %d\n", lowpass_width * lowpass_height);
501 }
502
509 int expected;
510 int a_expected = highpass_a_height * highpass_a_width;
512 int count = 0, bytes;
513
514 if (!got_buffer) {
518 }
519
520 if (highpass_height > highpass_a_height || highpass_width > highpass_a_width || a_expected < highpass_height * (uint64_t)highpass_stride) {
524 }
525 expected = highpass_height * highpass_stride;
526
528
530 {
533 while (1) {
537
538 /* escape */
539 if (level == 64)
540 break;
541
543
544 if (count > expected)
545 break;
546
548 for (i = 0; i <
run; i++)
549 *coeff_data++ = coeff;
550 }
551 } else {
552 while (1) {
556
557 /* escape */
558 if (level == 255 && run == 2)
559 break;
560
562
563 if (count > expected)
564 break;
565
567 for (i = 0; i <
run; i++)
568 *coeff_data++ = coeff;
569 }
570 }
572 }
573
574 if (count > expected) {
578 }
579
585 } else
587
588 av_log(avctx,
AV_LOG_DEBUG,
"End subband coeffs %i extra %i\n", count, count - expected);
590
591 /* Copy last line of coefficients if odd height */
592 if (highpass_height & 1) {
593 memcpy(&coeff_data[highpass_height * highpass_stride],
594 &coeff_data[(highpass_height - 1) * highpass_stride],
595 highpass_stride * sizeof(*coeff_data));
596 }
597 }
598 }
599
605 }
606
607 if (!got_buffer) {
611 }
612
614 for (plane = 0; plane < planes && !ret; plane++) {
615 /* level 1 */
619 int act_plane = plane == 1 ? 2 : plane == 2 ? 1 :
plane;
620 int16_t *low, *high, *output, *dst;
621
627 }
628
629 av_log(avctx,
AV_LOG_DEBUG,
"Decoding level 1 plane %i %i %i %i\n", plane, lowpass_height, lowpass_width, highpass_stride);
630
634 for (i = 0; i < lowpass_width; i++) {
635 vert_filter(output, lowpass_width, low, lowpass_width, high, highpass_stride, lowpass_height);
636 low++;
637 high++;
638 output++;
639 }
640
644
645 for (i = 0; i < lowpass_width; i++) {
646 // note the stride of "low" is highpass_stride
647 vert_filter(output, lowpass_width, low, highpass_stride, high, highpass_stride, lowpass_height);
648 low++;
649 high++;
650 output++;
651 }
652
656 for (i = 0; i < lowpass_height * 2; i++) {
658 low += lowpass_width;
659 high += lowpass_width;
660 output += lowpass_width * 2;
661 }
664 for (i = 0; i < lowpass_height * 2; i++) {
665 for (j = 0; j < lowpass_width * 2; j++)
666 output[j] *= 4;
667
668 output += lowpass_width * 2;
669 }
670 }
671
672 /* level 2 */
676
682 }
683
684 av_log(avctx,
AV_LOG_DEBUG,
"Level 2 plane %i %i %i %i\n", plane, lowpass_height, lowpass_width, highpass_stride);
685
689 for (i = 0; i < lowpass_width; i++) {
690 vert_filter(output, lowpass_width, low, lowpass_width, high, highpass_stride, lowpass_height);
691 low++;
692 high++;
693 output++;
694 }
695
699 for (i = 0; i < lowpass_width; i++) {
700 vert_filter(output, lowpass_width, low, highpass_stride, high, highpass_stride, lowpass_height);
701 low++;
702 high++;
703 output++;
704 }
705
709 for (i = 0; i < lowpass_height * 2; i++) {
711 low += lowpass_width;
712 high += lowpass_width;
713 output += lowpass_width * 2;
714 }
715
717 for (i = 0; i < lowpass_height * 2; i++) {
718 for (j = 0; j < lowpass_width * 2; j++)
719 output[j] *= 4;
720
721 output += lowpass_width * 2;
722 }
723
724 /* level 3 */
728
734 }
735
736 av_log(avctx,
AV_LOG_DEBUG,
"Level 3 plane %i %i %i %i\n", plane, lowpass_height, lowpass_width, highpass_stride);
737
741 for (i = 0; i < lowpass_width; i++) {
742 vert_filter(output, lowpass_width, low, lowpass_width, high, highpass_stride, lowpass_height);
743 low++;
744 high++;
745 output++;
746 }
747
751 for (i = 0; i < lowpass_width; i++) {
752 vert_filter(output, lowpass_width, low, highpass_stride, high, highpass_stride, lowpass_height);
753 low++;
754 high++;
755 output++;
756 }
757
758 dst = (int16_t *)pic->
data[act_plane];
761 for (i = 0; i < lowpass_height * 2; i++) {
763 low += lowpass_width;
764 high += lowpass_width;
765 dst += pic->
linesize[act_plane] / 2;
766 }
767 }
768
769
771 if (ret < 0)
772 return ret;
773
774 *got_frame = 1;
776 }
777
779 {
781
783
787 }
788
789 return 0;
790 }
791
803 };
#define FF_CODEC_CAP_INIT_CLEANUP
The codec allows calling the close function for deallocation even if the init function returned a fai...
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
static int cfhd_decode(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)
This structure describes decoded (raw) audio or video data.
ptrdiff_t const GLvoid * data
int av_pix_fmt_count_planes(enum AVPixelFormat pix_fmt)
int ff_set_dimensions(AVCodecContext *s, int width, int height)
Check that the provided frame dimensions are valid and set them on the codec context.
static av_cold int init(AVCodecContext *avctx)
static int dequant_and_decompand(int level, int quantisation)
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
static av_always_inline void bytestream2_init(GetByteContext *g, const uint8_t *buf, int buf_size)
int bits_per_raw_sample
Bits per sample/pixel of internal libavcodec pixel/sample format.
static void horiz_filter(int16_t *output, int16_t *low, int16_t *high, int width)
#define FF_CODEC_CAP_INIT_THREADSAFE
The codec does not modify any global variables in the init function, allowing to call the init functi...
static av_cold int end(AVCodecContext *avctx)
Multithreading support functions.
static void filter(int16_t *output, ptrdiff_t out_stride, int16_t *low, ptrdiff_t low_stride, int16_t *high, ptrdiff_t high_stride, int len, uint8_t clip)
static int alloc_buffers(AVCodecContext *avctx)
static int get_bits_count(const GetBitContext *s)
static av_always_inline void bytestream2_skipu(GetByteContext *g, unsigned int size)
CFHD_RL_VLC_ELEM table_18_rl_vlc[4572]
CFHD_RL_VLC_ELEM table_9_rl_vlc[2088]
uint8_t prescale_shift[3]
#define UPDATE_CACHE(name, gb)
int width
width and height of the video frame
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
int is_copy
Whether the parent AVCodecContext is a copy of the context which had init() called on it...
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
static void vert_filter(int16_t *output, int out_stride, int16_t *low, int low_stride, int16_t *high, int high_stride, int len)
static void horiz_filter_clip(int16_t *output, int16_t *low, int16_t *high, int width, uint8_t clip)
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
static av_always_inline unsigned int bytestream2_get_bytes_left(GetByteContext *g)
#define AV_PIX_FMT_GBRAP12
const char * name
Name of the codec implementation.
#define CLOSE_READER(name, gb)
static void * av_mallocz_array(size_t nmemb, size_t size)
#define AV_CODEC_CAP_FRAME_THREADS
Codec supports frame-level multithreading.
#define GET_RL_VLC(level, run, name, gb, table, bits,max_depth, need_update)
static void init_frame_defaults(CFHDContext *s)
SubBand band[DWT_LEVELS][4]
int width
picture width / height.
static void init_plane_defaults(CFHDContext *s)
void avcodec_get_chroma_sub_sample(enum AVPixelFormat pix_fmt, int *h_shift, int *v_shift)
Utility function to access log2_chroma_w log2_chroma_h from the pixel format AVPixFmtDescriptor.
#define AVERROR_PATCHWELCOME
Not yet implemented in FFmpeg, patches welcome.
static av_always_inline int bytestream2_tell(GetByteContext *g)
Libavcodec external API header.
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
int ff_thread_get_buffer(AVCodecContext *avctx, ThreadFrame *f, int flags)
Wrapper around get_buffer() for frame-multithreaded codecs.
main external API structure.
#define OPEN_READER(name, gb)
static av_cold int cfhd_close_decoder(AVCodecContext *avctx)
static int init_get_bits(GetBitContext *s, const uint8_t *buffer, int bit_size)
Initialize GetBitContext.
refcounted data buffer API
static av_cold int cfhd_decode_init(AVCodecContext *avctx)
#define AV_PIX_FMT_GBRP12
void avpriv_report_missing_feature(void *avc, const char *msg,...) av_printf_format(2
Log a generic warning message about a missing feature.
#define AV_PIX_FMT_YUV422P10
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
static void free_buffers(AVCodecContext *avctx)
GLint GLenum GLboolean GLsizei stride
common internal api header.
common internal and external API header
static double clip(void *opaque, double val)
Clip value val in the minval - maxval range.
struct AVCodecInternal * internal
Private context used for internal data.
static const double coeff[2][5]
static av_always_inline int bytestream2_seek(GetByteContext *g, int offset, int whence)
int ff_cfhd_init_vlcs(CFHDContext *s)
static int decode(AVCodecContext *avctx, AVFrame *frame, int *got_frame, AVPacket *pkt)
#define av_malloc_array(a, b)
uint8_t lowpass_precision
This structure stores compressed data.
void ff_free_vlc(VLC *vlc)
#define AV_CODEC_CAP_DR1
Codec uses get_buffer() for allocating buffers and supports custom allocators.
static av_always_inline av_const unsigned av_clip_uintp2_c(int a, int p)
Clip a signed integer to an unsigned power of two range.