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
99ee8ee0
Commit
99ee8ee0
authored
Nov 15, 2016
by
Hendrik Leppkes
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
dxva2_vc1: support multiple slices
parent
36e27c87
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
72 additions
and
34 deletions
+72
-34
dxva2_vc1.c
libavcodec/dxva2_vc1.c
+72
-34
No files found.
libavcodec/dxva2_vc1.c
View file @
99ee8ee0
...
...
@@ -29,9 +29,11 @@
// potentially newer version.
#include "dxva2_internal.h"
#define MAX_SLICES 1024
struct
dxva2_picture_context
{
DXVA_PictureParameters
pp
;
DXVA_SliceInfo
si
;
unsigned
slice_count
;
DXVA_SliceInfo
slice
[
MAX_SLICES
];
const
uint8_t
*
bitstream
;
unsigned
bitstream_size
;
...
...
@@ -174,7 +176,8 @@ static void fill_slice(AVCodecContext *avctx, DXVA_SliceInfo *slice,
slice
->
bStartCodeBitOffset
=
0
;
slice
->
bReservedBits
=
(
s
->
pict_type
==
AV_PICTURE_TYPE_B
&&
!
v
->
bi_type
)
?
v
->
bfraction_lut_index
+
9
:
0
;
slice
->
wMBbitOffset
=
v
->
p_frame_skipped
?
0xffff
:
get_bits_count
(
&
s
->
gb
)
+
(
avctx
->
codec_id
==
AV_CODEC_ID_VC1
?
32
:
0
);
slice
->
wNumberMBsInSlice
=
s
->
mb_width
*
s
->
mb_height
;
/* XXX We assume 1 slice */
/* XXX We store the index of the first MB and it will be fixed later */
slice
->
wNumberMBsInSlice
=
(
s
->
mb_y
>>
v
->
field_mode
)
*
s
->
mb_width
+
s
->
mb_x
;
slice
->
wQuantizerScaleCode
=
v
->
pq
;
slice
->
wBadSliceChopping
=
0
;
}
...
...
@@ -188,18 +191,15 @@ static int commit_bitstream_and_slice_buffer(AVCodecContext *avctx,
const
MpegEncContext
*
s
=
&
v
->
s
;
struct
dxva2_picture_context
*
ctx_pic
=
s
->
current_picture_ptr
->
hwaccel_picture_private
;
DXVA_SliceInfo
*
slice
=
&
ctx_pic
->
si
;
static
const
uint8_t
start_code
[]
=
{
0
,
0
,
1
,
0x0d
};
const
unsigned
start_code_size
=
avctx
->
codec_id
==
AV_CODEC_ID_VC1
?
sizeof
(
start_code
)
:
0
;
const
unsigned
slice_size
=
slice
->
dwSliceBitsInBuffer
/
8
;
const
unsigned
padding
=
128
-
((
start_code_size
+
slice_size
)
&
127
);
const
unsigned
data_size
=
start_code_size
+
slice_size
+
padding
;
const
unsigned
mb_count
=
s
->
mb_width
*
(
s
->
mb_height
>>
v
->
field_mode
);
DXVA_SliceInfo
*
slice
=
NULL
;
void
*
dxva_data_ptr
;
uint8_t
*
dxva_data
;
uint8_t
*
dxva_data
,
*
current
,
*
end
;
unsigned
dxva_size
;
int
result
;
unsigned
padding
;
unsigned
i
;
unsigned
type
;
#if CONFIG_D3D11VA
...
...
@@ -223,19 +223,49 @@ static int commit_bitstream_and_slice_buffer(AVCodecContext *avctx,
#endif
dxva_data
=
dxva_data_ptr
;
result
=
data_size
<=
dxva_size
?
0
:
-
1
;
if
(
!
result
)
{
if
(
start_code_size
>
0
)
{
memcpy
(
dxva_data
,
start_code
,
start_code_size
);
if
(
v
->
second_field
)
dxva_data
[
3
]
=
0x0c
;
current
=
dxva_data
;
end
=
dxva_data
+
dxva_size
;
for
(
i
=
0
;
i
<
ctx_pic
->
slice_count
;
i
++
)
{
unsigned
position
,
size
;
slice
=
&
ctx_pic
->
slice
[
i
];
position
=
slice
->
dwSliceDataLocation
;
size
=
slice
->
dwSliceBitsInBuffer
/
8
;
if
(
start_code_size
+
size
>
end
-
current
)
{
av_log
(
avctx
,
AV_LOG_ERROR
,
"Failed to build bitstream"
);
break
;
}
memcpy
(
dxva_data
+
start_code_size
,
ctx_pic
->
bitstream
+
slice
->
dwSliceDataLocation
,
slice_size
);
if
(
padding
>
0
)
memset
(
dxva_data
+
start_code_size
+
slice_size
,
0
,
padding
);
slice
->
dwSliceBitsInBuffer
=
8
*
data_size
;
slice
->
dwSliceDataLocation
=
current
-
dxva_data
;
if
(
i
<
ctx_pic
->
slice_count
-
1
)
slice
->
wNumberMBsInSlice
=
slice
[
1
].
wNumberMBsInSlice
-
slice
[
0
].
wNumberMBsInSlice
;
else
slice
->
wNumberMBsInSlice
=
mb_count
-
slice
[
0
].
wNumberMBsInSlice
;
/* write the appropriate frame, field or slice start code */
if
(
start_code_size
)
{
memcpy
(
current
,
start_code
,
start_code_size
);
if
(
i
==
0
&&
v
->
second_field
)
current
[
3
]
=
0x0c
;
else
if
(
i
>
0
)
current
[
3
]
=
0x0b
;
current
+=
start_code_size
;
slice
->
dwSliceBitsInBuffer
+=
start_code_size
*
8
;
}
memcpy
(
current
,
&
ctx_pic
->
bitstream
[
position
],
size
);
current
+=
size
;
}
padding
=
FFMIN
(
128
-
((
current
-
dxva_data
)
&
127
),
end
-
current
);
if
(
slice
&&
padding
>
0
)
{
memset
(
current
,
0
,
padding
);
current
+=
padding
;
slice
->
dwSliceBitsInBuffer
+=
padding
*
8
;
}
#if CONFIG_D3D11VA
if
(
avctx
->
pix_fmt
==
AV_PIX_FMT_D3D11VA_VLD
)
if
(
FAILED
(
ID3D11VideoContext_ReleaseDecoderBuffer
(
D3D11VA_CONTEXT
(
ctx
)
->
video_context
,
D3D11VA_CONTEXT
(
ctx
)
->
decoder
,
type
)))
...
...
@@ -246,16 +276,16 @@ static int commit_bitstream_and_slice_buffer(AVCodecContext *avctx,
if
(
FAILED
(
IDirectXVideoDecoder_ReleaseBuffer
(
DXVA2_CONTEXT
(
ctx
)
->
decoder
,
type
)))
return
-
1
;
#endif
if
(
resul
t
)
return
result
;
if
(
i
<
ctx_pic
->
slice_coun
t
)
return
-
1
;
#if CONFIG_D3D11VA
if
(
avctx
->
pix_fmt
==
AV_PIX_FMT_D3D11VA_VLD
)
{
D3D11_VIDEO_DECODER_BUFFER_DESC
*
dsc11
=
bs
;
memset
(
dsc11
,
0
,
sizeof
(
*
dsc11
));
dsc11
->
BufferType
=
type
;
dsc11
->
DataSize
=
data_size
;
dsc11
->
NumMBsInBuffer
=
s
->
mb_width
*
s
->
mb_heigh
t
;
dsc11
->
DataSize
=
current
-
dxva_data
;
dsc11
->
NumMBsInBuffer
=
mb_coun
t
;
type
=
D3D11_VIDEO_DECODER_BUFFER_SLICE_CONTROL
;
}
...
...
@@ -265,17 +295,18 @@ static int commit_bitstream_and_slice_buffer(AVCodecContext *avctx,
DXVA2_DecodeBufferDesc
*
dsc2
=
bs
;
memset
(
dsc2
,
0
,
sizeof
(
*
dsc2
));
dsc2
->
CompressedBufferType
=
type
;
dsc2
->
DataSize
=
data_size
;
dsc2
->
NumMBsInBuffer
=
s
->
mb_width
*
s
->
mb_heigh
t
;
dsc2
->
DataSize
=
current
-
dxva_data
;
dsc2
->
NumMBsInBuffer
=
mb_coun
t
;
type
=
DXVA2_SliceControlBufferType
;
}
#endif
assert
((
data_size
&
127
)
==
0
);
return
ff_dxva2_commit_buffer
(
avctx
,
ctx
,
sc
,
type
,
slice
,
sizeof
(
*
slice
),
s
->
mb_width
*
s
->
mb_height
);
ctx_pic
->
slice
,
ctx_pic
->
slice_count
*
sizeof
(
*
ctx_pic
->
slice
),
mb_count
);
}
static
int
dxva2_vc1_start_frame
(
AVCodecContext
*
avctx
,
...
...
@@ -294,6 +325,7 @@ static int dxva2_vc1_start_frame(AVCodecContext *avctx,
fill_picture_parameters
(
avctx
,
ctx
,
v
,
&
ctx_pic
->
pp
);
ctx_pic
->
slice_count
=
0
;
ctx_pic
->
bitstream_size
=
0
;
ctx_pic
->
bitstream
=
NULL
;
return
0
;
...
...
@@ -306,9 +338,13 @@ static int dxva2_vc1_decode_slice(AVCodecContext *avctx,
const
VC1Context
*
v
=
avctx
->
priv_data
;
const
Picture
*
current_picture
=
v
->
s
.
current_picture_ptr
;
struct
dxva2_picture_context
*
ctx_pic
=
current_picture
->
hwaccel_picture_private
;
unsigned
position
;
if
(
ctx_pic
->
bitstream_size
>
0
)
if
(
ctx_pic
->
slice_count
>=
MAX_SLICES
)
{
avpriv_request_sample
(
avctx
,
"%d slices in dxva2"
,
ctx_pic
->
slice_count
);
return
-
1
;
}
if
(
avctx
->
codec_id
==
AV_CODEC_ID_VC1
&&
size
>=
4
&&
IS_MARKER
(
AV_RB32
(
buffer
)))
{
...
...
@@ -316,10 +352,12 @@ static int dxva2_vc1_decode_slice(AVCodecContext *avctx,
size
-=
4
;
}
ctx_pic
->
bitstream_size
=
size
;
ctx_pic
->
bitstream
=
buffer
;
if
(
!
ctx_pic
->
bitstream
)
ctx_pic
->
bitstream
=
buffer
;
ctx_pic
->
bitstream_size
+=
size
;
fill_slice
(
avctx
,
&
ctx_pic
->
si
,
0
,
size
);
position
=
buffer
-
ctx_pic
->
bitstream
;
fill_slice
(
avctx
,
&
ctx_pic
->
slice
[
ctx_pic
->
slice_count
++
],
position
,
size
);
return
0
;
}
...
...
@@ -329,7 +367,7 @@ static int dxva2_vc1_end_frame(AVCodecContext *avctx)
struct
dxva2_picture_context
*
ctx_pic
=
v
->
s
.
current_picture_ptr
->
hwaccel_picture_private
;
int
ret
;
if
(
ctx_pic
->
bitstream_size
<=
0
)
if
(
ctx_pic
->
slice_count
<=
0
||
ctx_pic
->
bitstream_size
<=
0
)
return
-
1
;
ret
=
ff_dxva2_common_end_frame
(
avctx
,
v
->
s
.
current_picture_ptr
->
f
,
...
...
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