Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
F
ffmpeg
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
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
submodule
ffmpeg
Commits
d8928ad6
Commit
d8928ad6
authored
Jun 23, 2017
by
Mark Thompson
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
vaapi_mpeg2: Convert to use coded bitstream infrastructure
(cherry picked from commit
10eb496d
)
parent
038a5125
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
424 additions
and
216 deletions
+424
-216
configure
configure
+1
-1
vaapi_encode_mpeg2.c
libavcodec/vaapi_encode_mpeg2.c
+423
-215
No files found.
configure
View file @
d8928ad6
...
...
@@ -2864,7 +2864,7 @@ mpeg2_qsv_decoder_select="qsvdec mpeg2_qsv_hwaccel"
mpeg2_qsv_encoder_deps
=
"libmfx"
mpeg2_qsv_encoder_select
=
"qsvenc"
mpeg2_vaapi_encoder_deps
=
"VAEncPictureParameterBufferMPEG2"
mpeg2_vaapi_encoder_select
=
"vaapi_encode"
mpeg2_vaapi_encoder_select
=
"
cbs_mpeg2
vaapi_encode"
mpeg2_v4l2m2m_decoder_deps
=
"v4l2_m2m mpeg2_v4l2_m2m"
mpeg4_crystalhd_decoder_select
=
"crystalhd"
mpeg4_cuvid_decoder_deps
=
"cuda cuvid"
...
...
libavcodec/vaapi_encode_mpeg2.c
View file @
d8928ad6
...
...
@@ -20,15 +20,11 @@
#include <va/va_enc_mpeg2.h>
#include "libavutil/avassert.h"
#include "libavutil/common.h"
#include "libavutil/internal.h"
#include "libavutil/opt.h"
#include "libavutil/pixfmt.h"
#include "avcodec.h"
#include "
internal
.h"
#include "
mpegvideo
.h"
#include "
put_bits
.h"
#include "
cbs
.h"
#include "
cbs_mpeg2
.h"
#include "
mpeg12
.h"
#include "vaapi_encode.h"
typedef
struct
VAAPIEncodeMPEG2Context
{
...
...
@@ -39,79 +35,104 @@ typedef struct VAAPIEncodeMPEG2Context {
int
quant_p
;
int
quant_b
;
MPEG2RawSequenceHeader
sequence_header
;
MPEG2RawExtensionData
sequence_extension
;
MPEG2RawExtensionData
sequence_display_extension
;
MPEG2RawGroupOfPicturesHeader
gop_header
;
MPEG2RawPictureHeader
picture_header
;
MPEG2RawExtensionData
picture_coding_extension
;
int64_t
last_i_frame
;
unsigned
int
bit_rate
;
unsigned
int
vbv_buffer_size
;
AVRational
frame_rate
;
unsigned
int
f_code_horizontal
;
unsigned
int
f_code_vertical
;
CodedBitstreamContext
*
cbc
;
CodedBitstreamFragment
current_fragment
;
}
VAAPIEncodeMPEG2Context
;
#define vseq_var(name) vseq->name, name
#define vseqext_field(name) vseq->sequence_extension.bits.name, name
#define vgop_field(name) vseq->gop_header.bits.name, name
#define vpic_var(name) vpic->name, name
#define vpcext_field(name) vpic->picture_coding_extension.bits.name, name
#define vcomp_field(name) vpic->composite_display.bits.name, name
static
int
vaapi_encode_mpeg2_write_fragment
(
AVCodecContext
*
avctx
,
char
*
data
,
size_t
*
data_len
,
CodedBitstreamFragment
*
frag
)
{
VAAPIEncodeContext
*
ctx
=
avctx
->
priv_data
;
VAAPIEncodeMPEG2Context
*
priv
=
ctx
->
priv_data
;
int
err
;
err
=
ff_cbs_write_fragment_data
(
priv
->
cbc
,
frag
);
if
(
err
<
0
)
{
av_log
(
avctx
,
AV_LOG_ERROR
,
"Failed to write packed header.
\n
"
);
return
err
;
}
if
(
*
data_len
<
8
*
frag
->
data_size
-
frag
->
data_bit_padding
)
{
av_log
(
avctx
,
AV_LOG_ERROR
,
"Access unit too large: "
"%zu < %zu.
\n
"
,
*
data_len
,
8
*
frag
->
data_size
-
frag
->
data_bit_padding
);
return
AVERROR
(
ENOSPC
);
}
memcpy
(
data
,
frag
->
data
,
frag
->
data_size
);
*
data_len
=
8
*
frag
->
data_size
-
frag
->
data_bit_padding
;
return
0
;
}
static
int
vaapi_encode_mpeg2_add_header
(
AVCodecContext
*
avctx
,
CodedBitstreamFragment
*
frag
,
int
type
,
void
*
header
)
{
VAAPIEncodeContext
*
ctx
=
avctx
->
priv_data
;
VAAPIEncodeMPEG2Context
*
priv
=
ctx
->
priv_data
;
int
err
;
err
=
ff_cbs_insert_unit_content
(
priv
->
cbc
,
frag
,
-
1
,
type
,
header
);
if
(
err
<
0
)
{
av_log
(
avctx
,
AV_LOG_ERROR
,
"Failed to add header: "
"type = %d.
\n
"
,
type
);
return
err
;
}
#define u2(width, value, name) put_bits(&pbc, width, value)
#define u(width, ...) u2(width, __VA_ARGS__)
return
0
;
}
static
int
vaapi_encode_mpeg2_write_sequence_header
(
AVCodecContext
*
avctx
,
char
*
data
,
size_t
*
data_len
)
{
VAAPIEncodeContext
*
ctx
=
avctx
->
priv_data
;
VAEncSequenceParameterBufferMPEG2
*
vseq
=
ctx
->
codec_sequence_params
;
VAAPIEncodeMPEG2Context
*
priv
=
ctx
->
priv_data
;
PutBitContext
pbc
;
init_put_bits
(
&
pbc
,
data
,
8
*
*
data_len
);
u
(
32
,
SEQ_START_CODE
,
sequence_header_code
);
u
(
12
,
vseq
->
picture_width
,
horizontal_size_value
);
u
(
12
,
vseq
->
picture_height
,
vertical_size_value
);
u
(
4
,
vseq_var
(
aspect_ratio_information
));
u
(
4
,
8
,
frame_rate_code
);
u
(
18
,
priv
->
bit_rate
&
0x3fff
,
bit_rate_value
);
u
(
1
,
1
,
marker_bit
);
u
(
10
,
priv
->
vbv_buffer_size
&
0x3ff
,
vbv_buffer_size_value
);
u
(
1
,
0
,
constrained_parameters_flag
);
u
(
1
,
0
,
load_intra_quantiser_matrix
);
// intra_quantiser_matrix[64]
u
(
1
,
0
,
load_non_intra_quantiser_matrix
);
// non_intra_quantiser_matrix[64]
while
(
put_bits_count
(
&
pbc
)
%
8
)
u
(
1
,
0
,
zero_bit
);
u
(
32
,
EXT_START_CODE
,
extension_start_code
);
u
(
4
,
1
,
extension_start_code_identifier
);
u
(
8
,
vseqext_field
(
profile_and_level_indication
));
u
(
1
,
vseqext_field
(
progressive_sequence
));
u
(
2
,
vseqext_field
(
chroma_format
));
u
(
2
,
0
,
horizontal_size_extension
);
u
(
2
,
0
,
vertical_size_extension
);
u
(
12
,
priv
->
bit_rate
>>
18
,
bit_rate_extension
);
u
(
1
,
1
,
marker_bit
);
u
(
8
,
priv
->
vbv_buffer_size
>>
10
,
vbv_buffer_size_extension
);
u
(
1
,
vseqext_field
(
low_delay
));
u
(
2
,
vseqext_field
(
frame_rate_extension_n
));
u
(
2
,
vseqext_field
(
frame_rate_extension_d
));
while
(
put_bits_count
(
&
pbc
)
%
8
)
u
(
1
,
0
,
zero_bit
);
u
(
32
,
GOP_START_CODE
,
group_start_code
);
u
(
25
,
vgop_field
(
time_code
));
u
(
1
,
vgop_field
(
closed_gop
));
u
(
1
,
vgop_field
(
broken_link
));
while
(
put_bits_count
(
&
pbc
)
%
8
)
u
(
1
,
0
,
zero_bit
);
*
data_len
=
put_bits_count
(
&
pbc
);
flush_put_bits
(
&
pbc
);
VAAPIEncodeContext
*
ctx
=
avctx
->
priv_data
;
VAAPIEncodeMPEG2Context
*
priv
=
ctx
->
priv_data
;
CodedBitstreamFragment
*
frag
=
&
priv
->
current_fragment
;
int
err
;
err
=
vaapi_encode_mpeg2_add_header
(
avctx
,
frag
,
MPEG2_START_SEQUENCE_HEADER
,
&
priv
->
sequence_header
);
if
(
err
<
0
)
goto
fail
;
err
=
vaapi_encode_mpeg2_add_header
(
avctx
,
frag
,
MPEG2_START_EXTENSION
,
&
priv
->
sequence_extension
);
if
(
err
<
0
)
goto
fail
;
err
=
vaapi_encode_mpeg2_add_header
(
avctx
,
frag
,
MPEG2_START_EXTENSION
,
&
priv
->
sequence_display_extension
);
if
(
err
<
0
)
goto
fail
;
err
=
vaapi_encode_mpeg2_add_header
(
avctx
,
frag
,
MPEG2_START_GROUP
,
&
priv
->
gop_header
);
if
(
err
<
0
)
goto
fail
;
err
=
vaapi_encode_mpeg2_write_fragment
(
avctx
,
data
,
data_len
,
frag
);
fail:
ff_cbs_fragment_uninit
(
priv
->
cbc
,
frag
);
return
0
;
}
...
...
@@ -119,139 +140,275 @@ static int vaapi_encode_mpeg2_write_picture_header(AVCodecContext *avctx,
VAAPIEncodePicture
*
pic
,
char
*
data
,
size_t
*
data_len
)
{
VAEncPictureParameterBufferMPEG2
*
vpic
=
pic
->
codec_picture_params
;
int
picture_coding_type
;
PutBitContext
pbc
;
VAAPIEncodeContext
*
ctx
=
avctx
->
priv_data
;
VAAPIEncodeMPEG2Context
*
priv
=
ctx
->
priv_data
;
CodedBitstreamFragment
*
frag
=
&
priv
->
current_fragment
;
int
err
;
err
=
vaapi_encode_mpeg2_add_header
(
avctx
,
frag
,
MPEG2_START_PICTURE
,
&
priv
->
picture_header
);
if
(
err
<
0
)
goto
fail
;
err
=
vaapi_encode_mpeg2_add_header
(
avctx
,
frag
,
MPEG2_START_EXTENSION
,
&
priv
->
picture_coding_extension
);
if
(
err
<
0
)
goto
fail
;
err
=
vaapi_encode_mpeg2_write_fragment
(
avctx
,
data
,
data_len
,
frag
);
fail:
ff_cbs_fragment_uninit
(
priv
->
cbc
,
frag
);
return
0
;
}
init_put_bits
(
&
pbc
,
data
,
8
*
*
data_len
);
static
int
vaapi_encode_mpeg2_init_sequence_params
(
AVCodecContext
*
avctx
)
{
VAAPIEncodeContext
*
ctx
=
avctx
->
priv_data
;
VAAPIEncodeMPEG2Context
*
priv
=
ctx
->
priv_data
;
MPEG2RawSequenceHeader
*
sh
=
&
priv
->
sequence_header
;
MPEG2RawSequenceExtension
*
se
=
&
priv
->
sequence_extension
.
data
.
sequence
;
MPEG2RawSequenceDisplayExtension
*
sde
=
&
priv
->
sequence_display_extension
.
data
.
sequence_display
;
MPEG2RawGroupOfPicturesHeader
*
goph
=
&
priv
->
gop_header
;
MPEG2RawPictureHeader
*
ph
=
&
priv
->
picture_header
;
MPEG2RawPictureCodingExtension
*
pce
=
&
priv
->
picture_coding_extension
.
data
.
picture_coding
;
VAEncSequenceParameterBufferMPEG2
*
vseq
=
ctx
->
codec_sequence_params
;
VAEncPictureParameterBufferMPEG2
*
vpic
=
ctx
->
codec_picture_params
;
int
code
,
ext_n
,
ext_d
;
u
(
32
,
PICTURE_START_CODE
,
picture_start_code
);
u
(
10
,
vpic_var
(
temporal_reference
));
memset
(
sh
,
0
,
sizeof
(
*
sh
));
memset
(
se
,
0
,
sizeof
(
*
se
));
memset
(
sde
,
0
,
sizeof
(
*
sde
));
memset
(
goph
,
0
,
sizeof
(
*
goph
));
memset
(
ph
,
0
,
sizeof
(
*
ph
));
memset
(
pce
,
0
,
sizeof
(
*
pce
));
switch
(
vpic
->
picture_type
)
{
case
VAEncPictureTypeIntra
:
picture_coding_type
=
AV_PICTURE_TYPE_I
;
break
;
case
VAEncPictureTypePredictive
:
picture_coding_type
=
AV_PICTURE_TYPE_P
;
if
(
avctx
->
bit_rate
>
0
)
{
priv
->
bit_rate
=
(
avctx
->
bit_rate
+
399
)
/
400
;
}
else
{
// Unknown (not a bitrate-targetting mode), so just use the
// highest value.
priv
->
bit_rate
=
0x3fffffff
;
}
if
(
avctx
->
rc_buffer_size
>
0
)
{
priv
->
vbv_buffer_size
=
(
avctx
->
rc_buffer_size
+
(
1
<<
14
)
-
1
)
>>
14
;
}
else
{
// Unknown, so guess a value from the bitrate.
priv
->
vbv_buffer_size
=
priv
->
bit_rate
>>
14
;
}
switch
(
avctx
->
level
)
{
case
4
:
// High.
case
6
:
// High 1440.
priv
->
f_code_horizontal
=
9
;
priv
->
f_code_vertical
=
5
;
break
;
case
VAEncPictureTypeBidirectional
:
picture_coding_type
=
AV_PICTURE_TYPE_B
;
case
8
:
// Main.
priv
->
f_code_horizontal
=
8
;
priv
->
f_code_vertical
=
5
;
break
;
case
10
:
// Low.
default:
av_assert0
(
0
&&
"invalid picture_coding_type"
);
}
u
(
3
,
picture_coding_type
,
picture_coding_type
);
u
(
16
,
0xffff
,
vbv_delay
);
if
(
picture_coding_type
==
2
||
picture_coding_type
==
3
)
{
u
(
1
,
0
,
full_pel_forward_vector
);
u
(
3
,
7
,
forward_f_code
);
}
if
(
picture_coding_type
==
3
)
{
u
(
1
,
0
,
full_pel_backward_vector
);
u
(
3
,
7
,
backward_f_code
);
priv
->
f_code_horizontal
=
7
;
priv
->
f_code_vertical
=
4
;
break
;
}
u
(
1
,
0
,
extra_bit_picture
);
while
(
put_bits_count
(
&
pbc
)
%
8
)
u
(
1
,
0
,
zero_bit
);
u
(
32
,
EXT_START_CODE
,
extension_start_code
);
u
(
4
,
8
,
extension_start_code_identifier
);
u
(
4
,
vpic_var
(
f_code
[
0
][
0
]));
u
(
4
,
vpic_var
(
f_code
[
0
][
1
]));
u
(
4
,
vpic_var
(
f_code
[
1
][
0
]));
u
(
4
,
vpic_var
(
f_code
[
1
][
1
]));
u
(
2
,
vpcext_field
(
intra_dc_precision
));
u
(
2
,
vpcext_field
(
picture_structure
));
u
(
1
,
vpcext_field
(
top_field_first
));
u
(
1
,
vpcext_field
(
frame_pred_frame_dct
));
u
(
1
,
vpcext_field
(
concealment_motion_vectors
));
u
(
1
,
vpcext_field
(
q_scale_type
));
u
(
1
,
vpcext_field
(
intra_vlc_format
));
u
(
1
,
vpcext_field
(
alternate_scan
));
u
(
1
,
vpcext_field
(
repeat_first_field
));
u
(
1
,
1
,
chroma_420_type
);
u
(
1
,
vpcext_field
(
progressive_frame
));
u
(
1
,
vpcext_field
(
composite_display_flag
));
if
(
vpic
->
picture_coding_extension
.
bits
.
composite_display_flag
)
{
u
(
1
,
vcomp_field
(
v_axis
));
u
(
3
,
vcomp_field
(
field_sequence
));
u
(
1
,
vcomp_field
(
sub_carrier
));
u
(
7
,
vcomp_field
(
burst_amplitude
));
u
(
8
,
vcomp_field
(
sub_carrier_phase
));
// Sequence header
sh
->
sequence_header_code
=
MPEG2_START_SEQUENCE_HEADER
;
sh
->
horizontal_size_value
=
avctx
->
width
&
0xfff
;
sh
->
vertical_size_value
=
avctx
->
height
&
0xfff
;
if
(
avctx
->
sample_aspect_ratio
.
num
!=
0
&&
avctx
->
sample_aspect_ratio
.
den
!=
0
)
{
AVRational
dar
=
av_div_q
(
avctx
->
sample_aspect_ratio
,
(
AVRational
)
{
avctx
->
width
,
avctx
->
height
});
if
(
av_cmp_q
(
avctx
->
sample_aspect_ratio
,
(
AVRational
)
{
1
,
1
})
==
0
)
{
sh
->
aspect_ratio_information
=
1
;
}
else
if
(
av_cmp_q
(
dar
,
(
AVRational
)
{
3
,
4
})
==
0
)
{
sh
->
aspect_ratio_information
=
2
;
}
else
if
(
av_cmp_q
(
dar
,
(
AVRational
)
{
9
,
16
})
==
0
)
{
sh
->
aspect_ratio_information
=
3
;
}
else
if
(
av_cmp_q
(
dar
,
(
AVRational
)
{
100
,
221
})
==
0
)
{
sh
->
aspect_ratio_information
=
4
;
}
else
{
av_log
(
avctx
,
AV_LOG_WARNING
,
"Sample aspect ratio %d:%d is not "
"representable, signalling square pixels instead.
\n
"
,
avctx
->
sample_aspect_ratio
.
num
,
avctx
->
sample_aspect_ratio
.
den
);
sh
->
aspect_ratio_information
=
1
;
}
}
else
{
// Unknown - assume square pixels.
sh
->
aspect_ratio_information
=
1
;
}
while
(
put_bits_count
(
&
pbc
)
%
8
)
u
(
1
,
0
,
zero_bit
);
if
(
avctx
->
framerate
.
num
>
0
&&
avctx
->
framerate
.
den
>
0
)
priv
->
frame_rate
=
avctx
->
framerate
;
else
priv
->
frame_rate
=
av_inv_q
(
avctx
->
time_base
);
ff_mpeg12_find_best_frame_rate
(
priv
->
frame_rate
,
&
code
,
&
ext_n
,
&
ext_d
,
0
);
sh
->
frame_rate_code
=
code
;
*
data_len
=
put_bits_count
(
&
pbc
)
;
flush_put_bits
(
&
pbc
)
;
sh
->
bit_rate_value
=
priv
->
bit_rate
&
0x3ffff
;
sh
->
vbv_buffer_size_value
=
priv
->
vbv_buffer_size
&
0x3ff
;
return
0
;
}
sh
->
constrained_parameters_flag
=
0
;
sh
->
load_intra_quantiser_matrix
=
0
;
sh
->
load_non_intra_quantiser_matrix
=
0
;
static
int
vaapi_encode_mpeg2_init_sequence_params
(
AVCodecContext
*
avctx
)
{
VAAPIEncodeContext
*
ctx
=
avctx
->
priv_data
;
VAEncSequenceParameterBufferMPEG2
*
vseq
=
ctx
->
codec_sequence_params
;
VAEncPictureParameterBufferMPEG2
*
vpic
=
ctx
->
codec_picture_params
;
VAAPIEncodeMPEG2Context
*
priv
=
ctx
->
priv_data
;
vseq
->
intra_period
=
avctx
->
gop_size
;
vseq
->
ip_period
=
ctx
->
b_per_p
+
1
;
// Sequence extension
vseq
->
picture_width
=
avctx
->
width
;
vseq
->
picture_height
=
avctx
->
height
;
priv
->
sequence_extension
.
extension_start_code
=
MPEG2_START_EXTENSION
;
priv
->
sequence_extension
.
extension_start_code_identifier
=
MPEG2_EXTENSION_SEQUENCE
;
vseq
->
bits_per_second
=
avctx
->
bit_rate
;
if
(
avctx
->
framerate
.
num
>
0
&&
avctx
->
framerate
.
den
>
0
)
vseq
->
frame_rate
=
(
float
)
avctx
->
framerate
.
num
/
avctx
->
framerate
.
den
;
else
vseq
->
frame_rate
=
(
float
)
avctx
->
time_base
.
den
/
avctx
->
time_base
.
num
;
vseq
->
aspect_ratio_information
=
1
;
vseq
->
vbv_buffer_size
=
avctx
->
rc_buffer_size
/
(
16
*
1024
);
vseq
->
sequence_extension
.
bits
.
profile_and_level_indication
=
avctx
->
profile
<<
4
|
avctx
->
level
;
vseq
->
sequence_extension
.
bits
.
progressive_sequence
=
1
;
vseq
->
sequence_extension
.
bits
.
chroma_format
=
1
;
vseq
->
sequence_extension
.
bits
.
low_delay
=
0
;
vseq
->
sequence_extension
.
bits
.
frame_rate_extension_n
=
0
;
vseq
->
sequence_extension
.
bits
.
frame_rate_extension_d
=
0
;
vseq
->
new_gop_header
=
0
;
vseq
->
gop_header
.
bits
.
time_code
=
0
;
vseq
->
gop_header
.
bits
.
closed_gop
=
1
;
vseq
->
gop_header
.
bits
.
broken_link
=
0
;
vpic
->
forward_reference_picture
=
VA_INVALID_ID
;
vpic
->
backward_reference_picture
=
VA_INVALID_ID
;
vpic
->
reconstructed_picture
=
VA_INVALID_ID
;
vpic
->
coded_buf
=
VA_INVALID_ID
;
vpic
->
temporal_reference
=
0
;
vpic
->
f_code
[
0
][
0
]
=
15
;
vpic
->
f_code
[
0
][
1
]
=
15
;
vpic
->
f_code
[
1
][
0
]
=
15
;
vpic
->
f_code
[
1
][
1
]
=
15
;
vpic
->
picture_coding_extension
.
bits
.
intra_dc_precision
=
0
;
vpic
->
picture_coding_extension
.
bits
.
picture_structure
=
3
;
vpic
->
picture_coding_extension
.
bits
.
top_field_first
=
0
;
vpic
->
picture_coding_extension
.
bits
.
frame_pred_frame_dct
=
1
;
vpic
->
picture_coding_extension
.
bits
.
concealment_motion_vectors
=
0
;
vpic
->
picture_coding_extension
.
bits
.
q_scale_type
=
0
;
vpic
->
picture_coding_extension
.
bits
.
intra_vlc_format
=
0
;
vpic
->
picture_coding_extension
.
bits
.
alternate_scan
=
0
;
vpic
->
picture_coding_extension
.
bits
.
repeat_first_field
=
0
;
vpic
->
picture_coding_extension
.
bits
.
progressive_frame
=
1
;
vpic
->
picture_coding_extension
.
bits
.
composite_display_flag
=
0
;
priv
->
bit_rate
=
(
avctx
->
bit_rate
+
399
)
/
400
;
priv
->
vbv_buffer_size
=
avctx
->
rc_buffer_size
/
(
16
*
1024
);
se
->
profile_and_level_indication
=
avctx
->
profile
<<
4
|
avctx
->
level
;
se
->
progressive_sequence
=
1
;
se
->
chroma_format
=
1
;
se
->
horizontal_size_extension
=
avctx
->
width
>>
12
;
se
->
vertical_size_extension
=
avctx
->
height
>>
12
;
se
->
bit_rate_extension
=
priv
->
bit_rate
>>
18
;
se
->
vbv_buffer_size_extension
=
priv
->
vbv_buffer_size
>>
10
;
se
->
low_delay
=
ctx
->
b_per_p
==
0
;
se
->
frame_rate_extension_n
=
ext_n
;
se
->
frame_rate_extension_d
=
ext_d
;
// Sequence display extension
priv
->
sequence_display_extension
.
extension_start_code
=
MPEG2_START_EXTENSION
;
priv
->
sequence_display_extension
.
extension_start_code_identifier
=
MPEG2_EXTENSION_SEQUENCE_DISPLAY
;
sde
->
video_format
=
5
;
if
(
avctx
->
color_primaries
!=
AVCOL_PRI_UNSPECIFIED
||
avctx
->
color_trc
!=
AVCOL_TRC_UNSPECIFIED
||
avctx
->
colorspace
!=
AVCOL_SPC_UNSPECIFIED
)
{
sde
->
colour_description
=
1
;
sde
->
colour_primaries
=
avctx
->
color_primaries
;
sde
->
transfer_characteristics
=
avctx
->
color_trc
;
sde
->
matrix_coefficients
=
avctx
->
colorspace
;
}
else
{
sde
->
colour_description
=
0
;
}
sde
->
display_horizontal_size
=
avctx
->
width
;
sde
->
display_vertical_size
=
avctx
->
height
;
// GOP header
goph
->
group_start_code
=
MPEG2_START_GROUP
;
goph
->
time_code
=
0
;
goph
->
closed_gop
=
1
;
goph
->
broken_link
=
0
;
// Defaults for picture header
ph
->
picture_start_code
=
MPEG2_START_PICTURE
;
ph
->
vbv_delay
=
0xffff
;
// Not currently calculated.
ph
->
full_pel_forward_vector
=
0
;
ph
->
forward_f_code
=
7
;
ph
->
full_pel_backward_vector
=
0
;
ph
->
forward_f_code
=
7
;
// Defaults for picture coding extension
priv
->
picture_coding_extension
.
extension_start_code
=
MPEG2_START_EXTENSION
;
priv
->
picture_coding_extension
.
extension_start_code_identifier
=
MPEG2_EXTENSION_PICTURE_CODING
;
pce
->
intra_dc_precision
=
0
;
pce
->
picture_structure
=
3
;
pce
->
top_field_first
=
0
;
pce
->
frame_pred_frame_dct
=
1
;
pce
->
concealment_motion_vectors
=
0
;
pce
->
q_scale_type
=
0
;
pce
->
intra_vlc_format
=
0
;
pce
->
alternate_scan
=
0
;
pce
->
repeat_first_field
=
0
;
pce
->
progressive_frame
=
1
;
pce
->
composite_display_flag
=
0
;
*
vseq
=
(
VAEncSequenceParameterBufferMPEG2
)
{
.
intra_period
=
avctx
->
gop_size
,
.
ip_period
=
ctx
->
b_per_p
+
1
,
.
picture_width
=
avctx
->
width
,
.
picture_height
=
avctx
->
height
,
.
bits_per_second
=
avctx
->
bit_rate
,
.
frame_rate
=
av_q2d
(
priv
->
frame_rate
),
.
aspect_ratio_information
=
sh
->
aspect_ratio_information
,
.
vbv_buffer_size
=
priv
->
vbv_buffer_size
,
.
sequence_extension
.
bits
=
{
.
profile_and_level_indication
=
se
->
profile_and_level_indication
,
.
progressive_sequence
=
se
->
progressive_sequence
,
.
chroma_format
=
se
->
chroma_format
,
.
low_delay
=
se
->
low_delay
,
.
frame_rate_extension_n
=
se
->
frame_rate_extension_n
,
.
frame_rate_extension_d
=
se
->
frame_rate_extension_d
,
},
.
new_gop_header
=
1
,
.
gop_header
.
bits
=
{
.
time_code
=
goph
->
time_code
,
.
closed_gop
=
goph
->
closed_gop
,
.
broken_link
=
goph
->
broken_link
,
},
};
*
vpic
=
(
VAEncPictureParameterBufferMPEG2
)
{
.
forward_reference_picture
=
VA_INVALID_ID
,
.
backward_reference_picture
=
VA_INVALID_ID
,
.
reconstructed_picture
=
VA_INVALID_ID
,
.
coded_buf
=
VA_INVALID_ID
,
.
vbv_delay
=
0xffff
,
.
f_code
=
{
{
15
,
15
},
{
15
,
15
}
},
.
picture_coding_extension
.
bits
=
{
.
intra_dc_precision
=
pce
->
intra_dc_precision
,
.
picture_structure
=
pce
->
picture_structure
,
.
top_field_first
=
pce
->
top_field_first
,
.
frame_pred_frame_dct
=
pce
->
frame_pred_frame_dct
,
.
concealment_motion_vectors
=
pce
->
concealment_motion_vectors
,
.
q_scale_type
=
pce
->
q_scale_type
,
.
intra_vlc_format
=
pce
->
intra_vlc_format
,
.
alternate_scan
=
pce
->
alternate_scan
,
.
repeat_first_field
=
pce
->
repeat_first_field
,
.
progressive_frame
=
pce
->
progressive_frame
,
.
composite_display_flag
=
pce
->
composite_display_flag
,
},
.
composite_display
.
bits
=
{
.
v_axis
=
pce
->
v_axis
,
.
field_sequence
=
pce
->
field_sequence
,
.
sub_carrier
=
pce
->
sub_carrier
,
.
burst_amplitude
=
pce
->
burst_amplitude
,
.
sub_carrier_phase
=
pce
->
sub_carrier_phase
,
},
};
return
0
;
}
...
...
@@ -260,56 +417,61 @@ static int vaapi_encode_mpeg2_init_picture_params(AVCodecContext *avctx,
VAAPIEncodePicture
*
pic
)
{
VAAPIEncodeContext
*
ctx
=
avctx
->
priv_data
;
VAEncPictureParameterBufferMPEG2
*
vpic
=
pic
->
codec_picture_params
;
VAAPIEncodeMPEG2Context
*
priv
=
ctx
->
priv_data
;
int
fch
,
fcv
;
MPEG2RawPictureHeader
*
ph
=
&
priv
->
picture_header
;
MPEG2RawPictureCodingExtension
*
pce
=
&
priv
->
picture_coding_extension
.
data
.
picture_coding
;
VAEncPictureParameterBufferMPEG2
*
vpic
=
pic
->
codec_picture_params
;
switch
(
avctx
->
level
)
{
case
4
:
// High.
case
6
:
// High 1440.
fch
=
9
;
fcv
=
5
;
break
;
case
8
:
// Main.
fch
=
8
;
fcv
=
5
;
break
;
case
10
:
// Low.
default:
fch
=
7
;
fcv
=
4
;
break
;
if
(
pic
->
type
==
PICTURE_TYPE_IDR
||
pic
->
type
==
PICTURE_TYPE_I
)
{
ph
->
temporal_reference
=
0
;
ph
->
picture_coding_type
=
1
;
priv
->
last_i_frame
=
pic
->
display_order
;
}
else
{
ph
->
temporal_reference
=
pic
->
display_order
-
priv
->
last_i_frame
;
ph
->
picture_coding_type
=
pic
->
type
==
PICTURE_TYPE_B
?
3
:
2
;
}
if
(
pic
->
type
==
PICTURE_TYPE_P
||
pic
->
type
==
PICTURE_TYPE_B
)
{
pce
->
f_code
[
0
][
0
]
=
priv
->
f_code_horizontal
;
pce
->
f_code
[
0
][
1
]
=
priv
->
f_code_vertical
;
}
else
{
pce
->
f_code
[
0
][
0
]
=
15
;
pce
->
f_code
[
0
][
1
]
=
15
;
}
if
(
pic
->
type
==
PICTURE_TYPE_B
)
{
pce
->
f_code
[
1
][
0
]
=
priv
->
f_code_horizontal
;
pce
->
f_code
[
1
][
1
]
=
priv
->
f_code_vertical
;
}
else
{
pce
->
f_code
[
1
][
0
]
=
15
;
pce
->
f_code
[
1
][
1
]
=
15
;
}
vpic
->
reconstructed_picture
=
pic
->
recon_surface
;
vpic
->
coded_buf
=
pic
->
output_buffer
;
switch
(
pic
->
type
)
{
case
PICTURE_TYPE_IDR
:
case
PICTURE_TYPE_I
:
vpic
->
picture_type
=
VAEncPictureTypeIntra
;
priv
->
last_i_frame
=
pic
->
display_order
;
break
;
case
PICTURE_TYPE_P
:
vpic
->
picture_type
=
VAEncPictureTypePredictive
;
vpic
->
forward_reference_picture
=
pic
->
refs
[
0
]
->
recon_surface
;
vpic
->
f_code
[
0
][
0
]
=
fch
;
vpic
->
f_code
[
0
][
1
]
=
fcv
;
break
;
case
PICTURE_TYPE_B
:
vpic
->
picture_type
=
VAEncPictureTypeBidirectional
;
vpic
->
forward_reference_picture
=
pic
->
refs
[
0
]
->
recon_surface
;
vpic
->
backward_reference_picture
=
pic
->
refs
[
1
]
->
recon_surface
;
vpic
->
f_code
[
0
][
0
]
=
fch
;
vpic
->
f_code
[
0
][
1
]
=
fcv
;
vpic
->
f_code
[
1
][
0
]
=
fch
;
vpic
->
f_code
[
1
][
1
]
=
fcv
;
break
;
default:
av_assert0
(
0
&&
"invalid picture type"
);
}
vpic
->
reconstructed_picture
=
pic
->
recon_surface
;
vpic
->
coded_buf
=
pic
->
output_buffer
;
vpic
->
temporal_reference
=
pic
->
display_order
-
priv
->
last_i_frame
;
vpic
->
temporal_reference
=
ph
->
temporal_reference
;
vpic
->
f_code
[
0
][
0
]
=
pce
->
f_code
[
0
][
0
];
vpic
->
f_code
[
0
][
1
]
=
pce
->
f_code
[
0
][
1
];
vpic
->
f_code
[
1
][
0
]
=
pce
->
f_code
[
1
][
0
];
vpic
->
f_code
[
1
][
1
]
=
pce
->
f_code
[
1
][
1
];
pic
->
nb_slices
=
priv
->
mb_height
;
...
...
@@ -354,6 +516,11 @@ static av_cold int vaapi_encode_mpeg2_configure(AVCodecContext *avctx)
{
VAAPIEncodeContext
*
ctx
=
avctx
->
priv_data
;
VAAPIEncodeMPEG2Context
*
priv
=
ctx
->
priv_data
;
int
err
;
err
=
ff_cbs_init
(
&
priv
->
cbc
,
AV_CODEC_ID_MPEG2VIDEO
,
avctx
);
if
(
err
<
0
)
return
err
;
priv
->
mb_width
=
FFALIGN
(
avctx
->
width
,
16
)
/
16
;
priv
->
mb_height
=
FFALIGN
(
avctx
->
height
,
16
)
/
16
;
...
...
@@ -420,11 +587,41 @@ static av_cold int vaapi_encode_mpeg2_init(AVCodecContext *avctx)
case
FF_PROFILE_MPEG2_MAIN
:
ctx
->
va_profile
=
VAProfileMPEG2Main
;
break
;
case
FF_PROFILE_MPEG2_422
:
av_log
(
avctx
,
AV_LOG_ERROR
,
"MPEG-2 4:2:2 profile "
"is not supported.
\n
"
);
return
AVERROR_PATCHWELCOME
;
case
FF_PROFILE_MPEG2_HIGH
:
av_log
(
avctx
,
AV_LOG_ERROR
,
"MPEG-2 high profile "
"is not supported.
\n
"
);
return
AVERROR_PATCHWELCOME
;
case
FF_PROFILE_MPEG2_SS
:
case
FF_PROFILE_MPEG2_SNR_SCALABLE
:
av_log
(
avctx
,
AV_LOG_ERROR
,
"MPEG-2 scalable profiles "
"are not supported.
\n
"
);
return
AVERROR_PATCHWELCOME
;
default:
av_log
(
avctx
,
AV_LOG_ERROR
,
"Unknown MPEG-2 profile %d.
\n
"
,
avctx
->
profile
);
return
AVERROR
(
EINVAL
);
}
switch
(
avctx
->
level
)
{
case
4
:
// High
case
6
:
// High 1440
case
8
:
// Main
case
10
:
// Low
break
;
default:
av_log
(
avctx
,
AV_LOG_ERROR
,
"Unknown MPEG-2 level %d.
\n
"
,
avctx
->
level
);
return
AVERROR
(
EINVAL
);
}
if
(
avctx
->
height
%
4096
==
0
||
avctx
->
width
%
4096
==
0
)
{
av_log
(
avctx
,
AV_LOG_ERROR
,
"MPEG-2 does not support picture "
"height or width divisible by 4096.
\n
"
);
return
AVERROR
(
EINVAL
);
}
ctx
->
va_entrypoint
=
VAEntrypointEncSlice
;
ctx
->
va_rt_format
=
VA_RT_FORMAT_YUV420
;
...
...
@@ -439,6 +636,17 @@ static av_cold int vaapi_encode_mpeg2_init(AVCodecContext *avctx)
return
ff_vaapi_encode_init
(
avctx
);
}
static
av_cold
int
vaapi_encode_mpeg2_close
(
AVCodecContext
*
avctx
)
{
VAAPIEncodeContext
*
ctx
=
avctx
->
priv_data
;
VAAPIEncodeMPEG2Context
*
priv
=
ctx
->
priv_data
;
if
(
priv
)
ff_cbs_close
(
&
priv
->
cbc
);
return
ff_vaapi_encode_close
(
avctx
);
}
static
const
AVCodecDefault
vaapi_encode_mpeg2_defaults
[]
=
{
{
"profile"
,
"4"
},
{
"level"
,
"4"
},
...
...
@@ -460,7 +668,7 @@ AVCodec ff_mpeg2_vaapi_encoder = {
.
priv_data_size
=
sizeof
(
VAAPIEncodeContext
),
.
init
=
&
vaapi_encode_mpeg2_init
,
.
encode2
=
&
ff_vaapi_encode2
,
.
close
=
&
ff_vaapi_encode
_close
,
.
close
=
&
vaapi_encode_mpeg2
_close
,
.
capabilities
=
AV_CODEC_CAP_DELAY
,
.
defaults
=
vaapi_encode_mpeg2_defaults
,
.
pix_fmts
=
(
const
enum
AVPixelFormat
[])
{
...
...
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