exit(1); \
}
-#define INTRA_PERIOD 30
-
static int const picture_type_patter[][2] = {{VAEncPictureTypeIntra, 1},
{VAEncPictureTypePredictive, 3}, {VAEncPictureTypePredictive, 3},{VAEncPictureTypePredictive, 3},
{VAEncPictureTypePredictive, 3}, {VAEncPictureTypePredictive, 3},{VAEncPictureTypePredictive, 3},
/* args */
int rate_control_mode;
int fps;
+ int mode; /* 0:I, 1:I/P, 2:I/P/B */
int width;
int height;
int frame_size;
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_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.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_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
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
bitstream_put_ui(bs, 0, 1); /* extra_bit_picture, 0 */
+ bitstream_byte_aligning(bs, 0);
+
bitstream_put_ui(bs, START_CODE_EXT, 32);
bitstream_put_ui(bs, 8, 4); /* Picture Coding Extension ID: 8 */
bitstream_put_ui(bs, pic_param->f_code[0][0], 4);
bitstream_put_ui(bs, pic_param->picture_coding_extension.bits.progressive_frame, 1);
bitstream_put_ui(bs, pic_param->picture_coding_extension.bits.composite_display_flag, 1);
+ bitstream_byte_aligning(bs, 0);
+
if (pic_param->user_data_length) {
bitstream_put_ui(bs, START_CODE_USER, 32);
for (i = 0; i < pic_param->user_data_length; i++) {
bitstream_put_ui(bs, pic_param->user_data[i], 8);
}
+
+ bitstream_byte_aligning(bs, 0);
}
}
fprintf(stderr, "where options include:\n");
fprintf(stderr, "\t--cqp <QP> const qp mode with specified <QP>\n");
fprintf(stderr, "\t--fps <FPS> specify the frame rate\n");
+ fprintf(stderr, "\t--mode <MODE> specify the mode 0 (I), 1 (I/P) and 2 (I/P/B)\n");
}
static void
{"help", no_argument, 0, 'h'},
{"cqp", required_argument, 0, 'c'},
{"fps", required_argument, 0, 'f'},
+ {"mode", required_argument, 0, 'm'},
{ NULL, 0, NULL, 0 }
};
ctx->fps = 30;
ctx->qp = 28;
ctx->rate_control_mode = VA_RC_CQP;
+ ctx->mode = 1;
optind = 5;
break;
+ case 'm':
+ tmp = atoi(optarg);
+
+ if (tmp < 0 || tmp > 2)
+ fprintf(stderr, "Waning: MODE must be 0, 1, or 2\n");
+ else
+ ctx->mode = tmp;
+
+ break;
+
case '?':
fprintf(stderr, "Error: unkown command options\n");
seq_param->frame_rate = ctx->fps;
seq_param->aspect_ratio_information = 1;
- seq_param->vbv_buffer_size = 0x10000;
+ seq_param->vbv_buffer_size = 3; /* B = 16 * 1024 * vbv_buffer_size */
seq_param->sequence_extension.bits.profile_and_level_indication = 4 << 4 | 0x8; /* FIXME: Main/Main ??? */
seq_param->sequence_extension.bits.progressive_sequence = 1; /* progressive frame-pictures */
pic_param->picture_type = VAEncPictureTypeIntra;
pic_param->temporal_reference = 0;
- pic_param->f_code[0][0] = 1;
- pic_param->f_code[0][1] = 1;
- pic_param->f_code[1][0] = 1;
- pic_param->f_code[1][1] = 1;
+ pic_param->f_code[0][0] = 0xf;
+ pic_param->f_code[0][1] = 0xf;
+ pic_param->f_code[1][0] = 0xf;
+ pic_param->f_code[1][1] = 0xf;
pic_param->picture_coding_extension.bits.intra_dc_precision = 0; /* 8bits */
pic_param->picture_coding_extension.bits.picture_structure = 3; /* frame picture */
- pic_param->picture_coding_extension.bits.top_field_first = 1;
+ pic_param->picture_coding_extension.bits.top_field_first = 0;
pic_param->picture_coding_extension.bits.frame_pred_frame_dct = 1; /* FIXME */
pic_param->picture_coding_extension.bits.concealment_motion_vectors = 0;
pic_param->picture_coding_extension.bits.q_scale_type = 0;
ctx->codedbuf_buf_id = VA_INVALID_ID;
ctx->codedbuf_i_size = ctx->frame_size;
ctx->codedbuf_pb_size = 0;
- ctx->intra_period = INTRA_PERIOD;
+
+ if (ctx->mode == 0)
+ ctx->intra_period = 1;
+ else
+ ctx->intra_period = 16;
+
ctx->bit_rate = -1;
for (i = 0; i < MAX_SLICES; i++) {
ctx);
}
+static int
+mpeg2enc_time_code(VAEncSequenceParameterBufferMPEG2 *seq_param,
+ int num_frames)
+{
+ int fps = (int)(seq_param->frame_rate + 0.5);
+ int time_code = 0;
+ int time_code_pictures, time_code_seconds, time_code_minutes, time_code_hours;
+ int drop_frame_flag = 0;
+
+ assert(fps <= 60);
+
+ time_code_seconds = num_frames / fps;
+ time_code_pictures = num_frames % fps;
+ time_code |= time_code_pictures;
+
+ time_code_minutes = time_code_minutes / 60;
+ time_code_seconds = time_code_minutes % 60;
+ time_code |= (time_code_seconds << 6);
+
+ time_code_hours = time_code_minutes / 60;
+ time_code_minutes = time_code_minutes % 60;
+
+ time_code |= (1 << 12); /* marker_bit */
+ time_code |= (time_code_minutes << 13);
+
+ time_code_hours = time_code_hours % 24;
+ time_code |= (time_code_hours << 19);
+
+ time_code |= (drop_frame_flag << 24);
+
+ return time_code;
+}
+
/*
* run
*/
-static void
+static void
+mpeg2enc_update_sequence_parameter(struct mpeg2enc_context *ctx,
+ VAEncPictureType picture_type,
+ int coded_order,
+ int display_order)
+{
+ VAEncSequenceParameterBufferMPEG2 *seq_param = &ctx->seq_param;
+
+ /* update the GOP info for the new GOP */
+ if (display_order % ctx->intra_period == 0) {
+ seq_param->gop_header.bits.time_code = mpeg2enc_time_code(seq_param, display_order);
+ }
+}
+
+static void
mpeg2enc_update_picture_parameter(struct mpeg2enc_context *ctx,
- VAEncPictureType picture_type,
- int coded_order,
- int display_order)
+ VAEncPictureType picture_type,
+ int coded_order,
+ int display_order)
{
- VAEncPictureParameterBufferMPEG2 *pic_param;
- VAStatus va_status;
+ VAEncPictureParameterBufferMPEG2 *pic_param = &ctx->pic_param;
- // Picture level
- pic_param = &ctx->pic_param;
pic_param->picture_type = picture_type;
- pic_param->temporal_reference = display_order;
+ pic_param->temporal_reference = display_order % ctx->intra_period;
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];
- pic_param->coded_buf = ctx->codedbuf_buf_id;
+}
+
+static void
+mpeg2enc_update_picture_parameter_buffer(struct mpeg2enc_context *ctx,
+ VAEncPictureType picture_type,
+ int coded_order,
+ int display_order)
+{
+ VAEncPictureParameterBufferMPEG2 *pic_param = &ctx->pic_param;
+ VAStatus va_status;
+ /* update the coded buffer id */
+ pic_param->coded_buf = ctx->codedbuf_buf_id;
va_status = vaCreateBuffer(ctx->va_dpy,
ctx->context_id,
VAEncPictureParameterBufferType,
{
VAStatus va_status;
int tmp;
+ VAEncPackedHeaderParameterBuffer packed_header_param_buffer;
+ unsigned int length_in_bits;
+ unsigned char *packed_seq_buffer = NULL, *packed_pic_buffer = NULL;
if (ctx->upload_thread_value != 0) {
fprintf(stderr, "FATAL error!!!\n");
ctx->current_input_surface = ctx->current_upload_surface;
ctx->current_upload_surface = tmp;
- if (coded_order == 0) {
- VAEncPackedHeaderParameterBuffer packed_header_param_buffer;
- unsigned int length_in_bits;
- unsigned char *packed_seq_buffer = NULL, *packed_pic_buffer = NULL;
+ 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) {
assert(picture_type == VAEncPictureTypeIntra);
length_in_bits = build_packed_seq_buffer(&ctx->seq_param, &packed_seq_buffer);
packed_header_param_buffer.type = VAEncPackedHeaderMPEG2_SPS;
&ctx->packed_seq_buf_id);
CHECK_VASTATUS(va_status,"vaCreateBuffer");
- length_in_bits = build_packed_pic_buffer(&ctx->seq_param, &ctx->pic_param, &packed_pic_buffer);
- packed_header_param_buffer.type = VAEncPackedHeaderMPEG2_PPS;
- packed_header_param_buffer.has_emulation_bytes = 0;
- packed_header_param_buffer.bit_length = length_in_bits;
+ free(packed_seq_buffer);
+ }
- va_status = vaCreateBuffer(ctx->va_dpy,
- ctx->context_id,
- VAEncPackedHeaderParameterBufferType,
- sizeof(packed_header_param_buffer), 1, &packed_header_param_buffer,
- &ctx->packed_pic_header_param_buf_id);
- CHECK_VASTATUS(va_status,"vaCreateBuffer");
+ length_in_bits = build_packed_pic_buffer(&ctx->seq_param, &ctx->pic_param, &packed_pic_buffer);
+ packed_header_param_buffer.type = VAEncPackedHeaderMPEG2_PPS;
+ packed_header_param_buffer.has_emulation_bytes = 0;
+ packed_header_param_buffer.bit_length = length_in_bits;
- va_status = vaCreateBuffer(ctx->va_dpy,
- ctx->context_id,
- VAEncPackedHeaderDataBufferType,
- (length_in_bits + 7) / 8, 1, packed_pic_buffer,
- &ctx->packed_pic_buf_id);
- CHECK_VASTATUS(va_status,"vaCreateBuffer");
+ va_status = vaCreateBuffer(ctx->va_dpy,
+ ctx->context_id,
+ VAEncPackedHeaderParameterBufferType,
+ sizeof(packed_header_param_buffer), 1, &packed_header_param_buffer,
+ &ctx->packed_pic_header_param_buf_id);
+ CHECK_VASTATUS(va_status,"vaCreateBuffer");
- free(packed_seq_buffer);
- free(packed_pic_buffer);
- }
+ va_status = vaCreateBuffer(ctx->va_dpy,
+ ctx->context_id,
+ VAEncPackedHeaderDataBufferType,
+ (length_in_bits + 7) / 8, 1, packed_pic_buffer,
+ &ctx->packed_pic_buf_id);
+ CHECK_VASTATUS(va_status,"vaCreateBuffer");
+
+ free(packed_pic_buffer);
/* sequence parameter set */
VAEncSequenceParameterBufferMPEG2 *seq_param = &ctx->seq_param;
CHECK_VASTATUS(va_status,"vaCreateBuffer");
/* picture parameter set */
- mpeg2enc_update_picture_parameter(ctx, picture_type, coded_order, display_order);
+ mpeg2enc_update_picture_parameter_buffer(ctx, picture_type, coded_order, display_order);
mpeg2enc_render_picture(ctx);
mpeg2enc_run(struct mpeg2enc_context *ctx)
{
int display_order = 0, coded_order = 0;
- int i_frame_only = 1, i_p_frame_only = 1;
for (display_order = 0; display_order < ctx->num_pictures;) {
- if (i_frame_only) {
+ if (ctx->mode == 0) {
encode_picture(ctx,
coded_order,
display_order,
display_order + 1);
display_order++;
coded_order++;
- } else if (i_p_frame_only) {
+ } else if (ctx->mode == 1) {
+ assert(0);
if ((display_order % ctx->intra_period) == 0) {
encode_picture(ctx,
coded_order,
} else { // follow the i,p,b pattern
static int fcurrent = 0;
int fnext;
+
+ assert(0);
fcurrent = fcurrent % (sizeof(picture_type_patter)/sizeof(int[2]));
fnext = (fcurrent+1) % (sizeof(picture_type_patter)/sizeof(int[2]));