basevideoencoder: enhance set_caps

Specifically, only invoke set_format if incoming format really changed,
and finish current format if so (and if any current).
This commit is contained in:
Mark Nauwelaerts 2011-03-24 08:23:27 +01:00
parent d68288b597
commit d0753dec9b

View file

@ -167,42 +167,86 @@ gst_base_video_encoder_sink_setcaps (GstPad * pad, GstCaps * caps)
GstStructure *structure; GstStructure *structure;
GstVideoState *state; GstVideoState *state;
gboolean ret; gboolean ret;
gboolean changed = FALSE, u, v;
GstVideoFormat fmt;
gint w, h, num, den;
base_video_encoder = GST_BASE_VIDEO_ENCODER (gst_pad_get_parent (pad)); base_video_encoder = GST_BASE_VIDEO_ENCODER (gst_pad_get_parent (pad));
base_video_encoder_class = base_video_encoder_class =
GST_BASE_VIDEO_ENCODER_GET_CLASS (base_video_encoder); GST_BASE_VIDEO_ENCODER_GET_CLASS (base_video_encoder);
/* subclass should do something here ... */
g_return_val_if_fail (base_video_encoder_class->set_format != NULL, FALSE);
GST_DEBUG_OBJECT (base_video_encoder, "setcaps %" GST_PTR_FORMAT, caps); GST_DEBUG_OBJECT (base_video_encoder, "setcaps %" GST_PTR_FORMAT, caps);
state = &GST_BASE_VIDEO_CODEC (base_video_encoder)->state; state = &GST_BASE_VIDEO_CODEC (base_video_encoder)->state;
structure = gst_caps_get_structure (caps, 0); structure = gst_caps_get_structure (caps, 0);
gst_video_format_parse_caps (caps, &state->format, ret = gst_video_format_parse_caps (caps, &fmt, &w, &h);
&state->width, &state->height); if (!ret)
goto exit;
state->fps_n = 0; if (fmt != state->format || w != state->width || h != state->height) {
state->fps_d = 1; changed = TRUE;
gst_video_parse_caps_framerate (caps, &state->fps_n, &state->fps_d); state->format = fmt;
if (state->fps_d == 0) { state->width = w;
state->fps_n = 0; state->height = h;
state->fps_d = 1;
} }
state->par_n = 1; num = 0;
state->par_d = 1; den = 1;
gst_video_parse_caps_pixel_aspect_ratio (caps, &state->par_n, &state->par_d); gst_video_parse_caps_framerate (caps, &num, &den);
if (den == 0) {
num = 0;
den = 1;
}
if (num != state->fps_n || den != state->fps_d) {
changed = TRUE;
state->fps_n = num;
state->fps_d = den;
}
state->have_interlaced = gst_structure_get_boolean (structure, num = 0;
"interlaced", &state->interlaced); den = 1;
gst_video_parse_caps_pixel_aspect_ratio (caps, &num, &den);
if (den == 0) {
num = 0;
den = 1;
}
if (num != state->par_n || den != state->par_d) {
changed = TRUE;
state->par_n = num;
state->par_d = den;
}
u = gst_structure_get_boolean (structure, "interlaced", &v);
if (u != state->have_interlaced || v != state->interlaced) {
changed = TRUE;
state->have_interlaced = u;
state->interlaced = v;
}
state->clean_width = state->width; state->clean_width = state->width;
state->clean_height = state->height; state->clean_height = state->height;
state->clean_offset_left = 0; state->clean_offset_left = 0;
state->clean_offset_top = 0; state->clean_offset_top = 0;
ret = base_video_encoder_class->set_format (base_video_encoder, if (changed) {
&GST_BASE_VIDEO_CODEC (base_video_encoder)->state); /* arrange draining pending frames */
gst_base_video_encoder_drain (base_video_encoder);
/* and subclass should be ready to configure format at any time around */
if (base_video_encoder_class->set_format)
ret = base_video_encoder_class->set_format (base_video_encoder, state);
} else {
/* no need to stir things up */
GST_DEBUG_OBJECT (base_video_encoder,
"new video format identical to configured format");
ret = TRUE;
}
exit:
g_object_unref (base_video_encoder); g_object_unref (base_video_encoder);
if (!ret) { if (!ret) {
@ -497,6 +541,9 @@ gst_base_video_encoder_chain (GstPad * pad, GstBuffer * buf)
GST_BASE_VIDEO_CODEC (base_video_encoder)->frames = GST_BASE_VIDEO_CODEC (base_video_encoder)->frames =
g_list_append (GST_BASE_VIDEO_CODEC (base_video_encoder)->frames, frame); g_list_append (GST_BASE_VIDEO_CODEC (base_video_encoder)->frames, frame);
/* new data, more finish needed */
base_video_encoder->drained = FALSE;
GST_LOG_OBJECT (base_video_encoder, "passing frame pfn %d to subclass", GST_LOG_OBJECT (base_video_encoder, "passing frame pfn %d to subclass",
frame->presentation_frame_number); frame->presentation_frame_number);