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