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
faa94a57
Commit
faa94a57
authored
Apr 07, 2017
by
Paul B Mahol
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
avcodec/utvideodec: add support for gradient prediction
Signed-off-by:
Paul B Mahol
<
onemda@gmail.com
>
parent
2e664b9c
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
225 additions
and
5 deletions
+225
-5
utvideodec.c
libavcodec/utvideodec.c
+225
-5
No files found.
libavcodec/utvideodec.c
View file @
faa94a57
...
@@ -602,6 +602,189 @@ static void restore_median_packed_il(uint8_t *src, int step, ptrdiff_t stride,
...
@@ -602,6 +602,189 @@ static void restore_median_packed_il(uint8_t *src, int step, ptrdiff_t stride,
}
}
}
}
static
void
restore_gradient_planar
(
UtvideoContext
*
c
,
uint8_t
*
src
,
ptrdiff_t
stride
,
int
width
,
int
height
,
int
slices
,
int
rmode
)
{
int
i
,
j
,
slice
;
int
A
,
B
,
C
;
uint8_t
*
bsrc
;
int
slice_start
,
slice_height
;
const
int
cmask
=
~
rmode
;
for
(
slice
=
0
;
slice
<
slices
;
slice
++
)
{
slice_start
=
((
slice
*
height
)
/
slices
)
&
cmask
;
slice_height
=
((((
slice
+
1
)
*
height
)
/
slices
)
&
cmask
)
-
slice_start
;
if
(
!
slice_height
)
continue
;
bsrc
=
src
+
slice_start
*
stride
;
// first line - left neighbour prediction
bsrc
[
0
]
+=
0x80
;
c
->
llviddsp
.
add_left_pred
(
bsrc
,
bsrc
,
width
,
0
);
bsrc
+=
stride
;
if
(
slice_height
<=
1
)
continue
;
for
(
j
=
1
;
j
<
slice_height
;
j
++
)
{
// second line - first element has top prediction, the rest uses gradient
bsrc
[
0
]
=
(
bsrc
[
0
]
+
bsrc
[
-
stride
])
&
0xFF
;
for
(
i
=
1
;
i
<
width
;
i
++
)
{
A
=
bsrc
[
i
-
stride
];
B
=
bsrc
[
i
-
(
stride
+
1
)];
C
=
bsrc
[
i
-
1
];
bsrc
[
i
]
=
(
A
-
B
+
C
+
bsrc
[
i
])
&
0xFF
;
}
bsrc
+=
stride
;
}
}
}
static
void
restore_gradient_planar_il
(
UtvideoContext
*
c
,
uint8_t
*
src
,
ptrdiff_t
stride
,
int
width
,
int
height
,
int
slices
,
int
rmode
)
{
int
i
,
j
,
slice
;
int
A
,
B
,
C
;
uint8_t
*
bsrc
;
int
slice_start
,
slice_height
;
const
int
cmask
=
~
(
rmode
?
3
:
1
);
const
ptrdiff_t
stride2
=
stride
<<
1
;
for
(
slice
=
0
;
slice
<
slices
;
slice
++
)
{
slice_start
=
((
slice
*
height
)
/
slices
)
&
cmask
;
slice_height
=
((((
slice
+
1
)
*
height
)
/
slices
)
&
cmask
)
-
slice_start
;
slice_height
>>=
1
;
if
(
!
slice_height
)
continue
;
bsrc
=
src
+
slice_start
*
stride
;
// first line - left neighbour prediction
bsrc
[
0
]
+=
0x80
;
A
=
c
->
llviddsp
.
add_left_pred
(
bsrc
,
bsrc
,
width
,
0
);
c
->
llviddsp
.
add_left_pred
(
bsrc
+
stride
,
bsrc
+
stride
,
width
,
A
);
bsrc
+=
stride2
;
if
(
slice_height
<=
1
)
continue
;
for
(
j
=
1
;
j
<
slice_height
;
j
++
)
{
// second line - first element has top prediction, the rest uses gradient
bsrc
[
0
]
=
(
bsrc
[
0
]
+
bsrc
[
-
stride2
])
&
0xFF
;
for
(
i
=
1
;
i
<
width
;
i
++
)
{
A
=
bsrc
[
i
-
stride2
];
B
=
bsrc
[
i
-
(
stride2
+
1
)];
C
=
bsrc
[
i
-
1
];
bsrc
[
i
]
=
(
A
-
B
+
C
+
bsrc
[
i
])
&
0xFF
;
}
for
(
i
=
0
;
i
<
width
;
i
++
)
{
A
=
bsrc
[
i
-
stride
];
B
=
bsrc
[
i
-
(
1
+
stride
)];
C
=
bsrc
[
i
-
1
+
stride
];
bsrc
[
i
+
stride
]
=
(
A
-
B
+
C
+
bsrc
[
i
+
stride
])
&
0xFF
;
}
bsrc
+=
stride2
;
}
}
}
static
void
restore_gradient_packed
(
uint8_t
*
src
,
int
step
,
ptrdiff_t
stride
,
int
width
,
int
height
,
int
slices
,
int
rmode
)
{
int
i
,
j
,
slice
;
int
A
,
B
,
C
;
uint8_t
*
bsrc
;
int
slice_start
,
slice_height
;
const
int
cmask
=
~
rmode
;
for
(
slice
=
0
;
slice
<
slices
;
slice
++
)
{
slice_start
=
((
slice
*
height
)
/
slices
)
&
cmask
;
slice_height
=
((((
slice
+
1
)
*
height
)
/
slices
)
&
cmask
)
-
slice_start
;
if
(
!
slice_height
)
continue
;
bsrc
=
src
+
slice_start
*
stride
;
// first line - left neighbour prediction
bsrc
[
0
]
+=
0x80
;
A
=
bsrc
[
0
];
for
(
i
=
step
;
i
<
width
*
step
;
i
+=
step
)
{
bsrc
[
i
]
+=
A
;
A
=
bsrc
[
i
];
}
bsrc
+=
stride
;
if
(
slice_height
<=
1
)
continue
;
for
(
j
=
1
;
j
<
slice_height
;
j
++
)
{
// second line - first element has top prediction, the rest uses gradient
C
=
bsrc
[
-
stride
];
bsrc
[
0
]
+=
C
;
for
(
i
=
step
;
i
<
width
*
step
;
i
+=
step
)
{
A
=
bsrc
[
i
-
stride
];
B
=
bsrc
[
i
-
(
stride
+
step
)];
C
=
bsrc
[
i
-
step
];
bsrc
[
i
]
=
(
A
-
B
+
C
+
bsrc
[
i
])
&
0xFF
;
}
bsrc
+=
stride
;
}
}
}
static
void
restore_gradient_packed_il
(
uint8_t
*
src
,
int
step
,
ptrdiff_t
stride
,
int
width
,
int
height
,
int
slices
,
int
rmode
)
{
int
i
,
j
,
slice
;
int
A
,
B
,
C
;
uint8_t
*
bsrc
;
int
slice_start
,
slice_height
;
const
int
cmask
=
~
(
rmode
?
3
:
1
);
const
ptrdiff_t
stride2
=
stride
<<
1
;
for
(
slice
=
0
;
slice
<
slices
;
slice
++
)
{
slice_start
=
((
slice
*
height
)
/
slices
)
&
cmask
;
slice_height
=
((((
slice
+
1
)
*
height
)
/
slices
)
&
cmask
)
-
slice_start
;
slice_height
>>=
1
;
if
(
!
slice_height
)
continue
;
bsrc
=
src
+
slice_start
*
stride
;
// first line - left neighbour prediction
bsrc
[
0
]
+=
0x80
;
A
=
bsrc
[
0
];
for
(
i
=
step
;
i
<
width
*
step
;
i
+=
step
)
{
bsrc
[
i
]
+=
A
;
A
=
bsrc
[
i
];
}
for
(
i
=
0
;
i
<
width
*
step
;
i
+=
step
)
{
bsrc
[
stride
+
i
]
+=
A
;
A
=
bsrc
[
stride
+
i
];
}
bsrc
+=
stride2
;
if
(
slice_height
<=
1
)
continue
;
for
(
j
=
1
;
j
<
slice_height
;
j
++
)
{
// second line - first element has top prediction, the rest uses gradient
C
=
bsrc
[
-
stride2
];
bsrc
[
0
]
+=
C
;
for
(
i
=
step
;
i
<
width
*
step
;
i
+=
step
)
{
A
=
bsrc
[
i
-
stride2
];
B
=
bsrc
[
i
-
(
stride2
+
step
)];
C
=
bsrc
[
i
-
step
];
bsrc
[
i
]
=
(
A
-
B
+
C
+
bsrc
[
i
])
&
0xFF
;
}
for
(
i
=
0
;
i
<
width
*
step
;
i
+=
step
)
{
A
=
bsrc
[
i
-
stride
];
B
=
bsrc
[
i
-
(
step
+
stride
)];
C
=
bsrc
[
i
-
step
+
stride
];
bsrc
[
i
+
stride
]
=
(
A
-
B
+
C
+
bsrc
[
i
+
stride
])
&
0xFF
;
}
bsrc
+=
stride2
;
}
}
}
static
int
decode_frame
(
AVCodecContext
*
avctx
,
void
*
data
,
int
*
got_frame
,
static
int
decode_frame
(
AVCodecContext
*
avctx
,
void
*
data
,
int
*
got_frame
,
AVPacket
*
avpkt
)
AVPacket
*
avpkt
)
{
{
...
@@ -687,11 +870,6 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
...
@@ -687,11 +870,6 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
c
->
frame_pred
=
(
c
->
frame_info
>>
8
)
&
3
;
c
->
frame_pred
=
(
c
->
frame_info
>>
8
)
&
3
;
if
(
c
->
frame_pred
==
PRED_GRADIENT
)
{
avpriv_request_sample
(
avctx
,
"Frame with gradient prediction"
);
return
AVERROR_PATCHWELCOME
;
}
av_fast_malloc
(
&
c
->
slice_bits
,
&
c
->
slice_bits_size
,
av_fast_malloc
(
&
c
->
slice_bits
,
&
c
->
slice_bits_size
,
max_slice_size
+
AV_INPUT_BUFFER_PADDING_SIZE
);
max_slice_size
+
AV_INPUT_BUFFER_PADDING_SIZE
);
...
@@ -721,6 +899,17 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
...
@@ -721,6 +899,17 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
avctx
->
width
,
avctx
->
height
,
c
->
slices
,
avctx
->
width
,
avctx
->
height
,
c
->
slices
,
0
);
0
);
}
}
}
else
if
(
c
->
frame_pred
==
PRED_GRADIENT
)
{
if
(
!
c
->
interlaced
)
{
restore_gradient_packed
(
frame
.
f
->
data
[
0
]
+
ff_ut_rgb_order
[
i
],
c
->
planes
,
frame
.
f
->
linesize
[
0
],
avctx
->
width
,
avctx
->
height
,
c
->
slices
,
0
);
}
else
{
restore_gradient_packed_il
(
frame
.
f
->
data
[
0
]
+
ff_ut_rgb_order
[
i
],
c
->
planes
,
frame
.
f
->
linesize
[
0
],
avctx
->
width
,
avctx
->
height
,
c
->
slices
,
0
);
}
}
}
}
}
restore_rgb_planes
(
frame
.
f
->
data
[
0
],
c
->
planes
,
frame
.
f
->
linesize
[
0
],
restore_rgb_planes
(
frame
.
f
->
data
[
0
],
c
->
planes
,
frame
.
f
->
linesize
[
0
],
...
@@ -757,6 +946,17 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
...
@@ -757,6 +946,17 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
avctx
->
height
>>
!!
i
,
avctx
->
height
>>
!!
i
,
c
->
slices
,
!
i
);
c
->
slices
,
!
i
);
}
}
}
else
if
(
c
->
frame_pred
==
PRED_GRADIENT
)
{
if
(
!
c
->
interlaced
)
{
restore_gradient_planar
(
c
,
frame
.
f
->
data
[
i
],
frame
.
f
->
linesize
[
i
],
avctx
->
width
>>
!!
i
,
avctx
->
height
>>
!!
i
,
c
->
slices
,
!
i
);
}
else
{
restore_gradient_planar_il
(
c
,
frame
.
f
->
data
[
i
],
frame
.
f
->
linesize
[
i
],
avctx
->
width
>>
!!
i
,
avctx
->
height
>>
!!
i
,
c
->
slices
,
!
i
);
}
}
}
}
}
break
;
break
;
...
@@ -777,6 +977,16 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
...
@@ -777,6 +977,16 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
avctx
->
width
>>
!!
i
,
avctx
->
height
,
avctx
->
width
>>
!!
i
,
avctx
->
height
,
c
->
slices
,
0
);
c
->
slices
,
0
);
}
}
}
else
if
(
c
->
frame_pred
==
PRED_GRADIENT
)
{
if
(
!
c
->
interlaced
)
{
restore_gradient_planar
(
c
,
frame
.
f
->
data
[
i
],
frame
.
f
->
linesize
[
i
],
avctx
->
width
>>
!!
i
,
avctx
->
height
,
c
->
slices
,
0
);
}
else
{
restore_gradient_planar_il
(
c
,
frame
.
f
->
data
[
i
],
frame
.
f
->
linesize
[
i
],
avctx
->
width
>>
!!
i
,
avctx
->
height
,
c
->
slices
,
0
);
}
}
}
}
}
break
;
break
;
...
@@ -797,6 +1007,16 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
...
@@ -797,6 +1007,16 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
avctx
->
width
,
avctx
->
height
,
avctx
->
width
,
avctx
->
height
,
c
->
slices
,
0
);
c
->
slices
,
0
);
}
}
}
else
if
(
c
->
frame_pred
==
PRED_GRADIENT
)
{
if
(
!
c
->
interlaced
)
{
restore_gradient_planar
(
c
,
frame
.
f
->
data
[
i
],
frame
.
f
->
linesize
[
i
],
avctx
->
width
,
avctx
->
height
,
c
->
slices
,
0
);
}
else
{
restore_gradient_planar_il
(
c
,
frame
.
f
->
data
[
i
],
frame
.
f
->
linesize
[
i
],
avctx
->
width
,
avctx
->
height
,
c
->
slices
,
0
);
}
}
}
}
}
break
;
break
;
...
...
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