[FFmpeg-cvslog] vaapi_h264: Add support for VUI parameters

Mark Thompson git at videolan.org
Wed Jun 29 12:05:07 CEST 2016


ffmpeg | branch: master | Mark Thompson <sw at jkqxz.net> | Tue May 17 15:14:57 2016 +0100| [081961f819c0b16c7a860d7da7d39f1fd91bd2f0] | committer: Mark Thompson

vaapi_h264: Add support for VUI parameters

Supports aspect ratio, colour format and timing information.

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=081961f819c0b16c7a860d7da7d39f1fd91bd2f0
---

 libavcodec/vaapi_encode_h264.c |  126 +++++++++++++++++++++++++++++++++++++++-
 1 file changed, 124 insertions(+), 2 deletions(-)

diff --git a/libavcodec/vaapi_encode_h264.c b/libavcodec/vaapi_encode_h264.c
index 2341b12..139e6e9 100644
--- a/libavcodec/vaapi_encode_h264.c
+++ b/libavcodec/vaapi_encode_h264.c
@@ -61,7 +61,29 @@ typedef struct VAAPIEncodeH264MiscSequenceParams {
 
     int pic_init_qs_minus26;
 
-    char vui_parameters_present_flag;
+    char overscan_info_present_flag;
+    char overscan_appropriate_flag;
+
+    char video_signal_type_present_flag;
+    unsigned int video_format;
+    char video_full_range_flag;
+    char colour_description_present_flag;
+    unsigned int colour_primaries;
+    unsigned int transfer_characteristics;
+    unsigned int matrix_coefficients;
+
+    char chroma_loc_info_present_flag;
+    unsigned int chroma_sample_loc_type_top_field;
+    unsigned int chroma_sample_loc_type_bottom_field;
+
+    // Some timing elements are in VAEncSequenceParameterBufferH264.
+    char fixed_frame_rate_flag;
+
+    char nal_hrd_parameters_present_flag;
+    char vcl_hrd_parameters_present_flag;
+    char low_delay_hrd_flag;
+    char pic_struct_present_flag;
+    char bitstream_restriction_flag;
 } VAAPIEncodeH264MiscSequenceParams;
 
 // This structure contains all possibly-useful per-slice syntax elements
@@ -132,6 +154,7 @@ typedef struct VAAPIEncodeH264Options {
 
 #define vseq_var(name)     vseq->name, name
 #define vseq_field(name)   vseq->seq_fields.bits.name, name
+#define vvui_field(name)   vseq->vui_fields.bits.name, name
 #define vpic_var(name)     vpic->name, name
 #define vpic_field(name)   vpic->pic_fields.bits.name, name
 #define vslice_var(name)   vslice->name, name
@@ -154,6 +177,71 @@ static void vaapi_encode_h264_write_trailing_rbsp(PutBitContext *pbc)
         u(1, 0, rbsp_alignment_zero_bit);
 }
 
+static void vaapi_encode_h264_write_vui(PutBitContext *pbc,
+                                        VAAPIEncodeContext *ctx)
+{
+    VAEncSequenceParameterBufferH264  *vseq = ctx->codec_sequence_params;
+    VAAPIEncodeH264Context            *priv = ctx->priv_data;
+    VAAPIEncodeH264MiscSequenceParams *mseq = &priv->misc_sequence_params;
+
+    u(1, vvui_field(aspect_ratio_info_present_flag));
+    if (vseq->vui_fields.bits.aspect_ratio_info_present_flag) {
+        u(8, vseq_var(aspect_ratio_idc));
+        if (vseq->aspect_ratio_idc == 255) {
+            u(16, vseq_var(sar_width));
+            u(16, vseq_var(sar_height));
+        }
+    }
+
+    u(1, mseq_var(overscan_info_present_flag));
+    if (mseq->overscan_info_present_flag)
+        u(1, mseq_var(overscan_appropriate_flag));
+
+    u(1, mseq_var(video_signal_type_present_flag));
+    if (mseq->video_signal_type_present_flag) {
+        u(3, mseq_var(video_format));
+        u(1, mseq_var(video_full_range_flag));
+        u(1, mseq_var(colour_description_present_flag));
+        if (mseq->colour_description_present_flag) {
+            u(8, mseq_var(colour_primaries));
+            u(8, mseq_var(transfer_characteristics));
+            u(8, mseq_var(matrix_coefficients));
+        }
+    }
+
+    u(1, mseq_var(chroma_loc_info_present_flag));
+    if (mseq->chroma_loc_info_present_flag) {
+        ue(mseq_var(chroma_sample_loc_type_top_field));
+        ue(mseq_var(chroma_sample_loc_type_bottom_field));
+    }
+
+    u(1, vvui_field(timing_info_present_flag));
+    if (vseq->vui_fields.bits.timing_info_present_flag) {
+        u(32, vseq_var(num_units_in_tick));
+        u(32, vseq_var(time_scale));
+        u(1, mseq_var(fixed_frame_rate_flag));
+    }
+
+    u(1, mseq_var(nal_hrd_parameters_present_flag));
+    if (mseq->nal_hrd_parameters_present_flag) {
+        av_assert0(0 && "nal hrd parameters not supported");
+    }
+    u(1, mseq_var(vcl_hrd_parameters_present_flag));
+    if (mseq->vcl_hrd_parameters_present_flag) {
+        av_assert0(0 && "vcl hrd parameters not supported");
+    }
+
+    if (mseq->nal_hrd_parameters_present_flag ||
+        mseq->vcl_hrd_parameters_present_flag)
+        u(1, mseq_var(low_delay_hrd_flag));
+    u(1, mseq_var(pic_struct_present_flag));
+
+    u(1, vvui_field(bitstream_restriction_flag));
+    if (vseq->vui_fields.bits.bitstream_restriction_flag) {
+        av_assert0(0 && "bitstream restrictions not supported");
+    }
+}
+
 static void vaapi_encode_h264_write_sps(PutBitContext *pbc,
                                         VAAPIEncodeContext *ctx)
 {
@@ -233,7 +321,9 @@ static void vaapi_encode_h264_write_sps(PutBitContext *pbc,
         ue(vseq_var(frame_crop_bottom_offset));
     }
 
-    u(1, mseq_var(vui_parameters_present_flag));
+    u(1, vseq_var(vui_parameters_present_flag));
+    if (vseq->vui_parameters_present_flag)
+        vaapi_encode_h264_write_vui(pbc, ctx);
 
     vaapi_encode_h264_write_trailing_rbsp(pbc);
 }
@@ -529,13 +619,45 @@ static int vaapi_encode_h264_init_sequence_params(AVCodecContext *avctx)
             vseq->frame_cropping_flag = 0;
         }
 
+        vseq->vui_parameters_present_flag = 1;
+        if (avctx->sample_aspect_ratio.num != 0) {
+            vseq->vui_fields.bits.aspect_ratio_info_present_flag = 1;
+            // There is a large enum of these which we could support
+            // individually rather than using the generic X/Y form?
+            if (avctx->sample_aspect_ratio.num ==
+                avctx->sample_aspect_ratio.den) {
+                vseq->aspect_ratio_idc = 1;
+            } else {
+                vseq->aspect_ratio_idc = 255; // Extended SAR.
+                vseq->sar_width  = avctx->sample_aspect_ratio.num;
+                vseq->sar_height = avctx->sample_aspect_ratio.den;
+            }
+        }
+        if (avctx->color_primaries != AVCOL_PRI_UNSPECIFIED ||
+            avctx->color_trc       != AVCOL_TRC_UNSPECIFIED ||
+            avctx->colorspace      != AVCOL_SPC_UNSPECIFIED) {
+            mseq->video_signal_type_present_flag = 1;
+            mseq->video_format             = 5; // Unspecified.
+            mseq->video_full_range_flag    = 0;
+            mseq->colour_description_present_flag = 1;
+            // These enums are derived from the standard and hence
+            // we can just use the values directly.
+            mseq->colour_primaries         = avctx->color_primaries;
+            mseq->transfer_characteristics = avctx->color_trc;
+            mseq->matrix_coefficients      = avctx->colorspace;
+        }
+
         vseq->bits_per_second = avctx->bit_rate;
+
+        vseq->vui_fields.bits.timing_info_present_flag = 1;
         if (avctx->framerate.num > 0 && avctx->framerate.den > 0) {
             vseq->num_units_in_tick = avctx->framerate.num;
             vseq->time_scale        = 2 * avctx->framerate.den;
+            mseq->fixed_frame_rate_flag = 1;
         } else {
             vseq->num_units_in_tick = avctx->time_base.num;
             vseq->time_scale        = 2 * avctx->time_base.den;
+            mseq->fixed_frame_rate_flag = 0;
         }
 
         vseq->intra_period     = ctx->p_per_i * (ctx->b_per_p + 1);



More information about the ffmpeg-cvslog mailing list