static void
set_context_info (GstVaapiEncoder * encoder)
{
- GstVaapiEncoderClass *const klass = GST_VAAPI_ENCODER_GET_CLASS (encoder);
GstVaapiContextInfo *const cip = &encoder->context_info;
- cip->profile = GST_VAAPI_PROFILE_UNKNOWN;
+ cip->profile = encoder->profile;
cip->entrypoint = GST_VAAPI_ENTRYPOINT_SLICE_ENCODE;
cip->rc_mode = GST_VAAPI_ENCODER_RATE_CONTROL (encoder);
cip->width = GST_VAAPI_ENCODER_WIDTH (encoder);
cip->height = GST_VAAPI_ENCODER_HEIGHT (encoder);
- cip->ref_frames = 0;
- klass->set_context_info (encoder);
+ cip->ref_frames = encoder->num_ref_frames;
}
/* Ensures the underlying VA context for encoding is created */
CHECK_VTABLE_HOOK (encode);
CHECK_VTABLE_HOOK (reordering);
CHECK_VTABLE_HOOK (flush);
- CHECK_VTABLE_HOOK (set_context_info);
#undef CHECK_VTABLE_HOOK
return TRUE;
}
-gboolean
-init_encoder_public_attributes (GstVaapiEncoderH264 * encoder)
+static gboolean
+ensure_profile_and_level (GstVaapiEncoderH264 * encoder)
{
- GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder);
- guint width_mbs, height_mbs, total_mbs;
-
if (!encoder->profile)
encoder->profile = GST_VAAPI_ENCODER_H264_DEFAULT_PROFILE;
_set_level (encoder);
+ return TRUE;
+}
+
+static gboolean
+ensure_bitrate (GstVaapiEncoderH264 * encoder)
+{
+ GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder);
+
+ /* Default compression: 64 bits per macroblock */
+ switch (GST_VAAPI_ENCODER_RATE_CONTROL (encoder)) {
+ case GST_VAAPI_RATECONTROL_CBR:
+ case GST_VAAPI_RATECONTROL_VBR:
+ case GST_VAAPI_RATECONTROL_VBR_CONSTRAINED:
+ if (!base_encoder->bitrate)
+ base_encoder->bitrate = GST_VAAPI_ENCODER_WIDTH (encoder) *
+ GST_VAAPI_ENCODER_HEIGHT (encoder) *
+ GST_VAAPI_ENCODER_FPS_N (encoder) /
+ GST_VAAPI_ENCODER_FPS_D (encoder) / 4 / 1024;
+ break;
+ default:
+ base_encoder->bitrate = 0;
+ break;
+ }
+ return TRUE;
+}
+
+static void
+reset_properties (GstVaapiEncoderH264 * encoder)
+{
+ guint width_mbs, height_mbs, total_mbs;
if (encoder->intra_period > GST_VAAPI_ENCODER_H264_MAX_INTRA_PERIOD)
encoder->intra_period = GST_VAAPI_ENCODER_H264_MAX_INTRA_PERIOD;
encoder->min_qp < encoder->init_qp))
encoder->min_qp = encoder->init_qp;
- /* default compress ratio 1: (4*8*1.5) */
- if (GST_VAAPI_RATECONTROL_CBR == GST_VAAPI_ENCODER_RATE_CONTROL (encoder) ||
- GST_VAAPI_RATECONTROL_VBR == GST_VAAPI_ENCODER_RATE_CONTROL (encoder) ||
- GST_VAAPI_RATECONTROL_VBR_CONSTRAINED ==
- GST_VAAPI_ENCODER_RATE_CONTROL (encoder)) {
- if (!base_encoder->bitrate)
- base_encoder->bitrate = GST_VAAPI_ENCODER_WIDTH (encoder) *
- GST_VAAPI_ENCODER_HEIGHT (encoder) *
- GST_VAAPI_ENCODER_FPS_N (encoder) /
- GST_VAAPI_ENCODER_FPS_D (encoder) / 4 / 1024;
- } else
- base_encoder->bitrate = 0;
-
width_mbs = (GST_VAAPI_ENCODER_WIDTH (encoder) + 15) / 16;
height_mbs = (GST_VAAPI_ENCODER_HEIGHT (encoder) + 15) / 16;
total_mbs = width_mbs * height_mbs;
if (encoder->b_frame_num > 50)
encoder->b_frame_num = 50;
- return TRUE;
-}
-
-static gboolean
-init_encoder_private_attributes (GstVaapiEncoderH264 * encoder)
-{
if (encoder->b_frame_num)
encoder->cts_offset = GST_SECOND * GST_VAAPI_ENCODER_FPS_D (encoder) /
GST_VAAPI_ENCODER_FPS_N (encoder);
encoder->max_reflist1_count = 0;
encoder->max_ref_num =
encoder->max_reflist0_count + encoder->max_reflist1_count;
- return TRUE;
}
}
static void
-gst_vaapi_encoder_h264_set_context_info (GstVaapiEncoder * base_encoder)
+set_context_info (GstVaapiEncoder * base_encoder)
{
GstVaapiEncoderH264 *const encoder = GST_VAAPI_ENCODER_H264 (base_encoder);
- GstVaapiContextInfo *const cip = &base_encoder->context_info;
+ GstVideoInfo *const vip = GST_VAAPI_ENCODER_VIDEO_INFO (encoder);
const guint DEFAULT_SURFACES_COUNT = 3;
/* Maximum sizes for common headers (in bits) */
MAX_SLICE_HDR_SIZE = 397 + 2572 + 6670 + 2402,
};
- cip->profile = encoder->profile;
- cip->ref_frames = (encoder->b_frame_num ? 2 : 1) + DEFAULT_SURFACES_COUNT;
+ base_encoder->profile = encoder->profile;
+ base_encoder->num_ref_frames =
+ (encoder->b_frame_num ? 2 : 1) + DEFAULT_SURFACES_COUNT;
/* Only YUV 4:2:0 formats are supported for now. This means that we
have a limit of 3200 bits per macroblock. */
/* XXX: check profile and compute RawMbBits */
- base_encoder->codedbuf_size = (GST_ROUND_UP_16 (cip->width) *
- GST_ROUND_UP_16 (cip->height) / 256) * 400;
+ base_encoder->codedbuf_size = (GST_ROUND_UP_16 (vip->width) *
+ GST_ROUND_UP_16 (vip->height) / 256) * 400;
/* Account for SPS header */
/* XXX: exclude scaling lists, MVC/SVC extensions */
GstVaapiEncoderH264 *const encoder =
GST_VAAPI_ENCODER_H264_CAST (base_encoder);
- if (!init_encoder_public_attributes (encoder)) {
- GST_WARNING ("encoder ensure public attributes failed ");
+ if (!ensure_profile_and_level (encoder))
goto error;
- }
-
- if (!init_encoder_private_attributes (encoder)) {
- GST_WARNING ("prepare encoding failed ");
+ if (!ensure_bitrate (encoder))
goto error;
- }
+
+ reset_properties (encoder);
+ set_context_info (base_encoder);
return GST_VAAPI_ENCODER_STATUS_SUCCESS;
error:
}
static gboolean
-ensure_public_attributes (GstVaapiEncoderMpeg2 * encoder)
+ensure_profile_and_level (GstVaapiEncoderMpeg2 * encoder)
{
- GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder);
-
- if (encoder->ip_period > encoder->intra_period) {
- encoder->ip_period = encoder->intra_period - 1;
- }
-
if (encoder->profile == GST_ENCODER_MPEG2_PROFILE_SIMPLE) {
/* no b frames */
encoder->ip_period = 0;
/* only main level is defined in mpeg2 */
encoder->level = GST_VAAPI_ENCODER_MPEG2_LEVEL_MAIN;
}
+ return TRUE;
+}
- if (!ensure_sampling_desity (encoder))
- return FALSE;
-
- /* default compress ratio 1: (4*8*1.5) */
- if (GST_VAAPI_RATECONTROL_CBR == GST_VAAPI_ENCODER_RATE_CONTROL (encoder)) {
- if (!base_encoder->bitrate)
- base_encoder->bitrate = GST_VAAPI_ENCODER_WIDTH (encoder) *
- GST_VAAPI_ENCODER_HEIGHT (encoder) *
- GST_VAAPI_ENCODER_FPS_N (encoder) /
- GST_VAAPI_ENCODER_FPS_D (encoder) / 4 / 1024;
- } else
- base_encoder->bitrate = 0;
+static gboolean
+ensure_bitrate (GstVaapiEncoderMpeg2 * encoder)
+{
+ GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder);
+ /* Default compression: 64 bits per macroblock */
+ switch (GST_VAAPI_ENCODER_RATE_CONTROL (encoder)) {
+ case GST_VAAPI_RATECONTROL_CBR:
+ if (!base_encoder->bitrate)
+ base_encoder->bitrate = GST_VAAPI_ENCODER_WIDTH (encoder) *
+ GST_VAAPI_ENCODER_HEIGHT (encoder) *
+ GST_VAAPI_ENCODER_FPS_N (encoder) /
+ GST_VAAPI_ENCODER_FPS_D (encoder) / 4 / 1024;
+ break;
+ default:
+ base_encoder->bitrate = 0;
+ break;
+ }
return TRUE;
}
}
static void
-gst_vaapi_encoder_mpeg2_set_context_info (GstVaapiEncoder * base_encoder)
+set_context_info (GstVaapiEncoder * base_encoder)
{
GstVaapiEncoderMpeg2 *const encoder = GST_VAAPI_ENCODER_MPEG2 (base_encoder);
- GstVaapiContextInfo *const cip = &base_encoder->context_info;
+ GstVideoInfo *const vip = GST_VAAPI_ENCODER_VIDEO_INFO (encoder);
/* Maximum sizes for common headers (in bytes) */
enum
MAX_SLICE_HDR_SIZE = 8,
};
- cip->profile = to_vaapi_profile (encoder->profile);
- cip->ref_frames = 2;
+ base_encoder->profile = to_vaapi_profile (encoder->profile);
+ base_encoder->num_ref_frames = 2;
/* Only YUV 4:2:0 formats are supported for now. This means that we
have a limit of 4608 bits per macroblock. */
- base_encoder->codedbuf_size = (GST_ROUND_UP_16 (cip->width) *
- GST_ROUND_UP_16 (cip->height) / 256) * 576;
+ base_encoder->codedbuf_size = (GST_ROUND_UP_16 (vip->width) *
+ GST_ROUND_UP_16 (vip->height) / 256) * 576;
/* Account for Sequence, GOP, and Picture headers */
/* XXX: exclude unused Sequence Display Extension, Sequence Scalable
MAX_GOP_SIZE + MAX_PIC_HDR_SIZE + MAX_PIC_EXT_SIZE;
/* Account for Slice headers. We use one slice per line of macroblock */
- base_encoder->codedbuf_size += (GST_ROUND_UP_16 (cip->height) / 16) *
+ base_encoder->codedbuf_size += (GST_ROUND_UP_16 (vip->height) / 16) *
MAX_SLICE_HDR_SIZE;
}
GstVaapiEncoderMpeg2 *const encoder =
GST_VAAPI_ENCODER_MPEG2_CAST (base_encoder);
- if (!ensure_public_attributes (encoder)) {
- GST_WARNING ("encoder ensure public attributes failed ");
- goto error;
+ if (encoder->ip_period > encoder->intra_period) {
+ encoder->ip_period = encoder->intra_period - 1;
}
+
+ if (!ensure_profile_and_level (encoder))
+ goto error;
+ if (!ensure_bitrate (encoder))
+ goto error;
+ if (!ensure_sampling_desity (encoder))
+ goto error;
+
+ set_context_info (base_encoder);
return GST_VAAPI_ENCODER_STATUS_SUCCESS;
error:
VADisplay va_display;
VAContextID va_context;
GstVideoInfo video_info;
+ GstVaapiProfile profile;
+ guint num_ref_frames;
GstVaapiRateControl rate_control;
guint32 rate_control_mask;
guint bitrate; /* kbps */
gboolean (*init) (GstVaapiEncoder * encoder);
void (*finalize) (GstVaapiEncoder * encoder);
- void (*set_context_info) (GstVaapiEncoder * encoder);
-
GstVaapiEncoderStatus (*reconfigure) (GstVaapiEncoder * encoder);
GPtrArray * (*get_default_properties) (void);
GST_VAAPI_ENCODER_CLASS_HOOK (codec, finalize), \
GST_VAAPI_ENCODER_CLASS_HOOK (codec, reconfigure), \
GST_VAAPI_ENCODER_CLASS_HOOK (codec, get_default_properties), \
- GST_VAAPI_ENCODER_CLASS_HOOK (codec, set_context_info), \
GST_VAAPI_ENCODER_CLASS_HOOK (codec, reordering), \
GST_VAAPI_ENCODER_CLASS_HOOK (codec, encode), \
GST_VAAPI_ENCODER_CLASS_HOOK (codec, flush)