AW: Using appsrc in pull mode

Thornton, Keith keith.thornton at zeiss.com
Mon Feb 26 13:37:37 UTC 2018


Hi, when you have read the last part of your file, you have to push an eos to the pipeline. (gst_app_src_end_of_stream(appsrc);
You also need a bus handler to let you know when the filesink has received the eos. Only then can you shutdown your pipeline.
Why aren't you just using filesrc :-)

-----Ursprüngliche Nachricht-----
Von: gstreamer-devel [mailto:gstreamer-devel-bounces at lists.freedesktop.org] Im Auftrag von Nostalgia
Gesendet: Montag, 26. Februar 2018 13:58
An: gstreamer-devel at lists.freedesktop.org
Betreff: Using appsrc in pull mode

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/
_______________________________________________
gstreamer-devel mailing list
gstreamer-devel at lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel


More information about the gstreamer-devel mailing list