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
844ff494
Commit
844ff494
authored
Aug 19, 2018
by
Kieran Kunhya
Committed by
Paul B Mahol
Aug 25, 2018
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
mpeg4video: Add Studio DPCM support
parent
323095a6
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
146 additions
and
20 deletions
+146
-20
mpeg4videodec.c
libavcodec/mpeg4videodec.c
+88
-3
mpegvideo.c
libavcodec/mpegvideo.c
+56
-17
mpegvideo.h
libavcodec/mpegvideo.h
+2
-0
No files found.
libavcodec/mpeg4videodec.c
View file @
844ff494
...
@@ -24,6 +24,7 @@
...
@@ -24,6 +24,7 @@
#include "libavutil/internal.h"
#include "libavutil/internal.h"
#include "libavutil/opt.h"
#include "libavutil/opt.h"
#include "libavutil/pixdesc.h"
#include "error_resilience.h"
#include "error_resilience.h"
#include "hwaccel.h"
#include "hwaccel.h"
#include "idctdsp.h"
#include "idctdsp.h"
...
@@ -36,6 +37,7 @@
...
@@ -36,6 +37,7 @@
#include "profiles.h"
#include "profiles.h"
#include "thread.h"
#include "thread.h"
#include "xvididct.h"
#include "xvididct.h"
#include "unary.h"
/* The defines below define the number of bits that are read at once for
/* The defines below define the number of bits that are read at once for
* reading vlc values. Changing these may improve speed and data cache needs
* reading vlc values. Changing these may improve speed and data cache needs
...
@@ -1923,10 +1925,91 @@ static int mpeg4_decode_studio_block(MpegEncContext *s, int32_t block[64], int n
...
@@ -1923,10 +1925,91 @@ static int mpeg4_decode_studio_block(MpegEncContext *s, int32_t block[64], int n
return
0
;
return
0
;
}
}
static
int
mpeg4_decode_dpcm_macroblock
(
MpegEncContext
*
s
,
int16_t
macroblock
[
256
],
int
n
)
{
int
i
,
j
,
w
,
h
,
idx
=
0
;
int
block_mean
,
rice_parameter
,
rice_prefix_code
,
rice_suffix_code
,
dpcm_residual
,
left
,
top
,
topleft
,
min_left_top
,
max_left_top
,
p
,
p2
,
output
;
h
=
16
>>
(
n
?
s
->
chroma_y_shift
:
0
);
w
=
16
>>
(
n
?
s
->
chroma_x_shift
:
0
);
block_mean
=
get_bits
(
&
s
->
gb
,
s
->
avctx
->
bits_per_raw_sample
);
if
(
block_mean
==
0
){
av_log
(
s
->
avctx
,
AV_LOG_ERROR
,
"Forbidden block_mean
\n
"
);
return
AVERROR_INVALIDDATA
;
}
s
->
last_dc
[
n
]
=
block_mean
*
(
1
<<
(
s
->
dct_precision
+
s
->
intra_dc_precision
));
rice_parameter
=
get_bits
(
&
s
->
gb
,
4
);
if
(
rice_parameter
==
0
)
{
av_log
(
s
->
avctx
,
AV_LOG_ERROR
,
"Forbidden rice_parameter
\n
"
);
return
AVERROR_INVALIDDATA
;
}
if
(
rice_parameter
==
15
)
rice_parameter
=
0
;
if
(
rice_parameter
>
11
)
{
av_log
(
s
->
avctx
,
AV_LOG_ERROR
,
"Forbidden rice_parameter
\n
"
);
return
AVERROR_INVALIDDATA
;
}
for
(
i
=
0
;
i
<
h
;
i
++
)
{
output
=
1
<<
(
s
->
avctx
->
bits_per_raw_sample
-
1
);
top
=
1
<<
(
s
->
avctx
->
bits_per_raw_sample
-
1
);
for
(
j
=
0
;
j
<
w
;
j
++
)
{
left
=
output
;
topleft
=
top
;
rice_prefix_code
=
get_unary
(
&
s
->
gb
,
1
,
12
);
/* Escape */
if
(
rice_prefix_code
==
11
)
dpcm_residual
=
get_bits
(
&
s
->
gb
,
s
->
avctx
->
bits_per_raw_sample
);
else
{
rice_suffix_code
=
get_bitsz
(
&
s
->
gb
,
rice_parameter
);
dpcm_residual
=
(
rice_prefix_code
<<
rice_parameter
)
+
rice_suffix_code
;
}
/* Map to a signed residual */
if
(
dpcm_residual
&
1
)
dpcm_residual
=
(
-
1
*
dpcm_residual
)
>>
1
;
else
dpcm_residual
=
(
dpcm_residual
>>
1
);
if
(
i
!=
0
)
top
=
macroblock
[
idx
-
w
];
p
=
left
+
top
-
topleft
;
min_left_top
=
FFMIN
(
left
,
top
);
if
(
p
<
min_left_top
)
p
=
min_left_top
;
max_left_top
=
FFMAX
(
left
,
top
);
if
(
p
>
max_left_top
)
p
=
max_left_top
;
p2
=
(
FFMIN
(
min_left_top
,
topleft
)
+
FFMAX
(
max_left_top
,
topleft
))
>>
1
;
if
(
p2
==
p
)
p2
=
block_mean
;
if
(
p2
>
p
)
dpcm_residual
*=
-
1
;
macroblock
[
idx
++
]
=
output
=
(
dpcm_residual
+
p
)
&
((
1
<<
s
->
avctx
->
bits_per_raw_sample
)
-
1
);
}
}
return
0
;
}
static
int
mpeg4_decode_studio_mb
(
MpegEncContext
*
s
,
int16_t
block_
[
12
][
64
])
static
int
mpeg4_decode_studio_mb
(
MpegEncContext
*
s
,
int16_t
block_
[
12
][
64
])
{
{
int
i
;
int
i
;
s
->
dpcm_direction
=
0
;
/* StudioMacroblock */
/* StudioMacroblock */
/* Assumes I-VOP */
/* Assumes I-VOP */
s
->
mb_intra
=
1
;
s
->
mb_intra
=
1
;
...
@@ -1945,9 +2028,11 @@ static int mpeg4_decode_studio_mb(MpegEncContext *s, int16_t block_[12][64])
...
@@ -1945,9 +2028,11 @@ static int mpeg4_decode_studio_mb(MpegEncContext *s, int16_t block_[12][64])
}
else
{
}
else
{
/* DPCM */
/* DPCM */
check_marker
(
s
->
avctx
,
&
s
->
gb
,
"DPCM block start"
);
check_marker
(
s
->
avctx
,
&
s
->
gb
,
"DPCM block start"
);
avpriv_request_sample
(
s
->
avctx
,
"DPCM encoded block"
);
s
->
dpcm_direction
=
get_bits1
(
&
s
->
gb
)
?
-
1
:
1
;
next_start_code_studio
(
&
s
->
gb
);
for
(
i
=
0
;
i
<
3
;
i
++
)
{
return
SLICE_ERROR
;
if
(
mpeg4_decode_dpcm_macroblock
(
s
,
(
*
s
->
dpcm_macroblock
)[
i
],
i
)
<
0
)
return
AVERROR_INVALIDDATA
;
}
}
}
if
(
get_bits_left
(
&
s
->
gb
)
>=
24
&&
show_bits
(
&
s
->
gb
,
23
)
==
0
)
{
if
(
get_bits_left
(
&
s
->
gb
)
>=
24
&&
show_bits
(
&
s
->
gb
,
23
)
==
0
)
{
...
...
libavcodec/mpegvideo.c
View file @
844ff494
...
@@ -390,6 +390,8 @@ static int init_duplicate_context(MpegEncContext *s)
...
@@ -390,6 +390,8 @@ static int init_duplicate_context(MpegEncContext *s)
}
}
FF_ALLOCZ_OR_GOTO
(
s
->
avctx
,
s
->
block32
,
sizeof
(
*
s
->
block32
),
fail
)
FF_ALLOCZ_OR_GOTO
(
s
->
avctx
,
s
->
block32
,
sizeof
(
*
s
->
block32
),
fail
)
s
->
dpcm_direction
=
0
;
FF_ALLOCZ_OR_GOTO
(
s
->
avctx
,
s
->
dpcm_macroblock
,
sizeof
(
*
s
->
dpcm_macroblock
),
fail
)
if
(
s
->
avctx
->
codec_tag
==
AV_RL32
(
"VCR2"
))
{
if
(
s
->
avctx
->
codec_tag
==
AV_RL32
(
"VCR2"
))
{
// exchange uv
// exchange uv
...
@@ -427,6 +429,7 @@ static void free_duplicate_context(MpegEncContext *s)
...
@@ -427,6 +429,7 @@ static void free_duplicate_context(MpegEncContext *s)
av_freep
(
&
s
->
me
.
score_map
);
av_freep
(
&
s
->
me
.
score_map
);
av_freep
(
&
s
->
blocks
);
av_freep
(
&
s
->
blocks
);
av_freep
(
&
s
->
block32
);
av_freep
(
&
s
->
block32
);
av_freep
(
&
s
->
dpcm_macroblock
);
av_freep
(
&
s
->
ac_val_base
);
av_freep
(
&
s
->
ac_val_base
);
s
->
block
=
NULL
;
s
->
block
=
NULL
;
}
}
...
@@ -445,6 +448,8 @@ static void backup_duplicate_context(MpegEncContext *bak, MpegEncContext *src)
...
@@ -445,6 +448,8 @@ static void backup_duplicate_context(MpegEncContext *bak, MpegEncContext *src)
COPY
(
blocks
);
COPY
(
blocks
);
COPY
(
block
);
COPY
(
block
);
COPY
(
block32
);
COPY
(
block32
);
COPY
(
dpcm_macroblock
);
COPY
(
dpcm_direction
);
COPY
(
start_mb_y
);
COPY
(
start_mb_y
);
COPY
(
end_mb_y
);
COPY
(
end_mb_y
);
COPY
(
me
.
map_generation
);
COPY
(
me
.
map_generation
);
...
@@ -820,6 +825,8 @@ static void clear_context(MpegEncContext *s)
...
@@ -820,6 +825,8 @@ static void clear_context(MpegEncContext *s)
s
->
blocks
=
NULL
;
s
->
blocks
=
NULL
;
s
->
block32
=
NULL
;
s
->
block32
=
NULL
;
memset
(
s
->
pblocks
,
0
,
sizeof
(
s
->
pblocks
));
memset
(
s
->
pblocks
,
0
,
sizeof
(
s
->
pblocks
));
s
->
dpcm_direction
=
0
;
s
->
dpcm_macroblock
=
NULL
;
s
->
ac_val_base
=
NULL
;
s
->
ac_val_base
=
NULL
;
s
->
ac_val
[
0
]
=
s
->
ac_val
[
0
]
=
s
->
ac_val
[
1
]
=
s
->
ac_val
[
1
]
=
...
@@ -2132,23 +2139,55 @@ void mpv_reconstruct_mb_internal(MpegEncContext *s, int16_t block[12][64],
...
@@ -2132,23 +2139,55 @@ void mpv_reconstruct_mb_internal(MpegEncContext *s, int16_t block[12][64],
TODO: Integrate 10-bit properly into mpegvideo.c so that ER works properly */
TODO: Integrate 10-bit properly into mpegvideo.c so that ER works properly */
if
(
s
->
avctx
->
bits_per_raw_sample
>
8
){
if
(
s
->
avctx
->
bits_per_raw_sample
>
8
){
const
int
act_block_size
=
block_size
*
2
;
const
int
act_block_size
=
block_size
*
2
;
s
->
idsp
.
idct_put
(
dest_y
,
dct_linesize
,
(
int16_t
*
)(
*
s
->
block32
)[
0
]);
s
->
idsp
.
idct_put
(
dest_y
+
act_block_size
,
dct_linesize
,
(
int16_t
*
)(
*
s
->
block32
)[
1
]);
if
(
s
->
dpcm_direction
==
0
)
{
s
->
idsp
.
idct_put
(
dest_y
+
dct_offset
,
dct_linesize
,
(
int16_t
*
)(
*
s
->
block32
)[
2
]);
s
->
idsp
.
idct_put
(
dest_y
,
dct_linesize
,
(
int16_t
*
)(
*
s
->
block32
)[
0
]);
s
->
idsp
.
idct_put
(
dest_y
+
dct_offset
+
act_block_size
,
dct_linesize
,
(
int16_t
*
)(
*
s
->
block32
)[
3
]);
s
->
idsp
.
idct_put
(
dest_y
+
act_block_size
,
dct_linesize
,
(
int16_t
*
)(
*
s
->
block32
)[
1
]);
s
->
idsp
.
idct_put
(
dest_y
+
dct_offset
,
dct_linesize
,
(
int16_t
*
)(
*
s
->
block32
)[
2
]);
dct_linesize
=
uvlinesize
<<
s
->
interlaced_dct
;
s
->
idsp
.
idct_put
(
dest_y
+
dct_offset
+
act_block_size
,
dct_linesize
,
(
int16_t
*
)(
*
s
->
block32
)[
3
]);
dct_offset
=
s
->
interlaced_dct
?
uvlinesize
:
uvlinesize
*
block_size
;
dct_linesize
=
uvlinesize
<<
s
->
interlaced_dct
;
s
->
idsp
.
idct_put
(
dest_cb
,
dct_linesize
,
(
int16_t
*
)(
*
s
->
block32
)[
4
]);
dct_offset
=
s
->
interlaced_dct
?
uvlinesize
:
uvlinesize
*
block_size
;
s
->
idsp
.
idct_put
(
dest_cr
,
dct_linesize
,
(
int16_t
*
)(
*
s
->
block32
)[
5
]);
s
->
idsp
.
idct_put
(
dest_cb
+
dct_offset
,
dct_linesize
,
(
int16_t
*
)(
*
s
->
block32
)[
6
]);
s
->
idsp
.
idct_put
(
dest_cb
,
dct_linesize
,
(
int16_t
*
)(
*
s
->
block32
)[
4
]);
s
->
idsp
.
idct_put
(
dest_cr
+
dct_offset
,
dct_linesize
,
(
int16_t
*
)(
*
s
->
block32
)[
7
]);
s
->
idsp
.
idct_put
(
dest_cr
,
dct_linesize
,
(
int16_t
*
)(
*
s
->
block32
)[
5
]);
if
(
!
s
->
chroma_x_shift
){
//Chroma444
s
->
idsp
.
idct_put
(
dest_cb
+
dct_offset
,
dct_linesize
,
(
int16_t
*
)(
*
s
->
block32
)[
6
]);
s
->
idsp
.
idct_put
(
dest_cb
+
act_block_size
,
dct_linesize
,
(
int16_t
*
)(
*
s
->
block32
)[
8
]);
s
->
idsp
.
idct_put
(
dest_cr
+
dct_offset
,
dct_linesize
,
(
int16_t
*
)(
*
s
->
block32
)[
7
]);
s
->
idsp
.
idct_put
(
dest_cr
+
act_block_size
,
dct_linesize
,
(
int16_t
*
)(
*
s
->
block32
)[
9
]);
if
(
!
s
->
chroma_x_shift
){
//Chroma444
s
->
idsp
.
idct_put
(
dest_cb
+
act_block_size
+
dct_offset
,
dct_linesize
,
(
int16_t
*
)(
*
s
->
block32
)[
10
]);
s
->
idsp
.
idct_put
(
dest_cb
+
act_block_size
,
dct_linesize
,
(
int16_t
*
)(
*
s
->
block32
)[
8
]);
s
->
idsp
.
idct_put
(
dest_cr
+
act_block_size
+
dct_offset
,
dct_linesize
,
(
int16_t
*
)(
*
s
->
block32
)[
11
]);
s
->
idsp
.
idct_put
(
dest_cr
+
act_block_size
,
dct_linesize
,
(
int16_t
*
)(
*
s
->
block32
)[
9
]);
s
->
idsp
.
idct_put
(
dest_cb
+
act_block_size
+
dct_offset
,
dct_linesize
,
(
int16_t
*
)(
*
s
->
block32
)[
10
]);
s
->
idsp
.
idct_put
(
dest_cr
+
act_block_size
+
dct_offset
,
dct_linesize
,
(
int16_t
*
)(
*
s
->
block32
)[
11
]);
}
}
else
if
(
s
->
dpcm_direction
==
1
)
{
int
i
,
w
,
h
;
uint16_t
*
dest_pcm
[
3
]
=
{(
uint16_t
*
)
dest_y
,
(
uint16_t
*
)
dest_cb
,
(
uint16_t
*
)
dest_cr
};
int
linesize
[
3
]
=
{
dct_linesize
,
uvlinesize
,
uvlinesize
};
for
(
i
=
0
;
i
<
3
;
i
++
)
{
int
idx
=
0
;
int
vsub
=
i
?
s
->
chroma_y_shift
:
0
;
int
hsub
=
i
?
s
->
chroma_x_shift
:
0
;
for
(
h
=
0
;
h
<
(
16
>>
vsub
);
h
++
){
for
(
w
=
0
;
w
<
(
16
>>
hsub
);
w
++
)
dest_pcm
[
i
][
w
]
=
(
*
s
->
dpcm_macroblock
)[
i
][
idx
++
];
dest_pcm
[
i
]
+=
linesize
[
i
]
/
2
;
}
}
}
else
if
(
s
->
dpcm_direction
==
-
1
)
{
int
i
,
w
,
h
;
uint16_t
*
dest_pcm
[
3
]
=
{(
uint16_t
*
)
dest_y
,
(
uint16_t
*
)
dest_cb
,
(
uint16_t
*
)
dest_cr
};
int
linesize
[
3
]
=
{
dct_linesize
,
uvlinesize
,
uvlinesize
};
for
(
i
=
0
;
i
<
3
;
i
++
)
{
int
idx
=
0
;
int
vsub
=
i
?
s
->
chroma_y_shift
:
0
;
int
hsub
=
i
?
s
->
chroma_x_shift
:
0
;
dest_pcm
[
i
]
+=
(
linesize
[
i
]
/
2
)
*
((
16
>>
vsub
)
-
1
);
for
(
h
=
(
16
>>
vsub
)
-
1
;
h
>=
1
;
h
--
){
for
(
w
=
(
16
>>
hsub
)
-
1
;
w
>=
1
;
w
--
)
dest_pcm
[
i
][
w
]
=
(
*
s
->
dpcm_macroblock
)[
i
][
idx
++
];
dest_pcm
[
i
]
-=
linesize
[
i
]
/
2
;
}
}
}
}
}
}
/* dct only in intra block */
/* dct only in intra block */
...
...
libavcodec/mpegvideo.h
View file @
844ff494
...
@@ -509,6 +509,8 @@ typedef struct MpegEncContext {
...
@@ -509,6 +509,8 @@ typedef struct MpegEncContext {
int
(
*
decode_mb
)(
struct
MpegEncContext
*
s
,
int16_t
block
[
12
][
64
]);
// used by some codecs to avoid a switch()
int
(
*
decode_mb
)(
struct
MpegEncContext
*
s
,
int16_t
block
[
12
][
64
]);
// used by some codecs to avoid a switch()
int32_t
(
*
block32
)[
12
][
64
];
int32_t
(
*
block32
)[
12
][
64
];
int
dpcm_direction
;
// 0 = DCT, 1 = DPCM top to bottom scan, -1 = DPCM bottom to top scan
int16_t
(
*
dpcm_macroblock
)[
3
][
256
];
#define SLICE_OK 0
#define SLICE_OK 0
#define SLICE_ERROR -1
#define SLICE_ERROR -1
...
...
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