libs: add support for rate-control to GstVaapiContext.

Extend GstVaapiContextInfo structure to hold the desired rate control
mode for encoding purposes. For decoding purposes, this field is not
used and it is initialized to GST_VAAPI_RATECONTROL_NONE.

Signed-off-by: Gwenole Beauchesne <gwenole.beauchesne@intel.com>
This commit is contained in:
Wind Yuan 2013-07-12 22:07:59 +08:00 committed by Gwenole Beauchesne
parent 082fb3f1b4
commit 02e174c8bc
2 changed files with 38 additions and 6 deletions

View file

@ -522,7 +522,9 @@ gst_vaapi_context_create(GstVaapiContext *context)
GstVaapiDisplay * const display = GST_VAAPI_OBJECT_DISPLAY(context); GstVaapiDisplay * const display = GST_VAAPI_OBJECT_DISPLAY(context);
VAProfile va_profile; VAProfile va_profile;
VAEntrypoint va_entrypoint; VAEntrypoint va_entrypoint;
VAConfigAttrib attrib; guint va_rate_control;
VAConfigAttrib attribs[2];
guint num_attribs;
VAContextID context_id; VAContextID context_id;
VASurfaceID surface_id; VASurfaceID surface_id;
VAStatus status; VAStatus status;
@ -557,26 +559,42 @@ gst_vaapi_context_create(GstVaapiContext *context)
va_profile = gst_vaapi_profile_get_va_profile(cip->profile); va_profile = gst_vaapi_profile_get_va_profile(cip->profile);
va_entrypoint = gst_vaapi_entrypoint_get_va_entrypoint(cip->entrypoint); va_entrypoint = gst_vaapi_entrypoint_get_va_entrypoint(cip->entrypoint);
num_attribs = 0;
attribs[num_attribs++].type = VAConfigAttribRTFormat;
if (cip->entrypoint == GST_VAAPI_ENTRYPOINT_SLICE_ENCODE)
attribs[num_attribs++].type = VAConfigAttribRateControl;
GST_VAAPI_DISPLAY_LOCK(display); GST_VAAPI_DISPLAY_LOCK(display);
attrib.type = VAConfigAttribRTFormat;
status = vaGetConfigAttributes( status = vaGetConfigAttributes(
GST_VAAPI_DISPLAY_VADISPLAY(display), GST_VAAPI_DISPLAY_VADISPLAY(display),
va_profile, va_profile,
va_entrypoint, va_entrypoint,
&attrib, 1 attribs, num_attribs
); );
GST_VAAPI_DISPLAY_UNLOCK(display); GST_VAAPI_DISPLAY_UNLOCK(display);
if (!vaapi_check_status(status, "vaGetConfigAttributes()")) if (!vaapi_check_status(status, "vaGetConfigAttributes()"))
goto end; goto end;
if (!(attrib.value & VA_RT_FORMAT_YUV420)) if (!(attribs[0].value & VA_RT_FORMAT_YUV420))
goto end; goto end;
if (cip->entrypoint == GST_VAAPI_ENTRYPOINT_SLICE_ENCODE) {
va_rate_control = from_GstVaapiRateControl(cip->rc_mode);
if (va_rate_control == VA_RC_NONE)
attribs[1].value = VA_RC_NONE;
if ((attribs[1].value & va_rate_control) != va_rate_control) {
GST_ERROR("unsupported %s rate control",
string_of_VARateControl(va_rate_control));
goto end;
}
attribs[1].value = va_rate_control;
}
GST_VAAPI_DISPLAY_LOCK(display); GST_VAAPI_DISPLAY_LOCK(display);
status = vaCreateConfig( status = vaCreateConfig(
GST_VAAPI_DISPLAY_VADISPLAY(display), GST_VAAPI_DISPLAY_VADISPLAY(display),
va_profile, va_profile,
va_entrypoint, va_entrypoint,
&attrib, 1, attribs, num_attribs,
&context->config_id &context->config_id
); );
GST_VAAPI_DISPLAY_UNLOCK(display); GST_VAAPI_DISPLAY_UNLOCK(display);
@ -651,6 +669,7 @@ gst_vaapi_context_new(
info.profile = profile; info.profile = profile;
info.entrypoint = entrypoint; info.entrypoint = entrypoint;
info.rc_mode = GST_VAAPI_RATECONTROL_NONE;
info.width = width; info.width = width;
info.height = height; info.height = height;
info.ref_frames = get_max_ref_frames(profile); info.ref_frames = get_max_ref_frames(profile);
@ -719,6 +738,7 @@ gst_vaapi_context_reset(
info.profile = profile; info.profile = profile;
info.entrypoint = entrypoint; info.entrypoint = entrypoint;
info.rc_mode = GST_VAAPI_RATECONTROL_NONE;
info.width = width; info.width = width;
info.height = height; info.height = height;
info.ref_frames = context->info.ref_frames; info.ref_frames = context->info.ref_frames;
@ -742,7 +762,7 @@ gst_vaapi_context_reset_full(GstVaapiContext *context,
const GstVaapiContextInfo *new_cip) const GstVaapiContextInfo *new_cip)
{ {
GstVaapiContextInfo * const cip = &context->info; GstVaapiContextInfo * const cip = &context->info;
gboolean size_changed, codec_changed; gboolean size_changed, codec_changed, rc_mode_changed;
size_changed = cip->width != new_cip->width || size_changed = cip->width != new_cip->width ||
cip->height != new_cip->height; cip->height != new_cip->height;
@ -760,6 +780,14 @@ gst_vaapi_context_reset_full(GstVaapiContext *context,
cip->entrypoint = new_cip->entrypoint; cip->entrypoint = new_cip->entrypoint;
} }
if (new_cip->entrypoint == GST_VAAPI_ENTRYPOINT_SLICE_ENCODE) {
rc_mode_changed = cip->rc_mode != cip->rc_mode;
if (rc_mode_changed) {
gst_vaapi_context_destroy(context);
cip->rc_mode = new_cip->rc_mode;
}
}
if (size_changed && !gst_vaapi_context_create_surfaces(context)) if (size_changed && !gst_vaapi_context_create_surfaces(context))
return FALSE; return FALSE;

View file

@ -45,10 +45,14 @@ typedef struct _GstVaapiContextInfo GstVaapiContextInfo;
* Structure holding VA context info like encoded size, decoder * Structure holding VA context info like encoded size, decoder
* profile and entry-point to use, and maximum number of reference * profile and entry-point to use, and maximum number of reference
* frames reported by the bitstream. * frames reported by the bitstream.
*
* Note: @rc_mode is only valid for VA context used for encoding,
* i.e. if @entrypoint is set to @GST_VAAPI_ENTRYPOINT_SLICE_ENCODE.
*/ */
struct _GstVaapiContextInfo { struct _GstVaapiContextInfo {
GstVaapiProfile profile; GstVaapiProfile profile;
GstVaapiEntrypoint entrypoint; GstVaapiEntrypoint entrypoint;
GstVaapiRateControl rc_mode;
guint width; guint width;
guint height; guint height;
guint ref_frames; guint ref_frames;