Hi, I am trying to shaffle the input video stream as a sample for getting started with plugins and manipulating buffers.
I managed to get it to run, but the video does not to be shaffled at all.
Q: what is missing?
Hi, I am trying to shaffle the input video stream as a sample for getting started with plugins and manipulating buffers.
I managed to get it to run, but the video does not to be shaffled at all.
Q: what is missing?
static GstFlowReturn
gst_hello_chain(GstPad *pad, GstObject *parent, GstBuffer *buf)
{
GstHello *filter = GST_HELLO(parent);
// Increment and print custom ID
filter->custom_id++;
g_print("custom_id = %d\n", filter->custom_id);
// Add the incoming buffer to the queue (with a reference)
if (filter->buffer_count < 6) {
filter->buffer_queue[filter->buffer_count++] = gst_buffer_ref(buf);
} else {
g_print("Buffer queue overflow, resetting\n");
// Unref the buffers in the queue
for (int i = 0; i < filter->buffer_count; ++i) {
gst_buffer_unref(filter->buffer_queue[i]);
}
filter->buffer_count = 0;
// Add the new buffer
filter->buffer_queue[filter->buffer_count++] = gst_buffer_ref(buf);
}
// Emit when 6 buffers are queued
if (filter->buffer_count == 6) {
const gint emit_order[6] = {0, 3, 1, 4, 2, 5}; // Custom order: 1 4 2 5 3 6
// Deep copy the last 3 emitted buffers to new locations
GstBuffer *new_queue[3];
new_queue[0] = gst_buffer_ref(filter->buffer_queue[3]);
new_queue[1] = gst_buffer_ref(filter->buffer_queue[4]);
new_queue[2] = gst_buffer_ref(filter->buffer_queue[5]);
// Push buffers in the specified custom order
for (int i = 0; i < 6; ++i) {
GstBuffer *out_buf = filter->buffer_queue[emit_order[i]];
if (!GST_IS_BUFFER(out_buf)) {
g_printerr("Invalid buffer at emit_order[%d]!\n", i);
// Clean up and exit with error
for (int j = i + 1; j < 6; ++j) {
if (GST_IS_BUFFER(filter->buffer_queue[emit_order[j]]))
gst_buffer_unref(filter->buffer_queue[emit_order[j]]);
}
// Unref the deep copied buffers
for (int k = 0; k < 3; ++k) {
if (new_queue[k]) gst_buffer_unref(new_queue[k]);
}
filter->buffer_count = 0;
return GST_FLOW_ERROR;
}
// Push the buffer downstream
GstFlowReturn ret = gst_pad_push(filter->srcpad, out_buf);
if (ret != GST_FLOW_OK) {
g_printerr("Failed to push buffer %d: %s\n", emit_order[i], gst_flow_get_name(ret));
// Unref remaining buffers on error
for (int j = i + 1; j < 6; ++j) {
if (GST_IS_BUFFER(filter->buffer_queue[emit_order[j]]))
gst_buffer_unref(filter->buffer_queue[emit_order[j]]);
}
// Clean up new_queue on error
for (int k = 0; k < 3; ++k) {
if (new_queue[k]) gst_buffer_unref(new_queue[k]);
}
filter->buffer_count = 0;
return ret;
}
}
// Unref all original buffers after successful push
for (int i = 0; i < 3; ++i) {
gst_buffer_unref(filter->buffer_queue[i]);
}
// Save the deep-copied buffers at the front of the queue
filter->buffer_queue[0] = new_queue[0];
filter->buffer_queue[1] = new_queue[1];
filter->buffer_queue[2] = new_queue[2];
filter->buffer_count = 3;
}
// Unref the incoming buffer if it is not being used anymore
// Since it is referenced above when added to the queue, no need to unref immediately
// If the buffer was just added to the queue (above), we don't unref here.
return GST_FLOW_OK;
}
Might be related: