3 * Copyright (c) 2011 Konstantin Shishkov
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
30 #include "libavutil/intreadwrite.h"
33 #include "bytestream.h"
38 static int build_huff(const uint8_t *src
, VLC
*vlc
, int *fsym
)
49 for (i
= 0; i
< 256; i
++) {
53 qsort(he
, 256, sizeof(*he
), ff_ut_huff_cmp_len
);
61 while (he
[last
].len
== 255 && last
)
64 if (he
[last
].len
> 32)
68 for (i
= last
; i
>= 0; i
--) {
69 codes
[i
] = code
>> (32 - he
[i
].len
);
72 code
+= 0x80000000u
>> (he
[i
].len
- 1);
75 return ff_init_vlc_sparse(vlc
, FFMIN(he
[last
].len
, 11), last
+ 1,
76 bits
, sizeof(*bits
), sizeof(*bits
),
77 codes
, sizeof(*codes
), sizeof(*codes
),
78 syms
, sizeof(*syms
), sizeof(*syms
), 0);
81 static int decode_plane(UtvideoContext
*c
, int plane_no
,
82 uint8_t *dst
, int step
, int stride
,
83 int width
, int height
,
84 const uint8_t *src
, int use_pred
)
91 const int cmask
= ~(!plane_no
&& c
->avctx
->pix_fmt
== AV_PIX_FMT_YUV420P
);
93 if (build_huff(src
, &vlc
, &fsym
)) {
94 av_log(c
->avctx
, AV_LOG_ERROR
, "Cannot build Huffman codes\n");
95 return AVERROR_INVALIDDATA
;
97 if (fsym
>= 0) { // build_huff reported a symbol to fill slices with
99 for (slice
= 0; slice
< c
->slices
; slice
++) {
103 send
= (height
* (slice
+ 1) / c
->slices
) & cmask
;
104 dest
= dst
+ sstart
* stride
;
107 for (j
= sstart
; j
< send
; j
++) {
108 for (i
= 0; i
< width
* step
; i
+= step
) {
125 for (slice
= 0; slice
< c
->slices
; slice
++) {
127 int slice_data_start
, slice_data_end
, slice_size
;
130 send
= (height
* (slice
+ 1) / c
->slices
) & cmask
;
131 dest
= dst
+ sstart
* stride
;
133 // slice offset and size validation was done earlier
134 slice_data_start
= slice
? AV_RL32(src
+ slice
* 4 - 4) : 0;
135 slice_data_end
= AV_RL32(src
+ slice
* 4);
136 slice_size
= slice_data_end
- slice_data_start
;
139 av_log(c
->avctx
, AV_LOG_ERROR
, "Plane has more than one symbol "
140 "yet a slice has a length of zero.\n");
144 memcpy(c
->slice_bits
, src
+ slice_data_start
+ c
->slices
* 4,
146 memset(c
->slice_bits
+ slice_size
, 0, FF_INPUT_BUFFER_PADDING_SIZE
);
147 c
->bdsp
.bswap_buf((uint32_t *) c
->slice_bits
,
148 (uint32_t *) c
->slice_bits
,
149 (slice_data_end
- slice_data_start
+ 3) >> 2);
150 init_get_bits(&gb
, c
->slice_bits
, slice_size
* 8);
153 for (j
= sstart
; j
< send
; j
++) {
154 for (i
= 0; i
< width
* step
; i
+= step
) {
155 if (get_bits_left(&gb
) <= 0) {
156 av_log(c
->avctx
, AV_LOG_ERROR
,
157 "Slice decoding ran out of bits\n");
160 pix
= get_vlc2(&gb
, vlc
.table
, vlc
.bits
, 3);
162 av_log(c
->avctx
, AV_LOG_ERROR
, "Decoding error\n");
173 if (get_bits_left(&gb
) > 32)
174 av_log(c
->avctx
, AV_LOG_WARNING
,
175 "%d bits left after decoding slice\n", get_bits_left(&gb
));
183 return AVERROR_INVALIDDATA
;
186 static void restore_rgb_planes(uint8_t *src
, int step
, int stride
, int width
,
192 for (j
= 0; j
< height
; j
++) {
193 for (i
= 0; i
< width
* step
; i
+= step
) {
197 src
[i
] = r
+ g
- 0x80;
198 src
[i
+ 2] = b
+ g
- 0x80;
204 static void restore_median(uint8_t *src
, int step
, int stride
,
205 int width
, int height
, int slices
, int rmode
)
210 int slice_start
, slice_height
;
211 const int cmask
= ~rmode
;
213 for (slice
= 0; slice
< slices
; slice
++) {
214 slice_start
= ((slice
* height
) / slices
) & cmask
;
215 slice_height
= ((((slice
+ 1) * height
) / slices
) & cmask
) -
218 bsrc
= src
+ slice_start
* stride
;
220 // first line - left neighbour prediction
223 for (i
= step
; i
< width
* step
; i
+= step
) {
228 if (slice_height
<= 1)
230 // second line - first element has top prediction, the rest uses median
234 for (i
= step
; i
< width
* step
; i
+= step
) {
235 B
= bsrc
[i
- stride
];
236 bsrc
[i
] += mid_pred(A
, B
, (uint8_t)(A
+ B
- C
));
241 // the rest of lines use continuous median prediction
242 for (j
= 2; j
< slice_height
; j
++) {
243 for (i
= 0; i
< width
* step
; i
+= step
) {
244 B
= bsrc
[i
- stride
];
245 bsrc
[i
] += mid_pred(A
, B
, (uint8_t)(A
+ B
- C
));
254 /* UtVideo interlaced mode treats every two lines as a single one,
255 * so restoring function should take care of possible padding between
256 * two parts of the same "line".
258 static void restore_median_il(uint8_t *src
, int step
, int stride
,
259 int width
, int height
, int slices
, int rmode
)
264 int slice_start
, slice_height
;
265 const int cmask
= ~(rmode
? 3 : 1);
266 const int stride2
= stride
<< 1;
268 for (slice
= 0; slice
< slices
; slice
++) {
269 slice_start
= ((slice
* height
) / slices
) & cmask
;
270 slice_height
= ((((slice
+ 1) * height
) / slices
) & cmask
) -
274 bsrc
= src
+ slice_start
* stride
;
276 // first line - left neighbour prediction
279 for (i
= step
; i
< width
* step
; i
+= step
) {
283 for (i
= 0; i
< width
* step
; i
+= step
) {
284 bsrc
[stride
+ i
] += A
;
285 A
= bsrc
[stride
+ i
];
288 if (slice_height
<= 1)
290 // second line - first element has top prediction, the rest uses median
294 for (i
= step
; i
< width
* step
; i
+= step
) {
295 B
= bsrc
[i
- stride2
];
296 bsrc
[i
] += mid_pred(A
, B
, (uint8_t)(A
+ B
- C
));
300 for (i
= 0; i
< width
* step
; i
+= step
) {
301 B
= bsrc
[i
- stride
];
302 bsrc
[stride
+ i
] += mid_pred(A
, B
, (uint8_t)(A
+ B
- C
));
304 A
= bsrc
[stride
+ i
];
307 // the rest of lines use continuous median prediction
308 for (j
= 2; j
< slice_height
; j
++) {
309 for (i
= 0; i
< width
* step
; i
+= step
) {
310 B
= bsrc
[i
- stride2
];
311 bsrc
[i
] += mid_pred(A
, B
, (uint8_t)(A
+ B
- C
));
315 for (i
= 0; i
< width
* step
; i
+= step
) {
316 B
= bsrc
[i
- stride
];
317 bsrc
[i
+ stride
] += mid_pred(A
, B
, (uint8_t)(A
+ B
- C
));
319 A
= bsrc
[i
+ stride
];
326 static int decode_frame(AVCodecContext
*avctx
, void *data
, int *got_frame
,
329 const uint8_t *buf
= avpkt
->data
;
330 int buf_size
= avpkt
->size
;
331 UtvideoContext
*c
= avctx
->priv_data
;
333 const uint8_t *plane_start
[5];
334 int plane_size
, max_slice_size
= 0, slice_start
, slice_end
, slice_size
;
337 ThreadFrame frame
= { .f
= data
};
339 if ((ret
= ff_thread_get_buffer(avctx
, &frame
, 0)) < 0)
342 /* parse plane structure to get frame flags and validate slice offsets */
343 bytestream2_init(&gb
, buf
, buf_size
);
344 for (i
= 0; i
< c
->planes
; i
++) {
345 plane_start
[i
] = gb
.buffer
;
346 if (bytestream2_get_bytes_left(&gb
) < 256 + 4 * c
->slices
) {
347 av_log(avctx
, AV_LOG_ERROR
, "Insufficient data for a plane\n");
348 return AVERROR_INVALIDDATA
;
350 bytestream2_skipu(&gb
, 256);
353 for (j
= 0; j
< c
->slices
; j
++) {
354 slice_end
= bytestream2_get_le32u(&gb
);
355 slice_size
= slice_end
- slice_start
;
356 if (slice_end
< 0 || slice_size
< 0 ||
357 bytestream2_get_bytes_left(&gb
) < slice_end
) {
358 av_log(avctx
, AV_LOG_ERROR
, "Incorrect slice size\n");
359 return AVERROR_INVALIDDATA
;
361 slice_start
= slice_end
;
362 max_slice_size
= FFMAX(max_slice_size
, slice_size
);
364 plane_size
= slice_end
;
365 bytestream2_skipu(&gb
, plane_size
);
367 plane_start
[c
->planes
] = gb
.buffer
;
368 if (bytestream2_get_bytes_left(&gb
) < c
->frame_info_size
) {
369 av_log(avctx
, AV_LOG_ERROR
, "Not enough data for frame information\n");
370 return AVERROR_INVALIDDATA
;
372 c
->frame_info
= bytestream2_get_le32u(&gb
);
373 av_log(avctx
, AV_LOG_DEBUG
, "frame information flags %"PRIX32
"\n",
376 c
->frame_pred
= (c
->frame_info
>> 8) & 3;
378 if (c
->frame_pred
== PRED_GRADIENT
) {
379 avpriv_request_sample(avctx
, "Frame with gradient prediction");
380 return AVERROR_PATCHWELCOME
;
383 av_fast_malloc(&c
->slice_bits
, &c
->slice_bits_size
,
384 max_slice_size
+ FF_INPUT_BUFFER_PADDING_SIZE
);
386 if (!c
->slice_bits
) {
387 av_log(avctx
, AV_LOG_ERROR
, "Cannot allocate temporary buffer\n");
388 return AVERROR(ENOMEM
);
391 switch (c
->avctx
->pix_fmt
) {
392 case AV_PIX_FMT_RGB24
:
393 case AV_PIX_FMT_RGBA
:
394 for (i
= 0; i
< c
->planes
; i
++) {
395 ret
= decode_plane(c
, i
, frame
.f
->data
[0] + ff_ut_rgb_order
[i
],
396 c
->planes
, frame
.f
->linesize
[0], avctx
->width
,
397 avctx
->height
, plane_start
[i
],
398 c
->frame_pred
== PRED_LEFT
);
401 if (c
->frame_pred
== PRED_MEDIAN
) {
402 if (!c
->interlaced
) {
403 restore_median(frame
.f
->data
[0] + ff_ut_rgb_order
[i
],
404 c
->planes
, frame
.f
->linesize
[0], avctx
->width
,
405 avctx
->height
, c
->slices
, 0);
407 restore_median_il(frame
.f
->data
[0] + ff_ut_rgb_order
[i
],
408 c
->planes
, frame
.f
->linesize
[0],
409 avctx
->width
, avctx
->height
, c
->slices
,
414 restore_rgb_planes(frame
.f
->data
[0], c
->planes
, frame
.f
->linesize
[0],
415 avctx
->width
, avctx
->height
);
417 case AV_PIX_FMT_YUV420P
:
418 for (i
= 0; i
< 3; i
++) {
419 ret
= decode_plane(c
, i
, frame
.f
->data
[i
], 1, frame
.f
->linesize
[i
],
420 avctx
->width
>> !!i
, avctx
->height
>> !!i
,
421 plane_start
[i
], c
->frame_pred
== PRED_LEFT
);
424 if (c
->frame_pred
== PRED_MEDIAN
) {
425 if (!c
->interlaced
) {
426 restore_median(frame
.f
->data
[i
], 1, frame
.f
->linesize
[i
],
427 avctx
->width
>> !!i
, avctx
->height
>> !!i
,
430 restore_median_il(frame
.f
->data
[i
], 1, frame
.f
->linesize
[i
],
432 avctx
->height
>> !!i
,
438 case AV_PIX_FMT_YUV422P
:
439 for (i
= 0; i
< 3; i
++) {
440 ret
= decode_plane(c
, i
, frame
.f
->data
[i
], 1, frame
.f
->linesize
[i
],
441 avctx
->width
>> !!i
, avctx
->height
,
442 plane_start
[i
], c
->frame_pred
== PRED_LEFT
);
445 if (c
->frame_pred
== PRED_MEDIAN
) {
446 if (!c
->interlaced
) {
447 restore_median(frame
.f
->data
[i
], 1, frame
.f
->linesize
[i
],
448 avctx
->width
>> !!i
, avctx
->height
,
451 restore_median_il(frame
.f
->data
[i
], 1, frame
.f
->linesize
[i
],
452 avctx
->width
>> !!i
, avctx
->height
,
460 frame
.f
->key_frame
= 1;
461 frame
.f
->pict_type
= AV_PICTURE_TYPE_I
;
462 frame
.f
->interlaced_frame
= !!c
->interlaced
;
466 /* always report that the buffer was completely consumed */
470 static av_cold
int decode_init(AVCodecContext
*avctx
)
472 UtvideoContext
* const c
= avctx
->priv_data
;
476 ff_bswapdsp_init(&c
->bdsp
);
478 if (avctx
->extradata_size
< 16) {
479 av_log(avctx
, AV_LOG_ERROR
,
480 "Insufficient extradata size %d, should be at least 16\n",
481 avctx
->extradata_size
);
482 return AVERROR_INVALIDDATA
;
485 av_log(avctx
, AV_LOG_DEBUG
, "Encoder version %d.%d.%d.%d\n",
486 avctx
->extradata
[3], avctx
->extradata
[2],
487 avctx
->extradata
[1], avctx
->extradata
[0]);
488 av_log(avctx
, AV_LOG_DEBUG
, "Original format %"PRIX32
"\n",
489 AV_RB32(avctx
->extradata
+ 4));
490 c
->frame_info_size
= AV_RL32(avctx
->extradata
+ 8);
491 c
->flags
= AV_RL32(avctx
->extradata
+ 12);
493 if (c
->frame_info_size
!= 4)
494 avpriv_request_sample(avctx
, "Frame info not 4 bytes");
495 av_log(avctx
, AV_LOG_DEBUG
, "Encoding parameters %08"PRIX32
"\n", c
->flags
);
496 c
->slices
= (c
->flags
>> 24) + 1;
497 c
->compression
= c
->flags
& 1;
498 c
->interlaced
= c
->flags
& 0x800;
500 c
->slice_bits_size
= 0;
502 switch (avctx
->codec_tag
) {
503 case MKTAG('U', 'L', 'R', 'G'):
505 avctx
->pix_fmt
= AV_PIX_FMT_RGB24
;
507 case MKTAG('U', 'L', 'R', 'A'):
509 avctx
->pix_fmt
= AV_PIX_FMT_RGBA
;
511 case MKTAG('U', 'L', 'Y', '0'):
513 avctx
->pix_fmt
= AV_PIX_FMT_YUV420P
;
514 avctx
->colorspace
= AVCOL_SPC_BT470BG
;
516 case MKTAG('U', 'L', 'Y', '2'):
518 avctx
->pix_fmt
= AV_PIX_FMT_YUV422P
;
519 avctx
->colorspace
= AVCOL_SPC_BT470BG
;
521 case MKTAG('U', 'L', 'H', '0'):
523 avctx
->pix_fmt
= AV_PIX_FMT_YUV420P
;
524 avctx
->colorspace
= AVCOL_SPC_BT709
;
526 case MKTAG('U', 'L', 'H', '2'):
528 avctx
->pix_fmt
= AV_PIX_FMT_YUV422P
;
529 avctx
->colorspace
= AVCOL_SPC_BT709
;
532 av_log(avctx
, AV_LOG_ERROR
, "Unknown Ut Video FOURCC provided (%08X)\n",
534 return AVERROR_INVALIDDATA
;
540 static av_cold
int decode_end(AVCodecContext
*avctx
)
542 UtvideoContext
* const c
= avctx
->priv_data
;
544 av_freep(&c
->slice_bits
);
549 AVCodec ff_utvideo_decoder
= {
551 .long_name
= NULL_IF_CONFIG_SMALL("Ut Video"),
552 .type
= AVMEDIA_TYPE_VIDEO
,
553 .id
= AV_CODEC_ID_UTVIDEO
,
554 .priv_data_size
= sizeof(UtvideoContext
),
557 .decode
= decode_frame
,
558 .capabilities
= CODEC_CAP_DR1
| CODEC_CAP_FRAME_THREADS
,