That is, aligned to the basic type for audio and to 32 bytes for video.
Fixes crashes if the raw buffers are passed to SIMD processing functions.
https://bugzilla.gnome.org/show_bug.cgi?id=774428
static void gst_raw_audio_parse_get_units_per_second (GstRawBaseParse *
raw_base_parse, GstFormat format, GstRawBaseParseConfig config,
gsize * units_per_sec_n, gsize * units_per_sec_d);
+static gint gst_raw_audio_parse_get_alignment (GstRawBaseParse * raw_base_parse,
+ GstRawBaseParseConfig config);
static gboolean gst_raw_audio_parse_is_using_sink_caps (GstRawAudioParse *
raw_audio_parse);
GST_DEBUG_FUNCPTR (gst_raw_audio_parse_is_unit_format_supported);
rawbaseparse_class->get_units_per_second =
GST_DEBUG_FUNCPTR (gst_raw_audio_parse_get_units_per_second);
+ rawbaseparse_class->get_alignment =
+ GST_DEBUG_FUNCPTR (gst_raw_audio_parse_get_alignment);
g_object_class_install_property (object_class,
PROP_FORMAT,
return gst_raw_audio_parse_get_config_ptr (raw_audio_parse, config)->ready;
}
+static guint
+round_up_pow2 (guint n)
+{
+ n = n - 1;
+ n = n | (n >> 1);
+ n = n | (n >> 2);
+ n = n | (n >> 4);
+ n = n | (n >> 8);
+ n = n | (n >> 16);
+ return n + 1;
+}
+
+static gint
+gst_raw_audio_parse_get_alignment (GstRawBaseParse * raw_base_parse,
+ GstRawBaseParseConfig config)
+{
+ GstRawAudioParse *raw_audio_parse = GST_RAW_AUDIO_PARSE (raw_base_parse);
+ GstRawAudioParseConfig *config_ptr =
+ gst_raw_audio_parse_get_config_ptr (raw_audio_parse, config);
+ gint width;
+
+ if (config_ptr->format != GST_RAW_AUDIO_PARSE_FORMAT_PCM)
+ return 1;
+
+ width =
+ GST_AUDIO_FORMAT_INFO_WIDTH (gst_audio_format_get_info
+ (config_ptr->pcm_format)) / 8;
+ width = GST_ROUND_UP_8 (width);
+ width = round_up_pow2 (width);
+
+ return width;
+}
static gboolean
gst_raw_audio_parse_process (GstRawBaseParse * raw_base_parse,
return ret;
}
+static GstBuffer *
+gst_raw_base_parse_align_buffer (GstRawBaseParse * raw_base_parse,
+ gsize alignment, GstBuffer * buffer)
+{
+ GstMapInfo map;
+
+ gst_buffer_map (buffer, &map, GST_MAP_READ);
+
+ if (map.size < sizeof (guintptr)) {
+ gst_buffer_unmap (buffer, &map);
+ return buffer;
+ }
+
+ if (((guintptr) map.data) & (alignment - 1)) {
+ GstBuffer *new_buffer;
+ GstAllocationParams params = { 0, alignment - 1, 0, 0, };
+
+ new_buffer = gst_buffer_new_allocate (NULL,
+ gst_buffer_get_size (buffer), ¶ms);
+
+ /* Copy data "by hand", so ensure alignment is kept: */
+ gst_buffer_fill (new_buffer, 0, map.data, map.size);
+
+ gst_buffer_copy_into (new_buffer, buffer, GST_BUFFER_COPY_METADATA, 0, -1);
+ GST_DEBUG_OBJECT (raw_base_parse,
+ "We want output aligned on %" G_GSIZE_FORMAT ", reallocated",
+ alignment);
+
+ gst_buffer_unmap (buffer, &map);
+ gst_buffer_unref (buffer);
+
+ return new_buffer;
+ }
+
+ gst_buffer_unmap (buffer, &map);
+ return buffer;
+}
static GstFlowReturn
gst_raw_base_parse_handle_frame (GstBaseParse * parse,
guint64 buffer_duration;
GstFlowReturn flow_ret = GST_FLOW_OK;
GstEvent *new_caps_event = NULL;
+ gint alignment;
GstRawBaseParse *raw_base_parse = GST_RAW_BASE_PARSE (parse);
GstRawBaseParseClass *klass = GST_RAW_BASE_PARSE_GET_CLASS (parse);
frame->out_buffer = NULL;
}
+ if (klass->get_alignment
+ && (alignment =
+ klass->get_alignment (raw_base_parse,
+ GST_RAW_BASE_PARSE_CONFIG_CURRENT)) != 1) {
+ frame->out_buffer =
+ gst_raw_base_parse_align_buffer (raw_base_parse, alignment,
+ gst_buffer_ref (frame->buffer));
+ }
+
/* Set the duration of the output buffer, or if none exists, of
* the input buffer. Do this after the process() call, since in
* case out_buffer is set, the subclass has created a new buffer.
gint (*get_overhead_size) (GstRawBaseParse * raw_base_parse,
GstRawBaseParseConfig config);
+
+ gint (*get_alignment) (GstRawBaseParse * raw_base_parse,
+ GstRawBaseParseConfig config);
};
* gst_raw_video_parse_get_config_ptr (GstRawVideoParse * raw_video_parse,
GstRawBaseParseConfig config);
+static gint gst_raw_video_parse_get_alignment (GstRawBaseParse * raw_base_parse,
+ GstRawBaseParseConfig config);
+
static void gst_raw_video_parse_init_config (GstRawVideoParseConfig * config);
static void gst_raw_video_parse_update_info (GstRawVideoParseConfig * config);
-
-
static void
gst_raw_video_parse_class_init (GstRawVideoParseClass * klass)
{
GST_DEBUG_FUNCPTR (gst_raw_video_parse_get_units_per_second);
rawbaseparse_class->get_overhead_size =
GST_DEBUG_FUNCPTR (gst_raw_video_parse_get_overhead_size);
+ rawbaseparse_class->get_alignment =
+ GST_DEBUG_FUNCPTR (gst_raw_video_parse_get_alignment);
g_object_class_install_property (object_class,
PROP_WIDTH,
return gst_raw_video_parse_get_config_ptr (raw_video_parse, config)->ready;
}
+static gint
+gst_raw_video_parse_get_alignment (GstRawBaseParse * raw_base_parse,
+ GstRawBaseParseConfig config)
+{
+ return 32;
+}
static gboolean
gst_raw_video_parse_process (GstRawBaseParse * raw_base_parse,