Using appsrc in pull mode
Nostalgia
akra.hanine at gmail.com
Mon Feb 26 12:58:26 UTC 2018
Hi ,
I am writing a code that read an yuv file, encode it and save the results of
encoding in a new file using this pipeline :
appsrc -> encoder -> capsfilter -> filesink
So I use appsrc to push data from the file to the pipeline, knowing the size
of the file I then use appsrc in pull mode. My code runs correctly and I
obtain the right output but the problem that it doesn't return to the main
function when finishing reading the file :
//g++ -Wall -std=c++11 PullMode.cpp -o pm $(pkg-config --cflags --libs
gstreamer-app-1.0) -ldl
#include <gst/gst.h>
#include <gst/app/gstappsrc.h>
#include <cstring>
#include <iostream>
#include <unistd.h>
using namespace std;
#define WIDTH 640
#define HEIGHT 360
#define FORMAT "I420"
#define FRAME_RATE 25
#define FRAME_TIME 40000000
#define FRAME_SIZE ((WIDTH*HEIGHT*3) >> 1 )
#define FRAME_NUMBER(x) (int)(x/FRAME_SIZE)
#define Input_FILE
"/media/ubuntu/6634-3132/Hanine/InitialFiles/Basketball.yuv"
#define Output_FILE
"/media/ubuntu/6634-3132/Hanine/Basketball_appsource_pull.264"
static GstClockTime timestamp = 0;
static FILE *yuv_file;
static int num_buffers_to_send;
static int nbuffers = 0;
typedef struct _CustomData {
GstElement *pipeline, *source, *encoder, *filter, *fsink;
GMainLoop *loop;
} CustomData;
static void cb_need_data (GstElement *appsrc,
CustomData * data) {
char* ptr;
GstBuffer *buffer;
GstFlowReturn ret;
ptr = (char*)malloc (FRAME_SIZE);
g_assert(ptr != NULL);
fread(ptr, 1 , FRAME_SIZE, yuv_file);
buffer = gst_buffer_new_wrapped (ptr, FRAME_SIZE);
buffer->pts = timestamp;
buffer->dts = timestamp;
buffer->duration = FRAME_TIME;
g_signal_emit_by_name (appsrc, "push-buffer", buffer, &ret);
gst_buffer_unref(buffer);
timestamp += FRAME_TIME;
nbuffers +=1;
if (ret != GST_FLOW_OK) {
g_main_loop_quit (data->loop);
printf(" Error in pushing data to appsrc\n");
}
}
int main (int argc, char *argv[]) {
CustomData data;
GstCaps *input_enc_caps, *output_enc_caps;
GstStateChangeReturn state_ret;
/* Get a pointer to the YUV input file*/
yuv_file = fopen(Input_FILE, "rb");
g_assert(yuv_file != NULL);
/* Get the size of the input file*/
fseek (yuv_file , 0 , SEEK_END);
long int size = ftell (yuv_file);
rewind (yuv_file);
num_buffers_to_send = FRAME_NUMBER(size);
/* Initialize cumstom data structure */
memset (&data, 0, sizeof (data));
/* Initialize GStreamer and create the mainloop */
gst_init (&argc, &argv);
data.loop = g_main_loop_new (NULL, FALSE);
/* Create the elements */
data.source = gst_element_factory_make ("appsrc", "myapp_source");
data.encoder = gst_element_factory_make ("omxh264enc", "myapp_encoder");
data.filter = gst_element_factory_make ("capsfilter", "myapp_filter");
data.fsink = gst_element_factory_make ("filesink", "myapp_sink");
/* Create the empty pipeline */
data.pipeline = gst_pipeline_new ("myapp_pipeline");
if (!data.pipeline || !data.source || !data.encoder || !data.filter
|| !data.fsink)
{
g_printerr ("Not all elements could be created.\n");
return -1;
}
/* Configure source, filter and fsink */
input_enc_caps = gst_caps_new_simple ("video/x-raw",
"format", G_TYPE_STRING, FORMAT,
"width", G_TYPE_INT, WIDTH,
"height", G_TYPE_INT, HEIGHT,
"framerate", GST_TYPE_FRACTION, FRAME_RATE, 1, NULL);
output_enc_caps = gst_caps_new_simple ("video/x-h264",
"stream-format", G_TYPE_STRING, "byte-stream", NULL);
g_object_set (G_OBJECT (data.source), "caps", input_enc_caps,
"stream-type", 0,
"size", size,
"num-buffers", num_buffers_to_send,
NULL);
g_signal_connect (data.source, "need-data", G_CALLBACK (cb_need_data),
&data);
g_object_set (G_OBJECT (data.filter), "caps", output_enc_caps, NULL);
g_object_set (G_OBJECT (data.fsink), "location", Output_FILE, NULL);
gst_caps_unref (input_enc_caps);
gst_caps_unref (output_enc_caps);
/* Link all elements that can be automatically linked*/
gst_bin_add_many (GST_BIN (data.pipeline), data.source, data.encoder,
data.filter, data.fsink, NULL);
if ((gst_element_link_many (data.source, data.encoder, data.filter,
data.fsink, NULL)) != TRUE )
{
g_printerr ("Elements could not be linked.\n");
gst_object_unref (data.pipeline);
return -1;
}
/* Start playing the pipeline */
state_ret = gst_element_set_state (data.pipeline, GST_STATE_PLAYING);
if (state_ret == GST_STATE_CHANGE_FAILURE) {
g_printerr ("Unable to set the pipeline to the playing state.\n");
gst_object_unref (data.pipeline);
return -1;
}
/* Set the MainLoop to run */
g_main_loop_run (data.loop);
//gst_app_src_end_of_stream((GstAppSrc*) data.source);
/* Clean up */
fclose (yuv_file);
gst_element_set_state (data.pipeline, GST_STATE_NULL);
gst_object_unref (GST_OBJECT (data.pipeline));
g_main_loop_unref (data.loop);
printf("\n End of Stream \n");
return 0;
}
Can someone help me please to know the issues.
Thanks in advance.
--
Sent from: http://gstreamer-devel.966125.n4.nabble.com/
More information about the gstreamer-devel
mailing list