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
004ebd4b
Commit
004ebd4b
authored
Jun 18, 2019
by
Baptiste Coudurier
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
avcodec/dvdec: correctly decode bottom mb row in 1080i field mode
parent
33203a08
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
72 additions
and
20 deletions
+72
-20
dv.h
libavcodec/dv.h
+2
-0
dvdec.c
libavcodec/dvdec.c
+70
-20
No files found.
libavcodec/dv.h
View file @
004ebd4b
...
...
@@ -31,6 +31,7 @@
#include "dv_profile.h"
#include "me_cmp.h"
#include "vlc.h"
#include "idctdsp.h"
typedef
struct
DVwork_chunk
{
uint16_t
buf_offset
;
...
...
@@ -52,6 +53,7 @@ typedef struct DVVideoContext {
me_cmp_func
ildct_cmp
;
DVwork_chunk
work_chunks
[
4
*
12
*
27
];
uint32_t
idct_factor
[
2
*
4
*
16
*
64
];
IDCTDSPContext
idsp
;
int
quant_deadzone
;
}
DVVideoContext
;
...
...
libavcodec/dvdec.c
View file @
004ebd4b
...
...
@@ -45,7 +45,6 @@
#include "dv_profile_internal.h"
#include "dvdata.h"
#include "get_bits.h"
#include "idctdsp.h"
#include "internal.h"
#include "put_bits.h"
#include "simple_idct.h"
...
...
@@ -177,24 +176,22 @@ static void dv_init_weight_tables(DVVideoContext *ctx, const AVDVProfile *d)
static
av_cold
int
dvvideo_decode_init
(
AVCodecContext
*
avctx
)
{
DVVideoContext
*
s
=
avctx
->
priv_data
;
IDCTDSPContext
idsp
;
int
i
;
memset
(
&
idsp
,
0
,
sizeof
(
idsp
));
ff_idctdsp_init
(
&
idsp
,
avctx
);
ff_idctdsp_init
(
&
s
->
idsp
,
avctx
);
for
(
i
=
0
;
i
<
64
;
i
++
)
s
->
dv_zigzag
[
0
][
i
]
=
idsp
.
idct_permutation
[
ff_zigzag_direct
[
i
]];
s
->
dv_zigzag
[
0
][
i
]
=
s
->
idsp
.
idct_permutation
[
ff_zigzag_direct
[
i
]];
if
(
avctx
->
lowres
){
for
(
i
=
0
;
i
<
64
;
i
++
){
int
j
=
ff_dv_zigzag248_direct
[
i
];
s
->
dv_zigzag
[
1
][
i
]
=
idsp
.
idct_permutation
[(
j
&
7
)
+
(
j
&
8
)
*
4
+
(
j
&
48
)
/
2
];
s
->
dv_zigzag
[
1
][
i
]
=
s
->
idsp
.
idct_permutation
[(
j
&
7
)
+
(
j
&
8
)
*
4
+
(
j
&
48
)
/
2
];
}
}
else
memcpy
(
s
->
dv_zigzag
[
1
],
ff_dv_zigzag248_direct
,
sizeof
(
s
->
dv_zigzag
[
1
]));
s
->
idct_put
[
0
]
=
idsp
.
idct_put
;
s
->
idct_put
[
0
]
=
s
->
idsp
.
idct_put
;
s
->
idct_put
[
1
]
=
ff_simple_idct248_put
;
return
ff_dvvideo_init
(
avctx
);
...
...
@@ -272,6 +269,49 @@ static inline void bit_copy(PutBitContext *pb, GetBitContext *gb)
put_bits
(
pb
,
bits_left
,
get_bits
(
gb
,
bits_left
));
}
static
av_always_inline
void
put_block_8x4
(
int16_t
*
block
,
uint8_t
*
restrict
p
,
int
stride
)
{
int
i
,
j
;
const
uint8_t
*
cm
=
ff_crop_tab
+
MAX_NEG_CROP
;
for
(
i
=
0
;
i
<
4
;
i
++
)
{
for
(
j
=
0
;
j
<
8
;
j
++
)
p
[
j
]
=
cm
[
block
[
j
]];
block
+=
8
;
p
+=
stride
;
}
}
static
void
dv100_idct_put_last_row_field_chroma
(
DVVideoContext
*
s
,
uint8_t
*
data
,
int
stride
,
int16_t
*
blocks
)
{
s
->
idsp
.
idct
(
blocks
+
0
*
64
);
s
->
idsp
.
idct
(
blocks
+
1
*
64
);
put_block_8x4
(
blocks
+
0
*
64
,
data
,
stride
<<
1
);
put_block_8x4
(
blocks
+
0
*
64
+
4
*
8
,
data
+
8
,
stride
<<
1
);
put_block_8x4
(
blocks
+
1
*
64
,
data
+
stride
,
stride
<<
1
);
put_block_8x4
(
blocks
+
1
*
64
+
4
*
8
,
data
+
8
+
stride
,
stride
<<
1
);
}
static
void
dv100_idct_put_last_row_field_luma
(
DVVideoContext
*
s
,
uint8_t
*
data
,
int
stride
,
int16_t
*
blocks
)
{
s
->
idsp
.
idct
(
blocks
+
0
*
64
);
s
->
idsp
.
idct
(
blocks
+
1
*
64
);
s
->
idsp
.
idct
(
blocks
+
2
*
64
);
s
->
idsp
.
idct
(
blocks
+
3
*
64
);
put_block_8x4
(
blocks
+
0
*
64
,
data
,
stride
<<
1
);
put_block_8x4
(
blocks
+
0
*
64
+
4
*
8
,
data
+
16
,
stride
<<
1
);
put_block_8x4
(
blocks
+
1
*
64
,
data
+
8
,
stride
<<
1
);
put_block_8x4
(
blocks
+
1
*
64
+
4
*
8
,
data
+
24
,
stride
<<
1
);
put_block_8x4
(
blocks
+
2
*
64
,
data
+
stride
,
stride
<<
1
);
put_block_8x4
(
blocks
+
2
*
64
+
4
*
8
,
data
+
16
+
stride
,
stride
<<
1
);
put_block_8x4
(
blocks
+
3
*
64
,
data
+
8
+
stride
,
stride
<<
1
);
put_block_8x4
(
blocks
+
3
*
64
+
4
*
8
,
data
+
24
+
stride
,
stride
<<
1
);
}
/* mb_x and mb_y are in units of 8 pixels */
static
int
dv_decode_video_segment
(
AVCodecContext
*
avctx
,
void
*
arg
)
{
...
...
@@ -443,14 +483,18 @@ retry:
}
y_ptr
=
s
->
frame
->
data
[
0
]
+
((
mb_y
*
s
->
frame
->
linesize
[
0
]
+
mb_x
)
<<
log2_blocksize
);
linesize
=
s
->
frame
->
linesize
[
0
]
<<
is_field_mode
[
mb_index
];
mb
[
0
].
idct_put
(
y_ptr
,
linesize
,
block
+
0
*
64
);
if
(
s
->
sys
->
video_stype
==
4
)
{
/* SD 422 */
mb
[
2
].
idct_put
(
y_ptr
+
(
1
<<
log2_blocksize
),
linesize
,
block
+
2
*
64
);
if
(
mb_y
==
134
&&
is_field_mode
[
mb_index
])
{
dv100_idct_put_last_row_field_luma
(
s
,
y_ptr
,
s
->
frame
->
linesize
[
0
],
block
);
}
else
{
mb
[
1
].
idct_put
(
y_ptr
+
(
1
<<
log2_blocksize
),
linesize
,
block
+
1
*
64
);
mb
[
2
].
idct_put
(
y_ptr
+
y_stride
,
linesize
,
block
+
2
*
64
);
mb
[
3
].
idct_put
(
y_ptr
+
(
1
<<
log2_blocksize
)
+
y_stride
,
linesize
,
block
+
3
*
64
);
linesize
=
s
->
frame
->
linesize
[
0
]
<<
is_field_mode
[
mb_index
];
mb
[
0
].
idct_put
(
y_ptr
,
linesize
,
block
+
0
*
64
);
if
(
s
->
sys
->
video_stype
==
4
)
{
/* SD 422 */
mb
[
2
].
idct_put
(
y_ptr
+
(
1
<<
log2_blocksize
),
linesize
,
block
+
2
*
64
);
}
else
{
mb
[
1
].
idct_put
(
y_ptr
+
(
1
<<
log2_blocksize
),
linesize
,
block
+
1
*
64
);
mb
[
2
].
idct_put
(
y_ptr
+
y_stride
,
linesize
,
block
+
2
*
64
);
mb
[
3
].
idct_put
(
y_ptr
+
(
1
<<
log2_blocksize
)
+
y_stride
,
linesize
,
block
+
3
*
64
);
}
}
mb
+=
4
;
block
+=
4
*
64
;
...
...
@@ -478,13 +522,19 @@ retry:
mb
++
;
}
else
{
y_stride
=
(
mb_y
==
134
)
?
(
1
<<
log2_blocksize
)
:
s
->
frame
->
linesize
[
j
]
<<
((
!
is_field_mode
[
mb_index
])
*
log2_blocksize
);
linesize
=
s
->
frame
->
linesize
[
j
]
<<
is_field_mode
[
mb_index
];
(
mb
++
)
->
idct_put
(
c_ptr
,
linesize
,
block
);
block
+=
64
;
if
(
s
->
sys
->
bpm
==
8
)
{
(
mb
++
)
->
idct_put
(
c_ptr
+
y_stride
,
linesize
,
block
);
s
->
frame
->
linesize
[
j
]
<<
((
!
is_field_mode
[
mb_index
])
*
log2_blocksize
);
if
(
mb_y
==
134
&&
is_field_mode
[
mb_index
])
{
dv100_idct_put_last_row_field_chroma
(
s
,
c_ptr
,
s
->
frame
->
linesize
[
j
],
block
);
mb
+=
2
;
block
+=
2
*
64
;
}
else
{
linesize
=
s
->
frame
->
linesize
[
j
]
<<
is_field_mode
[
mb_index
];
(
mb
++
)
->
idct_put
(
c_ptr
,
linesize
,
block
);
block
+=
64
;
if
(
s
->
sys
->
bpm
==
8
)
{
(
mb
++
)
->
idct_put
(
c_ptr
+
y_stride
,
linesize
,
block
);
block
+=
64
;
}
}
}
}
...
...
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