Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in / Register
Toggle navigation
F
ffmpeg.wasm-core
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Linshizhi
ffmpeg.wasm-core
Commits
c5230955
Commit
c5230955
authored
Apr 10, 2017
by
Paul B Mahol
Committed by
Luca Barbato
Apr 13, 2017
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
utvideodec: Support UQY2
Signed-off-by:
Luca Barbato
<
lu_zero@gentoo.org
>
parent
9e4a5eb5
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
253 additions
and
40 deletions
+253
-40
utvideo.c
libavcodec/utvideo.c
+6
-0
utvideo.h
libavcodec/utvideo.h
+3
-1
utvideodec.c
libavcodec/utvideodec.c
+243
-39
riff.c
libavformat/riff.c
+1
-0
No files found.
libavcodec/utvideo.c
View file @
c5230955
...
@@ -39,3 +39,9 @@ int ff_ut_huff_cmp_len(const void *a, const void *b)
...
@@ -39,3 +39,9 @@ int ff_ut_huff_cmp_len(const void *a, const void *b)
const
HuffEntry
*
aa
=
a
,
*
bb
=
b
;
const
HuffEntry
*
aa
=
a
,
*
bb
=
b
;
return
(
aa
->
len
-
bb
->
len
)
*
256
+
aa
->
sym
-
bb
->
sym
;
return
(
aa
->
len
-
bb
->
len
)
*
256
+
aa
->
sym
-
bb
->
sym
;
}
}
int
ff_ut10_huff_cmp_len
(
const
void
*
a
,
const
void
*
b
)
{
const
HuffEntry
*
aa
=
a
,
*
bb
=
b
;
return
(
aa
->
len
-
bb
->
len
)
*
1024
+
aa
->
sym
-
bb
->
sym
;
}
libavcodec/utvideo.h
View file @
c5230955
...
@@ -76,6 +76,7 @@ typedef struct UtvideoContext {
...
@@ -76,6 +76,7 @@ typedef struct UtvideoContext {
int
compression
;
int
compression
;
int
interlaced
;
int
interlaced
;
int
frame_pred
;
int
frame_pred
;
int
pro
;
ptrdiff_t
slice_stride
;
ptrdiff_t
slice_stride
;
uint8_t
*
slice_bits
,
*
slice_buffer
[
4
];
uint8_t
*
slice_bits
,
*
slice_buffer
[
4
];
...
@@ -83,12 +84,13 @@ typedef struct UtvideoContext {
...
@@ -83,12 +84,13 @@ typedef struct UtvideoContext {
}
UtvideoContext
;
}
UtvideoContext
;
typedef
struct
HuffEntry
{
typedef
struct
HuffEntry
{
uint
8_t
sym
;
uint
16_t
sym
;
uint8_t
len
;
uint8_t
len
;
uint32_t
code
;
uint32_t
code
;
}
HuffEntry
;
}
HuffEntry
;
/* Compare huffman tree nodes */
/* Compare huffman tree nodes */
int
ff_ut_huff_cmp_len
(
const
void
*
a
,
const
void
*
b
);
int
ff_ut_huff_cmp_len
(
const
void
*
a
,
const
void
*
b
);
int
ff_ut10_huff_cmp_len
(
const
void
*
a
,
const
void
*
b
);
#endif
/* AVCODEC_UTVIDEO_H */
#endif
/* AVCODEC_UTVIDEO_H */
libavcodec/utvideodec.c
View file @
c5230955
...
@@ -37,6 +37,50 @@
...
@@ -37,6 +37,50 @@
#include "thread.h"
#include "thread.h"
#include "utvideo.h"
#include "utvideo.h"
static
int
build_huff10
(
const
uint8_t
*
src
,
VLC
*
vlc
,
int
*
fsym
)
{
int
i
;
HuffEntry
he
[
1024
];
int
last
;
uint32_t
codes
[
1024
];
uint8_t
bits
[
1024
];
uint16_t
syms
[
1024
];
uint32_t
code
;
*
fsym
=
-
1
;
for
(
i
=
0
;
i
<
1024
;
i
++
)
{
he
[
i
].
sym
=
i
;
he
[
i
].
len
=
*
src
++
;
}
qsort
(
he
,
1024
,
sizeof
(
*
he
),
ff_ut10_huff_cmp_len
);
if
(
!
he
[
0
].
len
)
{
*
fsym
=
he
[
0
].
sym
;
return
0
;
}
last
=
1023
;
while
(
he
[
last
].
len
==
255
&&
last
)
last
--
;
if
(
he
[
last
].
len
>
32
)
{
return
-
1
;
}
code
=
1
;
for
(
i
=
last
;
i
>=
0
;
i
--
)
{
codes
[
i
]
=
code
>>
(
32
-
he
[
i
].
len
);
bits
[
i
]
=
he
[
i
].
len
;
syms
[
i
]
=
he
[
i
].
sym
;
code
+=
0x80000000u
>>
(
he
[
i
].
len
-
1
);
}
return
ff_init_vlc_sparse
(
vlc
,
FFMIN
(
he
[
last
].
len
,
11
),
last
+
1
,
bits
,
sizeof
(
*
bits
),
sizeof
(
*
bits
),
codes
,
sizeof
(
*
codes
),
sizeof
(
*
codes
),
syms
,
sizeof
(
*
syms
),
sizeof
(
*
syms
),
0
);
}
static
int
build_huff
(
const
uint8_t
*
src
,
VLC
*
vlc
,
int
*
fsym
)
static
int
build_huff
(
const
uint8_t
*
src
,
VLC
*
vlc
,
int
*
fsym
)
{
{
int
i
;
int
i
;
...
@@ -79,6 +123,111 @@ static int build_huff(const uint8_t *src, VLC *vlc, int *fsym)
...
@@ -79,6 +123,111 @@ static int build_huff(const uint8_t *src, VLC *vlc, int *fsym)
syms
,
sizeof
(
*
syms
),
sizeof
(
*
syms
),
0
);
syms
,
sizeof
(
*
syms
),
sizeof
(
*
syms
),
0
);
}
}
static
int
decode_plane10
(
UtvideoContext
*
c
,
int
plane_no
,
uint16_t
*
dst
,
int
step
,
int
stride
,
int
width
,
int
height
,
const
uint8_t
*
src
,
const
uint8_t
*
huff
,
int
use_pred
)
{
BitstreamContext
bc
;
int
i
,
j
,
slice
,
pix
,
ret
;
int
sstart
,
send
;
VLC
vlc
;
int
prev
,
fsym
;
if
((
ret
=
build_huff10
(
huff
,
&
vlc
,
&
fsym
))
<
0
)
{
av_log
(
c
->
avctx
,
AV_LOG_ERROR
,
"Cannot build Huffman codes
\n
"
);
return
ret
;
}
if
(
fsym
>=
0
)
{
// build_huff reported a symbol to fill slices with
send
=
0
;
for
(
slice
=
0
;
slice
<
c
->
slices
;
slice
++
)
{
uint16_t
*
dest
;
sstart
=
send
;
send
=
(
height
*
(
slice
+
1
)
/
c
->
slices
);
dest
=
dst
+
sstart
*
stride
;
prev
=
0x200
;
for
(
j
=
sstart
;
j
<
send
;
j
++
)
{
for
(
i
=
0
;
i
<
width
*
step
;
i
+=
step
)
{
pix
=
fsym
;
if
(
use_pred
)
{
prev
+=
pix
;
prev
&=
0x3FF
;
pix
=
prev
;
}
dest
[
i
]
=
pix
;
}
dest
+=
stride
;
}
}
return
0
;
}
send
=
0
;
for
(
slice
=
0
;
slice
<
c
->
slices
;
slice
++
)
{
uint16_t
*
dest
;
int
slice_data_start
,
slice_data_end
,
slice_size
;
sstart
=
send
;
send
=
(
height
*
(
slice
+
1
)
/
c
->
slices
);
dest
=
dst
+
sstart
*
stride
;
// slice offset and size validation was done earlier
slice_data_start
=
slice
?
AV_RL32
(
src
+
slice
*
4
-
4
)
:
0
;
slice_data_end
=
AV_RL32
(
src
+
slice
*
4
);
slice_size
=
slice_data_end
-
slice_data_start
;
if
(
!
slice_size
)
{
av_log
(
c
->
avctx
,
AV_LOG_ERROR
,
"Plane has more than one symbol "
"yet a slice has a length of zero.
\n
"
);
goto
fail
;
}
memcpy
(
c
->
slice_bits
,
src
+
slice_data_start
+
c
->
slices
*
4
,
slice_size
);
memset
(
c
->
slice_bits
+
slice_size
,
0
,
AV_INPUT_BUFFER_PADDING_SIZE
);
c
->
bdsp
.
bswap_buf
((
uint32_t
*
)
c
->
slice_bits
,
(
uint32_t
*
)
c
->
slice_bits
,
(
slice_data_end
-
slice_data_start
+
3
)
>>
2
);
bitstream_init8
(
&
bc
,
c
->
slice_bits
,
slice_size
);
prev
=
0x200
;
for
(
j
=
sstart
;
j
<
send
;
j
++
)
{
for
(
i
=
0
;
i
<
width
*
step
;
i
+=
step
)
{
if
(
bitstream_bits_left
(
&
bc
)
<=
0
)
{
av_log
(
c
->
avctx
,
AV_LOG_ERROR
,
"Slice decoding ran out of bits
\n
"
);
goto
fail
;
}
pix
=
bitstream_read_vlc
(
&
bc
,
vlc
.
table
,
vlc
.
bits
,
3
);
if
(
pix
<
0
)
{
av_log
(
c
->
avctx
,
AV_LOG_ERROR
,
"Decoding error
\n
"
);
goto
fail
;
}
if
(
use_pred
)
{
prev
+=
pix
;
prev
&=
0x3FF
;
pix
=
prev
;
}
dest
[
i
]
=
pix
;
}
dest
+=
stride
;
}
if
(
bitstream_bits_left
(
&
bc
)
>
32
)
av_log
(
c
->
avctx
,
AV_LOG_WARNING
,
"%d bits left after decoding slice
\n
"
,
bitstream_bits_left
(
&
bc
));
}
ff_free_vlc
(
&
vlc
);
return
0
;
fail:
ff_free_vlc
(
&
vlc
);
return
AVERROR_INVALIDDATA
;
}
static
int
decode_plane
(
UtvideoContext
*
c
,
int
plane_no
,
static
int
decode_plane
(
UtvideoContext
*
c
,
int
plane_no
,
uint8_t
*
dst
,
int
step
,
ptrdiff_t
stride
,
uint8_t
*
dst
,
int
step
,
ptrdiff_t
stride
,
int
width
,
int
height
,
int
width
,
int
height
,
...
@@ -350,6 +499,38 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
...
@@ -350,6 +499,38 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
/* parse plane structure to get frame flags and validate slice offsets */
/* parse plane structure to get frame flags and validate slice offsets */
bytestream2_init
(
&
gb
,
buf
,
buf_size
);
bytestream2_init
(
&
gb
,
buf
,
buf_size
);
if
(
c
->
pro
)
{
if
(
bytestream2_get_bytes_left
(
&
gb
)
<
c
->
frame_info_size
)
{
av_log
(
avctx
,
AV_LOG_ERROR
,
"Not enough data for frame information
\n
"
);
return
AVERROR_INVALIDDATA
;
}
c
->
frame_info
=
bytestream2_get_le32u
(
&
gb
);
c
->
slices
=
((
c
->
frame_info
>>
16
)
&
0xff
)
+
1
;
for
(
i
=
0
;
i
<
c
->
planes
;
i
++
)
{
plane_start
[
i
]
=
gb
.
buffer
;
if
(
bytestream2_get_bytes_left
(
&
gb
)
<
1024
+
4
*
c
->
slices
)
{
av_log
(
avctx
,
AV_LOG_ERROR
,
"Insufficient data for a plane
\n
"
);
return
AVERROR_INVALIDDATA
;
}
slice_start
=
0
;
slice_end
=
0
;
for
(
j
=
0
;
j
<
c
->
slices
;
j
++
)
{
slice_end
=
bytestream2_get_le32u
(
&
gb
);
if
(
slice_end
<
0
||
slice_end
<
slice_start
||
bytestream2_get_bytes_left
(
&
gb
)
<
slice_end
)
{
av_log
(
avctx
,
AV_LOG_ERROR
,
"Incorrect slice size
\n
"
);
return
AVERROR_INVALIDDATA
;
}
slice_size
=
slice_end
-
slice_start
;
slice_start
=
slice_end
;
max_slice_size
=
FFMAX
(
max_slice_size
,
slice_size
);
}
plane_size
=
slice_end
;
bytestream2_skipu
(
&
gb
,
plane_size
);
bytestream2_skipu
(
&
gb
,
1024
);
}
plane_start
[
c
->
planes
]
=
gb
.
buffer
;
}
else
{
for
(
i
=
0
;
i
<
c
->
planes
;
i
++
)
{
for
(
i
=
0
;
i
<
c
->
planes
;
i
++
)
{
plane_start
[
i
]
=
gb
.
buffer
;
plane_start
[
i
]
=
gb
.
buffer
;
if
(
bytestream2_get_bytes_left
(
&
gb
)
<
256
+
4
*
c
->
slices
)
{
if
(
bytestream2_get_bytes_left
(
&
gb
)
<
256
+
4
*
c
->
slices
)
{
...
@@ -379,6 +560,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
...
@@ -379,6 +560,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
return
AVERROR_INVALIDDATA
;
return
AVERROR_INVALIDDATA
;
}
}
c
->
frame_info
=
bytestream2_get_le32u
(
&
gb
);
c
->
frame_info
=
bytestream2_get_le32u
(
&
gb
);
}
av_log
(
avctx
,
AV_LOG_DEBUG
,
"frame information flags %"
PRIX32
"
\n
"
,
av_log
(
avctx
,
AV_LOG_DEBUG
,
"frame information flags %"
PRIX32
"
\n
"
,
c
->
frame_info
);
c
->
frame_info
);
...
@@ -464,6 +646,15 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
...
@@ -464,6 +646,15 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
}
}
}
}
break
;
break
;
case
AV_PIX_FMT_YUV422P10
:
for
(
i
=
0
;
i
<
3
;
i
++
)
{
ret
=
decode_plane10
(
c
,
i
,
(
uint16_t
*
)
frame
.
f
->
data
[
i
],
1
,
frame
.
f
->
linesize
[
i
]
/
2
,
avctx
->
width
>>
!!
i
,
avctx
->
height
,
plane_start
[
i
],
plane_start
[
i
+
1
]
-
1024
,
c
->
frame_pred
==
PRED_LEFT
);
if
(
ret
)
return
ret
;
}
break
;
}
}
frame
.
f
->
key_frame
=
1
;
frame
.
f
->
key_frame
=
1
;
...
@@ -484,13 +675,7 @@ static av_cold int decode_init(AVCodecContext *avctx)
...
@@ -484,13 +675,7 @@ static av_cold int decode_init(AVCodecContext *avctx)
ff_bswapdsp_init
(
&
c
->
bdsp
);
ff_bswapdsp_init
(
&
c
->
bdsp
);
if
(
avctx
->
extradata_size
<
16
)
{
if
(
avctx
->
extradata_size
>=
16
)
{
av_log
(
avctx
,
AV_LOG_ERROR
,
"Insufficient extradata size %d, should be at least 16
\n
"
,
avctx
->
extradata_size
);
return
AVERROR_INVALIDDATA
;
}
av_log
(
avctx
,
AV_LOG_DEBUG
,
"Encoder version %d.%d.%d.%d
\n
"
,
av_log
(
avctx
,
AV_LOG_DEBUG
,
"Encoder version %d.%d.%d.%d
\n
"
,
avctx
->
extradata
[
3
],
avctx
->
extradata
[
2
],
avctx
->
extradata
[
3
],
avctx
->
extradata
[
2
],
avctx
->
extradata
[
1
],
avctx
->
extradata
[
0
]);
avctx
->
extradata
[
1
],
avctx
->
extradata
[
0
]);
...
@@ -505,6 +690,21 @@ static av_cold int decode_init(AVCodecContext *avctx)
...
@@ -505,6 +690,21 @@ static av_cold int decode_init(AVCodecContext *avctx)
c
->
slices
=
(
c
->
flags
>>
24
)
+
1
;
c
->
slices
=
(
c
->
flags
>>
24
)
+
1
;
c
->
compression
=
c
->
flags
&
1
;
c
->
compression
=
c
->
flags
&
1
;
c
->
interlaced
=
c
->
flags
&
0x800
;
c
->
interlaced
=
c
->
flags
&
0x800
;
}
else
if
(
avctx
->
extradata_size
==
8
)
{
av_log
(
avctx
,
AV_LOG_DEBUG
,
"Encoder version %d.%d.%d.%d
\n
"
,
avctx
->
extradata
[
3
],
avctx
->
extradata
[
2
],
avctx
->
extradata
[
1
],
avctx
->
extradata
[
0
]);
av_log
(
avctx
,
AV_LOG_DEBUG
,
"Original format %"
PRIX32
"
\n
"
,
AV_RB32
(
avctx
->
extradata
+
4
));
c
->
interlaced
=
0
;
c
->
pro
=
1
;
c
->
frame_info_size
=
4
;
}
else
{
av_log
(
avctx
,
AV_LOG_ERROR
,
"Insufficient extradata size %d, should be at least 16
\n
"
,
avctx
->
extradata_size
);
return
AVERROR_INVALIDDATA
;
}
c
->
slice_bits_size
=
0
;
c
->
slice_bits_size
=
0
;
...
@@ -527,6 +727,10 @@ static av_cold int decode_init(AVCodecContext *avctx)
...
@@ -527,6 +727,10 @@ static av_cold int decode_init(AVCodecContext *avctx)
avctx
->
pix_fmt
=
AV_PIX_FMT_YUV422P
;
avctx
->
pix_fmt
=
AV_PIX_FMT_YUV422P
;
avctx
->
colorspace
=
AVCOL_SPC_BT470BG
;
avctx
->
colorspace
=
AVCOL_SPC_BT470BG
;
break
;
break
;
case
MKTAG
(
'U'
,
'Q'
,
'Y'
,
'2'
):
c
->
planes
=
3
;
avctx
->
pix_fmt
=
AV_PIX_FMT_YUV422P10
;
break
;
case
MKTAG
(
'U'
,
'L'
,
'H'
,
'0'
):
case
MKTAG
(
'U'
,
'L'
,
'H'
,
'0'
):
c
->
planes
=
3
;
c
->
planes
=
3
;
avctx
->
pix_fmt
=
AV_PIX_FMT_YUV420P
;
avctx
->
pix_fmt
=
AV_PIX_FMT_YUV420P
;
...
...
libavformat/riff.c
View file @
c5230955
...
@@ -342,6 +342,7 @@ const AVCodecTag ff_codec_bmp_tags[] = {
...
@@ -342,6 +342,7 @@ const AVCodecTag ff_codec_bmp_tags[] = {
{
AV_CODEC_ID_UTVIDEO
,
MKTAG
(
'U'
,
'L'
,
'Y'
,
'2'
)
},
{
AV_CODEC_ID_UTVIDEO
,
MKTAG
(
'U'
,
'L'
,
'Y'
,
'2'
)
},
{
AV_CODEC_ID_UTVIDEO
,
MKTAG
(
'U'
,
'L'
,
'H'
,
'0'
)
},
{
AV_CODEC_ID_UTVIDEO
,
MKTAG
(
'U'
,
'L'
,
'H'
,
'0'
)
},
{
AV_CODEC_ID_UTVIDEO
,
MKTAG
(
'U'
,
'L'
,
'H'
,
'2'
)
},
{
AV_CODEC_ID_UTVIDEO
,
MKTAG
(
'U'
,
'L'
,
'H'
,
'2'
)
},
{
AV_CODEC_ID_UTVIDEO
,
MKTAG
(
'U'
,
'Q'
,
'Y'
,
'2'
)
},
{
AV_CODEC_ID_VBLE
,
MKTAG
(
'V'
,
'B'
,
'L'
,
'E'
)
},
{
AV_CODEC_ID_VBLE
,
MKTAG
(
'V'
,
'B'
,
'L'
,
'E'
)
},
{
AV_CODEC_ID_ESCAPE130
,
MKTAG
(
'E'
,
'1'
,
'3'
,
'0'
)
},
{
AV_CODEC_ID_ESCAPE130
,
MKTAG
(
'E'
,
'1'
,
'3'
,
'0'
)
},
{
AV_CODEC_ID_DXTORY
,
MKTAG
(
'x'
,
't'
,
'o'
,
'r'
)
},
{
AV_CODEC_ID_DXTORY
,
MKTAG
(
'x'
,
't'
,
'o'
,
'r'
)
},
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment