How can I get to know whether a element get my data or not

Ugly Face xuchangxue365812 at 126.com
Mon Mar 3 06:56:02 PST 2014


Thank again for your kindly reply.

1. I final goal is to transffer video captured and coded by android devices.
In this project , I need to use appsrc to get data coded by MediaRecorder .
The data is actually mp4 file . As a new bee to gstreamer , I find it hard
to control element appsrc .  So I first try to use appsrc in this case . I
first recorded mp4 video with android device . And from mp4 file , I get NAL
which should be pushed into appsrc. with an simple pipeline ,I try to check
if appsrc works properly.

2. I do not know what to share . Maybe the code?
test.c <http://gstreamer-devel.966125.n4.nabble.com/file/n4665686/test.c>  

#include<stdio.h>
#include <gst/gst.h>
/*
gst-launch-0.10 filesrc location=a.mp4 ! qtdemux name=demux demux.video_00 !
ffdec_h264 ! xvimagesink
*/
#define STREAMFORMAT "byte-stream"
#define ALIGNMENT  "nal"
typedef struct _CustomData{
	FILE *fp;
	GstElement *appsrc;
	GstElement *pipeline;
	guint sourceid;        /* To control the GSource */
  	GMainLoop *loop; 
  	int framerate;
	int width;
	int height;
}CustomData;

char codec[27];

void init_file_stream(CustomData *data)
{
	char i=0;
	char temp[3];
	while(fscanf(data->fp,"%c",&(temp[0]))>0)
	{
		if('a' == temp[0])
		{
			fread(temp,1,3,data->fp);
			printf("get an a\n");
			if(temp[0]=='v'&&temp[1]=='c'&&temp[2]=='C')
			{
				printf("flag avcC occur!\n");
				fread(codec, 1,27,data->fp);
				printf("begin =======================>\n");
				for(;i<27;i++)
				{
					printf("%d", (int)(codec[i]));
				}
				printf("end<=========================\n");
				break;
			}
		}
	}
	
	while(fscanf(data->fp,"%c",&(temp[0]))>0)
	{
		if('m' == temp[0])
		{
			fread(temp,1,3,data->fp);
			if(temp[0]=='d'&&temp[1]=='a'&&temp[2]=='t')
			{
				printf("flag mdat occur!\n");
				break;
			}
		}
	}
}

static gboolean push_data(CustomData *data)
{
	static unsigned long long frame_num = 0;
	int data_len = 0;
	GstBuffer *buffer;
	GstBuffer *c;
	GstCaps *caps;
	GstFlowReturn ret;
	char header[4];
	if(fread(header,1,4,data->fp) == 0)
	{
		printf("end or error!\n");
		return 0;
	}
	data_len = header[3]&0xFF | (header[2]&0xFF)<<8 | (header[1]&0xFF)<<16 |
(header[0]&0xFF)<<24;
	buffer = gst_buffer_new_and_alloc(data_len);
	GST_BUFFER_TIMESTAMP (buffer) = (GstClockTime) gst_util_uint64_scale
(frame_num, GST_SECOND, data->framerate);
	GST_BUFFER_DURATION (buffer) =  (GstClockTime) gst_util_uint64_scale (1,
GST_SECOND, data->framerate);
	frame_num = frame_num + 1;
	if(fread(GST_BUFFER_DATA(buffer), 1,data_len,data->fp) == 0)
	{
		printf("error\n");
		return 0;
	}
	c = gst_buffer_new_and_alloc(27);
	memcpy(GST_BUFFER_DATA(c), codec, 27);
	caps = gst_caps_new_simple ("video/x-h264",
				"codec_data", GST_TYPE_BUFFER, c,
    			/*"stream-format", G_TYPE_STRING, STREAMFORMAT,
    			"alignment", G_TYPE_STRING, ALIGNMENT,
    			"framerate", GST_TYPE_FRACTION, data->framerate, 1,
    			"width", G_TYPE_INT, data->width,
    			"height", G_TYPE_INT, data->height,*/
    			NULL);
    gst_buffer_set_caps(buffer, caps);
	g_signal_emit_by_name (data->appsrc, "push-buffer", buffer, &ret);
	gst_buffer_unref(buffer);
	if (ret != GST_FLOW_OK) 
	{
		/* We got some error, stop sending data */
		printf("error occur!\n");
		return FALSE;
  	}
  	printf("pushing frame %d ok! \n", frame_num);
  	return TRUE;
}

static void start_feed (GstElement *source, guint size, CustomData *data) 
{
  if (data->sourceid == 0) 
  {
    printf ("Start feeding\n");
    data->sourceid = g_idle_add ((GSourceFunc) push_data, data);
  }
}
   
/* This callback triggers when appsrc has enough data and we can stop
sending.
 * We remove the idle handler from the mainloop */
static void stop_feed (GstElement *source, CustomData *data) 
{
  if (data->sourceid != 0) {
    printf ("Stop feeding\n");
    g_source_remove (data->sourceid);
    data->sourceid = 0;
  }
}

void init_custom_data(CustomData *data)
{
	data->sourceid = 0;
	data->framerate = 30;
	data->width = 320;
	data->height = 240;
	data->fp = fopen("a.mp4","r");
}

static void error_cb (GstBus *bus, GstMessage *msg, CustomData *data) {
printf("here===========================error\n");
  GError *err;
  gchar *debug_info;
   
  /* Print error details on the screen */
  gst_message_parse_error (msg, &err, &debug_info);
  g_printerr ("Error received from element %s: %s\n", GST_OBJECT_NAME
(msg->src), err->message);
  g_printerr ("Debugging information: %s\n", debug_info ? debug_info :
"none");
  g_clear_error (&err);
  g_free (debug_info);
   
  g_main_loop_quit (data->loop);
}
int main(int argc, char* argv[])
{
	gboolean			res;
	GstPadLinkReturn	linkret;
	GstCaps	   *caps;
	GstBus *bus;
	GstBuffer *c;

	GstElement *parser;
	GstElement *decoder;
	GstElement *videosink;
	
	CustomData *data;
	data = (CustomData *)malloc(sizeof(CustomData));
	gst_debug_set_default_threshold(2);
	init_custom_data(data);
	init_file_stream(data);

	gst_init(&argc, &argv);
	data->pipeline 	= gst_pipeline_new(NULL);
	data->appsrc = gst_element_factory_make("appsrc", "appsrc");
	parser = gst_element_factory_make("h264parse", "parser");
	decoder = gst_element_factory_make("ffdec_h264", "decoder");
	videosink = gst_element_factory_make("xvimagesink", "videosink");
	//videosink = gst_element_factory_make("autovideosink", "videosink");
	
	if(!(data->appsrc) || !parser || !decoder || !videosink)
	{
		printf("not all element can be create!\n");
	}
	
	c = gst_buffer_new_and_alloc(27);
	memcpy(GST_BUFFER_DATA(c), codec, 27);
	caps = gst_caps_new_simple ("video/x-h264",
				"codec_data", GST_TYPE_BUFFER, c,
				"stream-format", G_TYPE_STRING, STREAMFORMAT,
    			"alignment", G_TYPE_STRING, ALIGNMENT,
    			/*"framerate", GST_TYPE_FRACTION, data->framerate, 1,
    			"width", G_TYPE_INT, data->width,
    			"height", G_TYPE_INT, data->height,*/
    			NULL);
    			
    g_object_set(data->appsrc, "is-live", TRUE, "block",FALSE,"caps", caps,
NULL);
    //gst_app_src_set_caps(data->appsrc, caps);
    g_signal_connect (data->appsrc, "need-data", G_CALLBACK (start_feed),
data);
  	g_signal_connect (data->appsrc, "enough-data", G_CALLBACK (stop_feed),
data);
	
	gst_bin_add_many(GST_BIN(data->pipeline), data->appsrc, parser, decoder,
videosink, NULL);
	
	/*res=gst_element_link(data->appsrc, parser);
	g_assert(res);
	res=gst_element_link(parser, decoder);
	g_assert(res);
	res=gst_element_link(decoder, videosink);
	g_assert(res);*/
	res = gst_element_link_many(data->appsrc, parser, decoder, videosink,
NULL);
	g_assert(res);
	
	bus = gst_element_get_bus (data->pipeline);
  	gst_bus_add_signal_watch (bus);
  	
  	g_signal_connect (G_OBJECT (bus), "message::error", (GCallback)error_cb,
&data);
  	gst_object_unref (bus);
	
	printf ("starting pipeline\n");
  	gst_element_set_state (data->pipeline, GST_STATE_PLAYING);

	data->loop = g_main_loop_new (NULL, FALSE);
	g_main_loop_run (data->loop);

  	gst_element_set_state (data->pipeline, GST_STATE_NULL);
  	gst_object_unref(GST_OBJECT(data->pipeline));
	
	fclose(data->fp);
	free(data);
	return(0);
}

what puzzles me most is that the program works improperly without any error.
It dose not provide me any hints.

I will try your suggestion about qtdemux .

Again , Thank you .

Gorge Y.



--
View this message in context: http://gstreamer-devel.966125.n4.nabble.com/How-can-I-get-to-know-whether-a-element-get-my-data-or-not-tp4665599p4665686.html
Sent from the GStreamer-devel mailing list archive at Nabble.com.


More information about the gstreamer-devel mailing list