summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXiang, Haihao <haihao.xiang@intel.com>2012-12-06 15:56:12 +0800
committerXiang, Haihao <haihao.xiang@intel.com>2012-12-07 16:05:35 +0800
commit5eabdd00fbfaa35926cd1da14fcc2ef6c03337c9 (patch)
tree2396d346c075c3aad66405c267e6a2b9e252a2de
parentac3c93a1fef43a829177894c4920d3c3a828d048 (diff)
downloadlibva-5eabdd00fbfaa35926cd1da14fcc2ef6c03337c9.tar.gz
mpeg2enc: temporal_referenc and GOP header follow MPEG-2 Spec.
temporal_reference is reset to zero at each group of pictures header Signed-off-by: Xiang, Haihao <haihao.xiang@intel.com>
-rw-r--r--test/encode/mpeg2enc.c110
1 files changed, 67 insertions, 43 deletions
diff --git a/test/encode/mpeg2enc.c b/test/encode/mpeg2enc.c
index 091732e..aba7317 100644
--- a/test/encode/mpeg2enc.c
+++ b/test/encode/mpeg2enc.c
@@ -100,6 +100,9 @@ struct mpeg2enc_context {
VAEncPictureType next_type;
int next_display_order;
int next_bframes;
+ int new_sequence;
+ int new_gop_header;
+ int gop_header_in_display_order;
/* VA resource */
VADisplay va_dpy;
@@ -257,40 +260,52 @@ find_frame_rate_code(const VAEncSequenceParameterBufferMPEG2 *seq_param)
}
static void
-sps_rbsp(const VAEncSequenceParameterBufferMPEG2 *seq_param,
+sps_rbsp(struct mpeg2enc_context *ctx,
+ const VAEncSequenceParameterBufferMPEG2 *seq_param,
bitstream *bs)
{
int frame_rate_code = find_frame_rate_code(seq_param);
- bitstream_put_ui(bs, START_CODE_SEQ, 32);
- bitstream_put_ui(bs, seq_param->picture_width, 12);
- bitstream_put_ui(bs, seq_param->picture_height, 12);
- bitstream_put_ui(bs, seq_param->aspect_ratio_information, 4);
- bitstream_put_ui(bs, frame_rate_code, 4); /* frame_rate_code */
- bitstream_put_ui(bs, (seq_param->bits_per_second + 399) / 400, 18); /* the low 18 bits of bit_rate */
- bitstream_put_ui(bs, 1, 1); /* marker_bit */
- bitstream_put_ui(bs, seq_param->vbv_buffer_size, 10);
- bitstream_put_ui(bs, 0, 1); /* constraint_parameter_flag, always 0 for MPEG-2 */
- bitstream_put_ui(bs, 0, 1); /* load_intra_quantiser_matrix */
- bitstream_put_ui(bs, 0, 1); /* load_non_intra_quantiser_matrix */
+ if (ctx->new_sequence) {
+ bitstream_put_ui(bs, START_CODE_SEQ, 32);
+ bitstream_put_ui(bs, seq_param->picture_width, 12);
+ bitstream_put_ui(bs, seq_param->picture_height, 12);
+ bitstream_put_ui(bs, seq_param->aspect_ratio_information, 4);
+ bitstream_put_ui(bs, frame_rate_code, 4); /* frame_rate_code */
+ bitstream_put_ui(bs, (seq_param->bits_per_second + 399) / 400, 18); /* the low 18 bits of bit_rate */
+ bitstream_put_ui(bs, 1, 1); /* marker_bit */
+ bitstream_put_ui(bs, seq_param->vbv_buffer_size, 10);
+ bitstream_put_ui(bs, 0, 1); /* constraint_parameter_flag, always 0 for MPEG-2 */
+ bitstream_put_ui(bs, 0, 1); /* load_intra_quantiser_matrix */
+ bitstream_put_ui(bs, 0, 1); /* load_non_intra_quantiser_matrix */
- bitstream_byte_aligning(bs, 0);
+ bitstream_byte_aligning(bs, 0);
- bitstream_put_ui(bs, START_CODE_EXT, 32);
- bitstream_put_ui(bs, 1, 4); /* sequence_extension id */
- bitstream_put_ui(bs, seq_param->sequence_extension.bits.profile_and_level_indication, 8);
- bitstream_put_ui(bs, seq_param->sequence_extension.bits.progressive_sequence, 1);
- bitstream_put_ui(bs, seq_param->sequence_extension.bits.chroma_format, 2);
- bitstream_put_ui(bs, seq_param->picture_width >> 12, 2);
- bitstream_put_ui(bs, seq_param->picture_height >> 12, 2);
- bitstream_put_ui(bs, ((seq_param->bits_per_second + 399) / 400) >> 18, 12); /* bit_rate_extension */
- bitstream_put_ui(bs, 1, 1); /* marker_bit */
- bitstream_put_ui(bs, seq_param->vbv_buffer_size >> 10, 8);
- bitstream_put_ui(bs, seq_param->sequence_extension.bits.low_delay, 1);
- bitstream_put_ui(bs, seq_param->sequence_extension.bits.frame_rate_extension_n, 2);
- bitstream_put_ui(bs, seq_param->sequence_extension.bits.frame_rate_extension_d, 5);
+ bitstream_put_ui(bs, START_CODE_EXT, 32);
+ bitstream_put_ui(bs, 1, 4); /* sequence_extension id */
+ bitstream_put_ui(bs, seq_param->sequence_extension.bits.profile_and_level_indication, 8);
+ bitstream_put_ui(bs, seq_param->sequence_extension.bits.progressive_sequence, 1);
+ bitstream_put_ui(bs, seq_param->sequence_extension.bits.chroma_format, 2);
+ bitstream_put_ui(bs, seq_param->picture_width >> 12, 2);
+ bitstream_put_ui(bs, seq_param->picture_height >> 12, 2);
+ bitstream_put_ui(bs, ((seq_param->bits_per_second + 399) / 400) >> 18, 12); /* bit_rate_extension */
+ bitstream_put_ui(bs, 1, 1); /* marker_bit */
+ bitstream_put_ui(bs, seq_param->vbv_buffer_size >> 10, 8);
+ bitstream_put_ui(bs, seq_param->sequence_extension.bits.low_delay, 1);
+ bitstream_put_ui(bs, seq_param->sequence_extension.bits.frame_rate_extension_n, 2);
+ bitstream_put_ui(bs, seq_param->sequence_extension.bits.frame_rate_extension_d, 5);
- bitstream_byte_aligning(bs, 0);
+ bitstream_byte_aligning(bs, 0);
+ }
+
+ if (ctx->new_gop_header) {
+ bitstream_put_ui(bs, START_CODE_GOP, 32);
+ bitstream_put_ui(bs, seq_param->gop_header.bits.time_code, 25);
+ bitstream_put_ui(bs, seq_param->gop_header.bits.closed_gop, 1);
+ bitstream_put_ui(bs, seq_param->gop_header.bits.broken_link, 1);
+
+ bitstream_byte_aligning(bs, 0);
+ }
}
static void
@@ -301,15 +316,6 @@ pps_rbsp(const VAEncSequenceParameterBufferMPEG2 *seq_param,
int i;
int chroma_420_type;
- if (pic_param->temporal_reference == 0) {
- bitstream_put_ui(bs, START_CODE_GOP, 32);
- bitstream_put_ui(bs, seq_param->gop_header.bits.time_code, 25);
- bitstream_put_ui(bs, seq_param->gop_header.bits.closed_gop, 1);
- bitstream_put_ui(bs, seq_param->gop_header.bits.broken_link, 1);
-
- bitstream_byte_aligning(bs, 0);
- }
-
if (seq_param->sequence_extension.bits.chroma_format == CHROMA_FORMAT_420)
chroma_420_type = pic_param->picture_coding_extension.bits.progressive_frame;
else
@@ -386,13 +392,14 @@ build_packed_pic_buffer(const VAEncSequenceParameterBufferMPEG2 *seq_param,
}
static int
-build_packed_seq_buffer(const VAEncSequenceParameterBufferMPEG2 *seq_param,
+build_packed_seq_buffer(struct mpeg2enc_context *ctx,
+ const VAEncSequenceParameterBufferMPEG2 *seq_param,
unsigned char **header_buffer)
{
bitstream bs;
bitstream_start(&bs);
- sps_rbsp(seq_param, &bs);
+ sps_rbsp(ctx, seq_param, &bs);
bitstream_end(&bs);
*header_buffer = (unsigned char *)bs.buffer;
@@ -886,6 +893,10 @@ mpeg2enc_init(struct mpeg2enc_context *ctx)
ctx->next_bframes = ctx->ip_period;
+ ctx->new_sequence = 1;
+ ctx->new_gop_header = 1;
+ ctx->gop_header_in_display_order = 0;
+
ctx->bit_rate = -1;
for (i = 0; i < MAX_SLICES; i++) {
@@ -949,8 +960,8 @@ mpeg2enc_update_sequence_parameter(struct mpeg2enc_context *ctx,
{
VAEncSequenceParameterBufferMPEG2 *seq_param = &ctx->seq_param;
- /* update the GOP info for the new GOP */
- if (display_order % ctx->intra_period == 0) {
+ /* update the time_code info for the new GOP */
+ if (ctx->new_gop_header) {
seq_param->gop_header.bits.time_code = mpeg2enc_time_code(seq_param, display_order);
}
}
@@ -964,7 +975,7 @@ mpeg2enc_update_picture_parameter(struct mpeg2enc_context *ctx,
VAEncPictureParameterBufferMPEG2 *pic_param = &ctx->pic_param;
pic_param->picture_type = picture_type;
- pic_param->temporal_reference = display_order % ctx->intra_period;
+ pic_param->temporal_reference = (display_order - ctx->gop_header_in_display_order) & 0x3FF;
pic_param->reconstructed_picture = surface_ids[SID_RECON_PICTURE];
pic_param->forward_reference_picture = surface_ids[SID_REFERENCE_PICTURE_L0];
pic_param->backward_reference_picture = surface_ids[SID_REFERENCE_PICTURE_L1];
@@ -1079,9 +1090,9 @@ begin_picture(struct mpeg2enc_context *ctx,
mpeg2enc_update_sequence_parameter(ctx, picture_type, coded_order, display_order);
mpeg2enc_update_picture_parameter(ctx, picture_type, coded_order, display_order);
- if (coded_order == 0) {
+ if (ctx->new_sequence || ctx->new_gop_header) {
assert(picture_type == VAEncPictureTypeIntra);
- length_in_bits = build_packed_seq_buffer(&ctx->seq_param, &packed_seq_buffer);
+ length_in_bits = build_packed_seq_buffer(ctx, &ctx->seq_param, &packed_seq_buffer);
packed_header_param_buffer.type = VAEncPackedHeaderMPEG2_SPS;
packed_header_param_buffer.has_emulation_bytes = 0;
packed_header_param_buffer.bit_length = length_in_bits;
@@ -1395,12 +1406,17 @@ update_next_frame_info(struct mpeg2enc_context *ctx,
ctx->next_bframes -= rtmp;
}
}
+
static void
mpeg2enc_run(struct mpeg2enc_context *ctx)
{
int display_order = 0, coded_order = 0;
VAEncPictureType type;
+ ctx->new_sequence = 1;
+ ctx->new_gop_header = 1;
+ ctx->gop_header_in_display_order = display_order;
+
while (coded_order < ctx->num_pictures) {
type = ctx->next_type;
display_order = ctx->next_display_order;
@@ -1412,6 +1428,14 @@ mpeg2enc_run(struct mpeg2enc_context *ctx)
type,
ctx->next_type == VAEncPictureTypeBidirectional,
ctx->next_display_order);
+
+ /* update gop_header */
+ ctx->new_sequence = 0;
+ ctx->new_gop_header = ctx->next_type == VAEncPictureTypeIntra;
+
+ if (ctx->new_gop_header)
+ ctx->gop_header_in_display_order += ctx->intra_period;
+
coded_order++;
fprintf(stderr, "\r %d/%d ...", coded_order, ctx->num_pictures);