summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ext/mpeg2dec/gstmpeg2dec.c384
-rw-r--r--ext/mpeg2dec/gstmpeg2dec.h5
2 files changed, 207 insertions, 182 deletions
diff --git a/ext/mpeg2dec/gstmpeg2dec.c b/ext/mpeg2dec/gstmpeg2dec.c
index 28616c56..73908759 100644
--- a/ext/mpeg2dec/gstmpeg2dec.c
+++ b/ext/mpeg2dec/gstmpeg2dec.c
@@ -222,6 +222,11 @@ gst_mpeg2dec_stop (GstVideoDecoder * decoder)
gst_video_codec_state_unref (mpeg2dec->input_state);
mpeg2dec->input_state = NULL;
+ if (mpeg2dec->downstream_pool) {
+ gst_buffer_pool_set_active (mpeg2dec->downstream_pool, FALSE);
+ gst_object_unref (mpeg2dec->downstream_pool);
+ }
+
return TRUE;
}
@@ -237,6 +242,9 @@ gst_mpeg2dec_flush (GstVideoDecoder * decoder)
gst_mpeg2dec_clear_buffers (mpeg2dec);
+ if (mpeg2dec->downstream_pool)
+ gst_buffer_pool_set_active (mpeg2dec->downstream_pool, FALSE);
+
return TRUE;
}
@@ -250,13 +258,24 @@ static gboolean
gst_mpeg2dec_decide_allocation (GstVideoDecoder * decoder, GstQuery * query)
{
GstMpeg2dec *dec = GST_MPEG2DEC (decoder);
- GstVideoCodecState *state;
GstBufferPool *pool;
guint size, min, max;
- GstStructure *config;
+ GstStructure *config, *down_config = NULL;
GstAllocator *allocator;
GstAllocationParams params;
gboolean update_allocator;
+ gboolean has_videometa = FALSE;
+ GstCaps *caps;
+
+ /* Get rid of ancient pool */
+ if (dec->downstream_pool) {
+ gst_buffer_pool_set_active (dec->downstream_pool, FALSE);
+ gst_object_unref (dec->downstream_pool);
+ dec->downstream_pool = NULL;
+ }
+
+ /* Get negotiated allocation caps */
+ gst_query_parse_allocation (query, &caps, NULL);
/* Set allocation parameters to guarantee 16-byte aligned output buffers */
if (gst_query_get_n_allocation_params (query) > 0) {
@@ -274,47 +293,133 @@ gst_mpeg2dec_decide_allocation (GstVideoDecoder * decoder, GstQuery * query)
gst_query_set_nth_allocation_param (query, 0, allocator, &params);
else
gst_query_add_allocation_param (query, allocator, &params);
- if (allocator)
- gst_object_unref (allocator);
/* Now chain up to the parent class to guarantee that we can
* get a buffer pool from the query */
if (!GST_VIDEO_DECODER_CLASS (parent_class)->decide_allocation (decoder,
- query))
+ query)) {
+ if (allocator)
+ gst_object_unref (allocator);
return FALSE;
-
- state = gst_video_decoder_get_output_state (decoder);
+ }
gst_query_parse_nth_allocation_pool (query, 0, &pool, &size, &min, &max);
- dec->has_cropping = FALSE;
config = gst_buffer_pool_get_config (pool);
if (gst_query_find_allocation_meta (query, GST_VIDEO_META_API_TYPE, NULL)) {
gst_buffer_pool_config_add_option (config,
GST_BUFFER_POOL_OPTION_VIDEO_META);
- dec->has_cropping =
- gst_query_find_allocation_meta (query, GST_VIDEO_CROP_META_API_TYPE,
- NULL);
+ has_videometa = TRUE;
}
- if (dec->has_cropping) {
- GstCaps *caps;
+ if (dec->need_alignment) {
+ /* If downstream does not support video meta, we will have to copy, keep
+ * the downstream pool to avoid double copying */
+ if (!has_videometa) {
+ dec->downstream_pool = pool;
+ pool = NULL;
+ down_config = gst_structure_copy (config);
+ config = NULL;
+ min = 2;
+ max = 0;
+ }
+
+ /* In case downstream support video meta, but the downstream pool does not
+ * have alignment support, discard downstream pool and use video pool */
+ else if (!gst_buffer_pool_has_option (pool,
+ GST_BUFFER_POOL_OPTION_VIDEO_ALIGNMENT)) {
+ gst_object_unref (pool);
+ pool = NULL;
+ gst_structure_free (config);
+ config = NULL;
+ }
+
+ if (!pool) {
+ pool = gst_video_buffer_pool_new ();
+ config = gst_buffer_pool_get_config (pool);
+ gst_buffer_pool_config_set_allocator (config, allocator, &params);
+ gst_buffer_pool_config_set_params (config, caps, size, min, max);
+ gst_buffer_pool_config_add_option (config,
+ GST_BUFFER_POOL_OPTION_VIDEO_META);
+ }
- /* Calculate uncropped size */
- size = MAX (size, dec->decoded_info.size);
- caps = gst_video_info_to_caps (&dec->decoded_info);
- gst_buffer_pool_config_set_params (config, caps, size, min, max);
- gst_caps_unref (caps);
+ gst_buffer_pool_config_add_option (config,
+ GST_BUFFER_POOL_OPTION_VIDEO_ALIGNMENT);
+ gst_buffer_pool_config_set_video_alignment (config, &dec->valign);
}
- gst_buffer_pool_set_config (pool, config);
+ if (allocator)
+ gst_object_unref (allocator);
- gst_query_set_nth_allocation_pool (query, 0, pool, size, min, max);
+ /* If we are copying out, we'll need to setup and active the other pool */
+ if (dec->downstream_pool) {
+ if (!gst_buffer_pool_set_config (dec->downstream_pool, down_config)) {
+ down_config = gst_buffer_pool_get_config (dec->downstream_pool);
+ if (!gst_buffer_pool_config_validate_params (down_config, caps, size, min,
+ max)) {
+ gst_structure_free (down_config);
+ goto config_failed;
+ }
+
+ if (!gst_buffer_pool_set_config (dec->downstream_pool, down_config))
+ goto config_failed;
+ }
+
+ if (!gst_buffer_pool_set_active (dec->downstream_pool, TRUE))
+ goto pool_activation_failed;
+ }
+
+ /* Now configure the pool, if the pool had made some changes, it will
+ * return FALSE. Validate the changes ...*/
+ if (!gst_buffer_pool_set_config (pool, config)) {
+ config = gst_buffer_pool_get_config (pool);
+
+ /* Check basic params */
+ if (!gst_buffer_pool_config_validate_params (config, caps, size, min, max)) {
+ gst_structure_free (config);
+ goto config_failed;
+ }
+
+ /* If needed, check that resulting alignment is still valid */
+ if (dec->need_alignment) {
+ GstVideoAlignment valign;
+
+ if (!gst_buffer_pool_config_get_video_alignment (config, &valign)) {
+ gst_structure_free (config);
+ goto config_failed;
+ }
+
+ if (valign.padding_left != 0 || valign.padding_top != 0
+ || valign.padding_right < dec->valign.padding_right
+ || valign.padding_bottom < dec->valign.padding_bottom) {
+ gst_structure_free (config);
+ goto config_failed;
+ }
+ }
+
+ if (!gst_buffer_pool_set_config (pool, config))
+ goto config_failed;
+ /* FIXME Activate the pool, and check that strides are uniform */
+ }
+
+ gst_query_set_nth_allocation_pool (query, 0, pool, size, min, max);
gst_object_unref (pool);
- gst_video_codec_state_unref (state);
return TRUE;
+
+config_failed:
+ gst_object_unref (pool);
+ GST_ELEMENT_ERROR (dec, RESOURCE, SETTINGS,
+ ("Failed to configure buffer pool"),
+ ("Configuration is most likely invalid, please report this issue."));
+ return FALSE;
+
+pool_activation_failed:
+ gst_object_unref (pool);
+ GST_ELEMENT_ERROR (dec, RESOURCE, SETTINGS,
+ ("Failed to activate downstream buffer pool"), (NULL));
+ return FALSE;
}
static GstFlowReturn
@@ -324,9 +429,9 @@ gst_mpeg2dec_crop_buffer (GstMpeg2dec * dec, GstVideoCodecFrame * in_frame,
GstVideoCodecState *state;
GstVideoInfo *info;
GstVideoInfo *dinfo;
- guint c, n_planes;
GstVideoFrame output_frame;
GstFlowReturn ret;
+ GstBuffer *buffer;
state = gst_video_decoder_get_output_state (GST_VIDEO_DECODER (dec));
info = &state->info;
@@ -337,39 +442,17 @@ gst_mpeg2dec_crop_buffer (GstMpeg2dec * dec, GstVideoCodecFrame * in_frame,
"%ux%u (%" G_GSIZE_FORMAT ")", dinfo->width, dinfo->height,
dinfo->size, info->width, info->height, info->size);
- ret =
- gst_video_decoder_allocate_output_frame (GST_VIDEO_DECODER (dec),
- in_frame);
+ ret = gst_buffer_pool_acquire_buffer (dec->downstream_pool, &buffer, NULL);
if (ret != GST_FLOW_OK)
goto beach;
- if (!gst_video_frame_map (&output_frame, info, in_frame->output_buffer,
- GST_MAP_WRITE))
+ if (!gst_video_frame_map (&output_frame, info, buffer, GST_MAP_WRITE))
goto map_fail;
- n_planes = GST_VIDEO_FRAME_N_PLANES (&output_frame);
- for (c = 0; c < n_planes; c++) {
- guint w, h, j;
- guint8 *sp, *dp;
- gint ss, ds;
+ gst_buffer_replace (&in_frame->output_buffer, buffer);
- sp = GST_VIDEO_FRAME_PLANE_DATA (input_vframe, c);
- dp = GST_VIDEO_FRAME_PLANE_DATA (&output_frame, c);
-
- ss = GST_VIDEO_FRAME_PLANE_STRIDE (input_vframe, c);
- ds = GST_VIDEO_FRAME_PLANE_STRIDE (&output_frame, c);
-
- w = MIN (ABS (ss), ABS (ds));
- h = GST_VIDEO_FRAME_COMP_HEIGHT (&output_frame, c);
-
- GST_CAT_DEBUG (GST_CAT_PERFORMANCE, "copy plane %u, w:%u h:%u ", c, w, h);
-
- for (j = 0; j < h; j++) {
- memcpy (dp, sp, w);
- dp += ds;
- sp += ss;
- }
- }
+ if (!gst_video_frame_copy (&output_frame, input_vframe))
+ goto copy_failed;
gst_video_frame_unmap (&output_frame);
@@ -387,48 +470,13 @@ map_fail:
gst_video_codec_state_unref (state);
return GST_FLOW_ERROR;
}
-}
-static void
-frame_user_data_destroy_notify (GstBuffer * buf)
-{
- GST_DEBUG ("Releasing buffer %p", buf);
- if (buf)
- gst_buffer_unref (buf);
-}
-
-static GstFlowReturn
-gst_mpeg2dec_alloc_sized_buf (GstMpeg2dec * mpeg2dec, guint size,
- GstVideoCodecFrame * frame, GstBuffer ** buffer)
-{
- GstFlowReturn ret = GST_FLOW_OK;
- GstVideoCodecState *state;
-
- state = gst_video_decoder_get_output_state (GST_VIDEO_DECODER (mpeg2dec));
-
- if (!mpeg2dec->need_cropping || mpeg2dec->has_cropping) {
- /* need parsed input, but that might be slightly bogus,
- * so avoid giving up altogether and mark it as error */
- if (frame->output_buffer) {
- gst_buffer_replace (&frame->output_buffer, NULL);
- GST_VIDEO_DECODER_ERROR (mpeg2dec, 1, STREAM, DECODE,
- ("decoding error"), ("Input not correctly parsed"), ret);
- }
- ret =
- gst_video_decoder_allocate_output_frame (GST_VIDEO_DECODER (mpeg2dec),
- frame);
- *buffer = frame->output_buffer;
- } else {
- GstAllocationParams params = { 0, 15, 0, 0 };
-
- *buffer = gst_buffer_new_allocate (NULL, size, &params);
- gst_video_codec_frame_set_user_data (frame, *buffer,
- (GDestroyNotify) frame_user_data_destroy_notify);
+copy_failed:
+ {
+ GST_ERROR_OBJECT (dec, "Failed to copy output frame");
+ gst_video_codec_state_unref (state);
+ return GST_FLOW_ERROR;
}
-
- gst_video_codec_state_unref (state);
-
- return ret;
}
typedef struct
@@ -504,67 +552,6 @@ gst_mpeg2dec_get_buffer (GstMpeg2dec * mpeg2dec, gint id)
return NULL;
}
-static GstFlowReturn
-gst_mpeg2dec_alloc_buffer (GstMpeg2dec * mpeg2dec, GstVideoCodecFrame * frame,
- GstBuffer ** buffer)
-{
- GstFlowReturn ret;
- GstVideoFrame vframe;
- guint8 *buf[3];
-
- ret =
- gst_mpeg2dec_alloc_sized_buf (mpeg2dec, mpeg2dec->decoded_info.size,
- frame, buffer);
- if (G_UNLIKELY (ret != GST_FLOW_OK))
- goto beach;
-
- if (mpeg2dec->need_cropping && mpeg2dec->has_cropping) {
- GstVideoCropMeta *crop;
- GstVideoCodecState *state;
- GstVideoInfo *vinfo;
-
- state = gst_video_decoder_get_output_state (GST_VIDEO_DECODER (mpeg2dec));
- vinfo = &state->info;
-
- crop = gst_buffer_add_video_crop_meta (frame->output_buffer);
- /* we can do things slightly more efficient when we know that
- * downstream understands clipping */
- crop->x = 0;
- crop->y = 0;
- crop->width = vinfo->width;
- crop->height = vinfo->height;
-
- gst_video_codec_state_unref (state);
- }
-
- if (!gst_video_frame_map (&vframe, &mpeg2dec->decoded_info, *buffer,
- GST_MAP_READ | GST_MAP_WRITE))
- goto map_fail;
-
- buf[0] = GST_VIDEO_FRAME_PLANE_DATA (&vframe, 0);
- buf[1] = GST_VIDEO_FRAME_PLANE_DATA (&vframe, 1);
- buf[2] = GST_VIDEO_FRAME_PLANE_DATA (&vframe, 2);
-
- GST_DEBUG_OBJECT (mpeg2dec, "set_buf: %p %p %p, frame %i",
- buf[0], buf[1], buf[2], frame->system_frame_number);
-
- /* Note: We use a non-null 'id' value to make the distinction
- * between the dummy buffers (which have an id of NULL) and the
- * ones we did */
- mpeg2_set_buf (mpeg2dec->decoder, buf,
- GINT_TO_POINTER (frame->system_frame_number + 1));
- gst_mpeg2dec_save_buffer (mpeg2dec, frame->system_frame_number, &vframe);
-
-beach:
- return ret;
-
-map_fail:
- {
- GST_ERROR_OBJECT (mpeg2dec, "Failed to map frame");
- return GST_FLOW_ERROR;
- }
-}
-
static void
init_dummybuf (GstMpeg2dec * mpeg2dec)
{
@@ -588,9 +575,7 @@ handle_sequence (GstMpeg2dec * mpeg2dec, const mpeg2_info_t * info)
GstClockTime latency;
const mpeg2_sequence_t *sequence;
GstVideoCodecState *state;
- GstVideoInfo *dinfo = &mpeg2dec->decoded_info;
GstVideoInfo *vinfo;
- GstVideoInfo pre_crop_info;
GstVideoFormat format;
sequence = info->sequence;
@@ -609,13 +594,21 @@ handle_sequence (GstMpeg2dec * mpeg2dec, const mpeg2_info_t * info)
sequence->picture_width, sequence->picture_height, sequence->width,
sequence->height);
- if (sequence->picture_width != sequence->width ||
- sequence->picture_height != sequence->height) {
+ gst_video_alignment_reset (&mpeg2dec->valign);
+
+ if (sequence->picture_width < sequence->width ||
+ sequence->picture_height < sequence->height) {
GST_DEBUG_OBJECT (mpeg2dec, "we need to crop");
- mpeg2dec->need_cropping = TRUE;
- } else {
+ mpeg2dec->valign.padding_right = sequence->width - sequence->picture_width;
+ mpeg2dec->valign.padding_bottom =
+ sequence->height - sequence->picture_height;
+ mpeg2dec->need_alignment = TRUE;
+ } else if (sequence->picture_width == sequence->width ||
+ sequence->picture_height == sequence->height) {
GST_DEBUG_OBJECT (mpeg2dec, "no cropping needed");
- mpeg2dec->need_cropping = FALSE;
+ mpeg2dec->need_alignment = FALSE;
+ } else {
+ goto invalid_picture;
}
/* get subsampling */
@@ -759,15 +752,9 @@ handle_sequence (GstMpeg2dec * mpeg2dec, const mpeg2_info_t * info)
sequence->flags & SEQ_FLAG_LOW_DELAY,
sequence->flags & SEQ_FLAG_COLOUR_DESCRIPTION);
- /* we store the codec size before cropping */
- *dinfo = *vinfo;
- gst_video_info_set_format (&pre_crop_info, format, sequence->width,
- sequence->height);
- dinfo->width = sequence->width;
- dinfo->height = sequence->height;
- dinfo->size = pre_crop_info.size;
- memcpy (dinfo->stride, pre_crop_info.stride, sizeof (pre_crop_info.stride));
- memcpy (dinfo->offset, pre_crop_info.offset, sizeof (pre_crop_info.offset));
+ /* Save the padded video information */
+ mpeg2dec->decoded_info = *vinfo;
+ gst_video_info_align (&mpeg2dec->decoded_info, &mpeg2dec->valign);
/* Mpeg2dec has 2 frame latency to produce a picture and 1 frame latency in
* it's parser */
@@ -805,6 +792,15 @@ invalid_size:
return GST_FLOW_ERROR;
}
+invalid_picture:
+ {
+ GST_ERROR_OBJECT (mpeg2dec, "Picture dimension bigger then frame: "
+ "%d x %d is bigger then %d x %d", sequence->picture_width,
+ sequence->picture_height, sequence->width, sequence->height);
+ return GST_FLOW_ERROR;
+ }
+
+
negotiation_fail:
{
GST_WARNING_OBJECT (mpeg2dec, "Failed to negotiate with downstream");
@@ -817,14 +813,16 @@ static GstFlowReturn
handle_picture (GstMpeg2dec * mpeg2dec, const mpeg2_info_t * info,
GstVideoCodecFrame * frame)
{
+ GstVideoDecoder *decoder = (GstVideoDecoder *) mpeg2dec;
GstFlowReturn ret;
gint type;
const gchar *type_str = NULL;
gboolean key_frame = FALSE;
const mpeg2_picture_t *picture = info->current_picture;
- GstBuffer *buffer;
+ GstVideoFrame vframe;
+ guint8 *buf[3];
- ret = gst_mpeg2dec_alloc_buffer (mpeg2dec, frame, &buffer);
+ ret = gst_video_decoder_allocate_output_frame (decoder, frame);
if (ret != GST_FLOW_OK)
return ret;
@@ -856,15 +854,16 @@ handle_picture (GstMpeg2dec * mpeg2dec, const mpeg2_info_t * info,
if (GST_VIDEO_INFO_IS_INTERLACED (&mpeg2dec->decoded_info)) {
/* This implies SEQ_FLAG_PROGRESSIVE_SEQUENCE is not set */
if (picture->flags & PIC_FLAG_TOP_FIELD_FIRST) {
- GST_BUFFER_FLAG_SET (buffer, GST_VIDEO_BUFFER_FLAG_TFF);
+ GST_BUFFER_FLAG_SET (frame->output_buffer, GST_VIDEO_BUFFER_FLAG_TFF);
}
if (!(picture->flags & PIC_FLAG_PROGRESSIVE_FRAME)) {
- GST_BUFFER_FLAG_SET (buffer, GST_VIDEO_BUFFER_FLAG_INTERLACED);
+ GST_BUFFER_FLAG_SET (frame->output_buffer,
+ GST_VIDEO_BUFFER_FLAG_INTERLACED);
}
#if MPEG2_RELEASE >= MPEG2_VERSION(0,5,0)
/* repeat field introduced in 0.5.0 */
if (picture->flags & PIC_FLAG_REPEAT_FIRST_FIELD) {
- GST_BUFFER_FLAG_SET (buffer, GST_VIDEO_BUFFER_FLAG_RFF);
+ GST_BUFFER_FLAG_SET (frame->output_buffer, GST_VIDEO_BUFFER_FLAG_RFF);
}
#endif
}
@@ -887,7 +886,32 @@ handle_picture (GstMpeg2dec * mpeg2dec, const mpeg2_info_t * info,
(picture->flags & PIC_FLAG_COMPOSITE_DISPLAY ? "composite" : " "),
picture->nb_fields, GST_TIME_ARGS (frame->pts));
+ if (!gst_video_frame_map (&vframe, &mpeg2dec->decoded_info,
+ frame->output_buffer, GST_MAP_READ | GST_MAP_WRITE))
+ goto map_fail;
+
+ buf[0] = GST_VIDEO_FRAME_PLANE_DATA (&vframe, 0);
+ buf[1] = GST_VIDEO_FRAME_PLANE_DATA (&vframe, 1);
+ buf[2] = GST_VIDEO_FRAME_PLANE_DATA (&vframe, 2);
+
+ GST_DEBUG_OBJECT (mpeg2dec, "set_buf: %p %p %p, frame %i",
+ buf[0], buf[1], buf[2], frame->system_frame_number);
+
+ /* Note: We use a non-null 'id' value to make the distinction
+ * between the dummy buffers (which have an id of NULL) and the
+ * ones we did */
+ mpeg2_set_buf (mpeg2dec->decoder, buf,
+ GINT_TO_POINTER (frame->system_frame_number + 1));
+ gst_mpeg2dec_save_buffer (mpeg2dec, frame->system_frame_number, &vframe);
+
return ret;
+
+map_fail:
+ {
+ GST_ELEMENT_ERROR (mpeg2dec, RESOURCE, WRITE, ("Failed to map frame"),
+ (NULL));
+ return GST_FLOW_ERROR;
+ }
}
static GstFlowReturn
@@ -897,7 +921,6 @@ handle_slice (GstMpeg2dec * mpeg2dec, const mpeg2_info_t * info)
GstVideoCodecFrame *frame;
const mpeg2_picture_t *picture;
gboolean key_frame = FALSE;
- GstVideoCodecState *state;
GST_DEBUG_OBJECT (mpeg2dec,
"fbuf:%p display_picture:%p current_picture:%p fbuf->id:%d",
@@ -937,29 +960,30 @@ handle_slice (GstMpeg2dec * mpeg2dec, const mpeg2_info_t * info)
return ret;
}
- state = gst_video_decoder_get_output_state (GST_VIDEO_DECODER (mpeg2dec));
-
/* do cropping if the target region is smaller than the input one */
- if (mpeg2dec->need_cropping && !mpeg2dec->has_cropping) {
+ if (mpeg2dec->downstream_pool) {
GstVideoFrame *vframe;
if (gst_video_decoder_get_max_decode_time (GST_VIDEO_DECODER (mpeg2dec),
frame) < 0) {
GST_DEBUG_OBJECT (mpeg2dec, "dropping buffer crop, too late");
- ret = gst_video_decoder_drop_frame (GST_VIDEO_DECODER (mpeg2dec), frame);
- goto beach;
+ return gst_video_decoder_drop_frame (GST_VIDEO_DECODER (mpeg2dec), frame);
}
- GST_DEBUG_OBJECT (mpeg2dec, "cropping buffer");
+ GST_DEBUG_OBJECT (mpeg2dec, "Doing a crop copy of the decoded buffer");
+
vframe = gst_mpeg2dec_get_buffer (mpeg2dec, frame->system_frame_number);
g_assert (vframe != NULL);
ret = gst_mpeg2dec_crop_buffer (mpeg2dec, frame, vframe);
+
+ if (ret != GST_FLOW_OK) {
+ gst_video_decoder_drop_frame (GST_VIDEO_DECODER (mpeg2dec), frame);
+ return ret;
+ }
}
ret = gst_video_decoder_finish_frame (GST_VIDEO_DECODER (mpeg2dec), frame);
-beach:
- gst_video_codec_state_unref (state);
return ret;
no_frame:
diff --git a/ext/mpeg2dec/gstmpeg2dec.h b/ext/mpeg2dec/gstmpeg2dec.h
index 9623b722..f88459e4 100644
--- a/ext/mpeg2dec/gstmpeg2dec.h
+++ b/ext/mpeg2dec/gstmpeg2dec.h
@@ -71,8 +71,9 @@ struct _GstMpeg2dec {
/* video state */
GstVideoCodecState *input_state;
GstVideoInfo decoded_info;
- gboolean need_cropping;
- gboolean has_cropping;
+ GstVideoAlignment valign;
+ GstBufferPool * downstream_pool;
+ gboolean need_alignment;
guint8 *dummybuf[4];
};