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
) -
220 bsrc
= src
+ slice_start
* stride
;
222 // first line - left neighbour prediction
225 for (i
= step
; i
< width
* step
; i
+= step
) {
230 if (slice_height
<= 1)
232 // second line - first element has top prediction, the rest uses median
236 for (i
= step
; i
< width
* step
; i
+= step
) {
237 B
= bsrc
[i
- stride
];
238 bsrc
[i
] += mid_pred(A
, B
, (uint8_t)(A
+ B
- C
));
243 // the rest of lines use continuous median prediction
244 for (j
= 2; j
< slice_height
; j
++) {
245 for (i
= 0; i
< width
* step
; i
+= step
) {
246 B
= bsrc
[i
- stride
];
247 bsrc
[i
] += mid_pred(A
, B
, (uint8_t)(A
+ B
- C
));
256 /* UtVideo interlaced mode treats every two lines as a single one,
257 * so restoring function should take care of possible padding between
258 * two parts of the same "line".
260 static void restore_median_il(uint8_t *src
, int step
, int stride
,
261 int width
, int height
, int slices
, int rmode
)
266 int slice_start
, slice_height
;
267 const int cmask
= ~(rmode
? 3 : 1);
268 const int stride2
= stride
<< 1;
270 for (slice
= 0; slice
< slices
; slice
++) {
271 slice_start
= ((slice
* height
) / slices
) & cmask
;
272 slice_height
= ((((slice
+ 1) * height
) / slices
) & cmask
) -
278 bsrc
= src
+ slice_start
* stride
;
280 // first line - left neighbour prediction
283 for (i
= step
; i
< width
* step
; i
+= step
) {
287 for (i
= 0; i
< width
* step
; i
+= step
) {
288 bsrc
[stride
+ i
] += A
;
289 A
= bsrc
[stride
+ i
];
292 if (slice_height
<= 1)
294 // second line - first element has top prediction, the rest uses median
298 for (i
= step
; i
< width
* step
; i
+= step
) {
299 B
= bsrc
[i
- stride2
];
300 bsrc
[i
] += mid_pred(A
, B
, (uint8_t)(A
+ B
- C
));
304 for (i
= 0; i
< width
* step
; i
+= step
) {
305 B
= bsrc
[i
- stride
];
306 bsrc
[stride
+ i
] += mid_pred(A
, B
, (uint8_t)(A
+ B
- C
));
308 A
= bsrc
[stride
+ i
];
311 // the rest of lines use continuous median prediction
312 for (j
= 2; j
< slice_height
; j
++) {
313 for (i
= 0; i
< width
* step
; i
+= step
) {
314 B
= bsrc
[i
- stride2
];
315 bsrc
[i
] += mid_pred(A
, B
, (uint8_t)(A
+ B
- C
));
319 for (i
= 0; i
< width
* step
; i
+= step
) {
320 B
= bsrc
[i
- stride
];
321 bsrc
[i
+ stride
] += mid_pred(A
, B
, (uint8_t)(A
+ B
- C
));
323 A
= bsrc
[i
+ stride
];
330 static int decode_frame(AVCodecContext
*avctx
, void *data
, int *got_frame
,
333 const uint8_t *buf
= avpkt
->data
;
334 int buf_size
= avpkt
->size
;
335 UtvideoContext
*c
= avctx
->priv_data
;
337 const uint8_t *plane_start
[5];
338 int plane_size
, max_slice_size
= 0, slice_start
, slice_end
, slice_size
;
341 ThreadFrame frame
= { .f
= data
};
343 if ((ret
= ff_thread_get_buffer(avctx
, &frame
, 0)) < 0)
346 /* parse plane structure to get frame flags and validate slice offsets */
347 bytestream2_init(&gb
, buf
, buf_size
);
348 for (i
= 0; i
< c
->planes
; i
++) {
349 plane_start
[i
] = gb
.buffer
;
350 if (bytestream2_get_bytes_left(&gb
) < 256 + 4 * c
->slices
) {
351 av_log(avctx
, AV_LOG_ERROR
, "Insufficient data for a plane\n");
352 return AVERROR_INVALIDDATA
;
354 bytestream2_skipu(&gb
, 256);
357 for (j
= 0; j
< c
->slices
; j
++) {
358 slice_end
= bytestream2_get_le32u(&gb
);
359 slice_size
= slice_end
- slice_start
;
360 if (slice_end
< 0 || slice_size
< 0 ||
361 bytestream2_get_bytes_left(&gb
) < slice_end
) {
362 av_log(avctx
, AV_LOG_ERROR
, "Incorrect slice size\n");
363 return AVERROR_INVALIDDATA
;
365 slice_start
= slice_end
;
366 max_slice_size
= FFMAX(max_slice_size
, slice_size
);
368 plane_size
= slice_end
;
369 bytestream2_skipu(&gb
, plane_size
);
371 plane_start
[c
->planes
] = gb
.buffer
;
372 if (bytestream2_get_bytes_left(&gb
) < c
->frame_info_size
) {
373 av_log(avctx
, AV_LOG_ERROR
, "Not enough data for frame information\n");
374 return AVERROR_INVALIDDATA
;
376 c
->frame_info
= bytestream2_get_le32u(&gb
);
377 av_log(avctx
, AV_LOG_DEBUG
, "frame information flags %"PRIX32
"\n",
380 c
->frame_pred
= (c
->frame_info
>> 8) & 3;
382 if (c
->frame_pred
== PRED_GRADIENT
) {
383 avpriv_request_sample(avctx
, "Frame with gradient prediction");
384 return AVERROR_PATCHWELCOME
;
387 av_fast_malloc(&c
->slice_bits
, &c
->slice_bits_size
,
388 max_slice_size
+ FF_INPUT_BUFFER_PADDING_SIZE
);
390 if (!c
->slice_bits
) {
391 av_log(avctx
, AV_LOG_ERROR
, "Cannot allocate temporary buffer\n");
392 return AVERROR(ENOMEM
);
395 switch (c
->avctx
->pix_fmt
) {
396 case AV_PIX_FMT_RGB24
:
397 case AV_PIX_FMT_RGBA
:
398 for (i
= 0; i
< c
->planes
; i
++) {
399 ret
= decode_plane(c
, i
, frame
.f
->data
[0] + ff_ut_rgb_order
[i
],
400 c
->planes
, frame
.f
->linesize
[0], avctx
->width
,
401 avctx
->height
, plane_start
[i
],
402 c
->frame_pred
== PRED_LEFT
);
405 if (c
->frame_pred
== PRED_MEDIAN
) {
406 if (!c
->interlaced
) {
407 restore_median(frame
.f
->data
[0] + ff_ut_rgb_order
[i
],
408 c
->planes
, frame
.f
->linesize
[0], avctx
->width
,
409 avctx
->height
, c
->slices
, 0);
411 restore_median_il(frame
.f
->data
[0] + ff_ut_rgb_order
[i
],
412 c
->planes
, frame
.f
->linesize
[0],
413 avctx
->width
, avctx
->height
, c
->slices
,
418 restore_rgb_planes(frame
.f
->data
[0], c
->planes
, frame
.f
->linesize
[0],
419 avctx
->width
, avctx
->height
);
421 case AV_PIX_FMT_YUV420P
:
422 for (i
= 0; i
< 3; i
++) {
423 ret
= decode_plane(c
, i
, frame
.f
->data
[i
], 1, frame
.f
->linesize
[i
],
424 avctx
->width
>> !!i
, avctx
->height
>> !!i
,
425 plane_start
[i
], c
->frame_pred
== PRED_LEFT
);
428 if (c
->frame_pred
== PRED_MEDIAN
) {
429 if (!c
->interlaced
) {
430 restore_median(frame
.f
->data
[i
], 1, frame
.f
->linesize
[i
],
431 avctx
->width
>> !!i
, avctx
->height
>> !!i
,
434 restore_median_il(frame
.f
->data
[i
], 1, frame
.f
->linesize
[i
],
436 avctx
->height
>> !!i
,
442 case AV_PIX_FMT_YUV422P
:
443 for (i
= 0; i
< 3; i
++) {
444 ret
= decode_plane(c
, i
, frame
.f
->data
[i
], 1, frame
.f
->linesize
[i
],
445 avctx
->width
>> !!i
, avctx
->height
,
446 plane_start
[i
], c
->frame_pred
== PRED_LEFT
);
449 if (c
->frame_pred
== PRED_MEDIAN
) {
450 if (!c
->interlaced
) {
451 restore_median(frame
.f
->data
[i
], 1, frame
.f
->linesize
[i
],
452 avctx
->width
>> !!i
, avctx
->height
,
455 restore_median_il(frame
.f
->data
[i
], 1, frame
.f
->linesize
[i
],
456 avctx
->width
>> !!i
, avctx
->height
,
464 frame
.f
->key_frame
= 1;
465 frame
.f
->pict_type
= AV_PICTURE_TYPE_I
;
466 frame
.f
->interlaced_frame
= !!c
->interlaced
;
470 /* always report that the buffer was completely consumed */
474 static av_cold
int decode_init(AVCodecContext
*avctx
)
476 UtvideoContext
* const c
= avctx
->priv_data
;
480 ff_bswapdsp_init(&c
->bdsp
);
482 if (avctx
->extradata_size
< 16) {
483 av_log(avctx
, AV_LOG_ERROR
,
484 "Insufficient extradata size %d, should be at least 16\n",
485 avctx
->extradata_size
);
486 return AVERROR_INVALIDDATA
;
489 av_log(avctx
, AV_LOG_DEBUG
, "Encoder version %d.%d.%d.%d\n",
490 avctx
->extradata
[3], avctx
->extradata
[2],
491 avctx
->extradata
[1], avctx
->extradata
[0]);
492 av_log(avctx
, AV_LOG_DEBUG
, "Original format %"PRIX32
"\n",
493 AV_RB32(avctx
->extradata
+ 4));
494 c
->frame_info_size
= AV_RL32(avctx
->extradata
+ 8);
495 c
->flags
= AV_RL32(avctx
->extradata
+ 12);
497 if (c
->frame_info_size
!= 4)
498 avpriv_request_sample(avctx
, "Frame info not 4 bytes");
499 av_log(avctx
, AV_LOG_DEBUG
, "Encoding parameters %08"PRIX32
"\n", c
->flags
);
500 c
->slices
= (c
->flags
>> 24) + 1;
501 c
->compression
= c
->flags
& 1;
502 c
->interlaced
= c
->flags
& 0x800;
504 c
->slice_bits_size
= 0;
506 switch (avctx
->codec_tag
) {
507 case MKTAG('U', 'L', 'R', 'G'):
509 avctx
->pix_fmt
= AV_PIX_FMT_RGB24
;
511 case MKTAG('U', 'L', 'R', 'A'):
513 avctx
->pix_fmt
= AV_PIX_FMT_RGBA
;
515 case MKTAG('U', 'L', 'Y', '0'):
517 avctx
->pix_fmt
= AV_PIX_FMT_YUV420P
;
518 avctx
->colorspace
= AVCOL_SPC_BT470BG
;
520 case MKTAG('U', 'L', 'Y', '2'):
522 avctx
->pix_fmt
= AV_PIX_FMT_YUV422P
;
523 avctx
->colorspace
= AVCOL_SPC_BT470BG
;
525 case MKTAG('U', 'L', 'H', '0'):
527 avctx
->pix_fmt
= AV_PIX_FMT_YUV420P
;
528 avctx
->colorspace
= AVCOL_SPC_BT709
;
530 case MKTAG('U', 'L', 'H', '2'):
532 avctx
->pix_fmt
= AV_PIX_FMT_YUV422P
;
533 avctx
->colorspace
= AVCOL_SPC_BT709
;
536 av_log(avctx
, AV_LOG_ERROR
, "Unknown Ut Video FOURCC provided (%08X)\n",
538 return AVERROR_INVALIDDATA
;
544 static av_cold
int decode_end(AVCodecContext
*avctx
)
546 UtvideoContext
* const c
= avctx
->priv_data
;
548 av_freep(&c
->slice_bits
);
553 AVCodec ff_utvideo_decoder
= {
555 .long_name
= NULL_IF_CONFIG_SMALL("Ut Video"),
556 .type
= AVMEDIA_TYPE_VIDEO
,
557 .id
= AV_CODEC_ID_UTVIDEO
,
558 .priv_data_size
= sizeof(UtvideoContext
),
561 .decode
= decode_frame
,
562 .capabilities
= CODEC_CAP_DR1
| CODEC_CAP_FRAME_THREADS
,