mpeg2enc: Keep the packed data consistent with each parameters
[profile/ivi/libva.git] / test / encode / mpeg2enc.c
index 5a29786..73f66be 100644 (file)
@@ -274,13 +274,6 @@ sps_rbsp(const VAEncSequenceParameterBufferMPEG2 *seq_param,
     bitstream_put_ui(bs, seq_param->sequence_extension.bits.frame_rate_extension_d, 5);
 
     bitstream_byte_aligning(bs, 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);
 }
 
 static void 
@@ -291,6 +284,15 @@ 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
@@ -816,27 +818,82 @@ mpeg2enc_init(struct mpeg2enc_context *ctx)
                                               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,
@@ -906,6 +963,9 @@ begin_picture(struct mpeg2enc_context *ctx,
     ctx->current_input_surface = ctx->current_upload_surface;
     ctx->current_upload_surface = tmp;
 
+    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);
@@ -1166,7 +1226,7 @@ encode_picture(struct mpeg2enc_context *ctx,
         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);