Problem writing mp4 player with appsrc
jyoti kulkarni
jyotimk029 at gmail.com
Wed Jun 12 01:29:09 PDT 2013
Hello All,
I have written a program to play a mp4 file with aapsrc, program compiles
fine but i dont see any display and i get following output on the console:
/My_programs$ gcc mp4_stream.c -o mp4_stream -lX11 `pkg-config --cflags
--libs gstreamer-0.10 gstreamer-app-0.10` -lgstinterfaces-0.10
/My_programs$ ./mp4_stream test.mp4
** (process:14249): WARNING **: map xwindow
set state returned 2
got message stream-status
got message stream-status
start feeding
stop feeding
pad added
pad name video/x-h264
pad added
pad name video/x-h264
got message tag
pad added
pad name audio/mpeg
pad added
pad name audio/mpeg
got message tag
got message tag
Error Internal data flow error.
set state null returned 1
X Error of failed request: BadWindow (invalid Window parameter)
Major opcode of failed request: 4 (X_DestroyWindow)
Resource id in failed request: 0x3600002
Serial number of failed request: 15
Current serial number in output stream: 17
/My_programs$
Following is the code, and iam using gstreamer 0.1
I have tested the pipeline manually with gst-launch and it works fine, with
following command:
gst-launch-0.10 filesrc location=test.mp4 ! qtdemux name=demux.audio_00 !
queue ! faad ! alsasink demux.video_00 ! queue ! ffdec_h264 ! autovideosink
PLEASE HELP...WITH FOLLOWING CODE:
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <stdio.h>
#include <unistd.h> // sleep()
#include <stdbool.h>
#include <gst/gst.h>
#include <gst/app/gstappsrc.h>
#include <gst/app/gstappbuffer.h>
#include <gst/interfaces/xoverlay.h>
#define BUFF_SIZE (640*480*3)//(1024)
#define BORDER_WIDTH 2
#define DEBUG printf
typedef unsigned int uint32;
typedef unsigned char uint8;
typedef struct {
GstPipeline *pipeline;
GstAppSrc *src;
GstElement *sink;
GstElement *video_decoder;
GstElement *audio_decoder;
GstElement *audiosink;
GstElement *queue1;
GstElement *queue2;
//GstElement *ffmpeg;
GstElement *videosink;
GstElement *demuxer;
GMainLoop *loop;
guint sourceid;
FILE *file;
} gst_app_t;
static gst_app_t gst_app;
static Window child_window = 0;
static Window window = 0;
static gboolean read_data(gst_app_t *app)
{
GstBuffer *buffer;
guint8 *ptr;
gint size;
GstFlowReturn ret;
ptr = g_malloc(BUFF_SIZE);
g_assert(ptr);
size = fread(ptr, 1, BUFF_SIZE, app->file);
if(size == 0){
ret = gst_app_src_end_of_stream(app->src);
DEBUG("eos returned %d at %d\n", ret, __LINE__);
return FALSE;
}
buffer = gst_buffer_new();
GST_BUFFER_MALLOCDATA(buffer) = ptr;
GST_BUFFER_SIZE(buffer) = size;
GST_BUFFER_DATA(buffer) = GST_BUFFER_MALLOCDATA(buffer);
ret = gst_app_src_push_buffer(app->src, buffer);
if(ret != GST_FLOW_OK){
DEBUG("push buffer returned %d for %d bytes \n", ret, size);
return FALSE;
}
if(size != BUFF_SIZE){
ret = gst_app_src_end_of_stream(app->src);
DEBUG("eos returned %d at %d\n", ret, __LINE__);
return FALSE;
}
return TRUE;
}
static void start_feed (GstElement * pipeline, guint size, gst_app_t *app)
{
if (app->sourceid == 0) {
DEBUG ("start feeding\n");
app->sourceid = g_idle_add ((GSourceFunc) read_data, app);
}
}
static void stop_feed (GstElement * pipeline, gst_app_t *app)
{
if (app->sourceid != 0) {
DEBUG ("stop feeding\n");
g_source_remove (app->sourceid);
app->sourceid = 0;
}
}
static void on_pad_added(GstElement *element, GstPad *pad)
{
GstCaps *caps;
GstStructure *str;
gchar *name;
//GstPad *ffmpegsink;
GstPadLinkReturn ret;
DEBUG("pad added\n");
caps = gst_pad_get_caps(pad);
str = gst_caps_get_structure(caps, 0);
g_assert(str);
name = (gchar*)gst_structure_get_name(str);
DEBUG("pad name %s\n", name);
gst_caps_unref(caps);
}
static gboolean bus_callback(GstBus *bus, GstMessage *message, gpointer
*ptr)
{
gst_app_t *app = (gst_app_t*)ptr;
switch(GST_MESSAGE_TYPE(message))
{
case GST_MESSAGE_ELEMENT: {
gst_x_overlay_set_window_handle (GST_X_OVERLAY
(GST_MESSAGE_SRC(message)), child_window);
}
break;
case GST_MESSAGE_ERROR:
{
gchar *debug;
GError *err;
gst_message_parse_error(message, &err, &debug);
DEBUG("Error %s\n", err->message);
g_error_free(err);
g_free(debug);
g_main_loop_quit(app->loop);
}
break;
case GST_MESSAGE_WARNING:
{
gchar *debug;
GError *err;
gchar *name;
gst_message_parse_warning(message, &err, &debug);
DEBUG("Warning %s\nDebug %s\n", err->message, debug);
name = GST_MESSAGE_SRC_NAME(message);
DEBUG("Name of src %s\n", name ? name : "nil");
g_error_free(err);
g_free(debug);
}
break;
case GST_MESSAGE_EOS:
DEBUG("End of stream\n");
g_main_loop_quit(app->loop);
break;
case GST_MESSAGE_STATE_CHANGED:
break;
default:
DEBUG("got message %s\n", \
gst_message_type_get_name (GST_MESSAGE_TYPE (message)));
break;
}
return TRUE;
}
static gboolean terminate_playback (GstElement * loop)
{
DEBUG ("Terminating playback\n");
g_main_loop_quit ((GMainLoop *)loop);
return FALSE;
}
int gstreamer_init(int argc, char *argv[])
{
gst_app_t *app = &gst_app;
GstBus *bus;
GstStateChangeReturn state_ret;
app->file = fopen(argv[1], "r");
g_assert(app->file);
/* initialization */
gst_init((int)0, NULL);
app->loop = g_main_loop_new(NULL, FALSE);
/* create elements */
app->pipeline = (GstPipeline *)gst_pipeline_new("my_pipeline");
app->src = (GstAppSrc *)gst_element_factory_make("appsrc", "myappsrc");
app->video_decoder = gst_element_factory_make("ffdec_h264",
"myvideodecoder");
app->videosink = gst_element_factory_make("autovideosink",
"myvideosink");
app->audiosink = gst_element_factory_make("alsasink", "myaudiosink");
app->demuxer = gst_element_factory_make("qtdemux","mydemuxer");
app->audio_decoder=gst_element_factory_make("faad", "myaudiodecoder");
app->queue1=gst_element_factory_make("queue", "myqueue1");
app->queue2=gst_element_factory_make("queue", "myqueue2");
if (!app->videosink) {
DEBUG ("output could not be found - check your install\n");
}
g_assert(app->src);
g_assert(app->video_decoder);
g_assert(app->audio_decoder);
g_assert(app->videosink);
g_assert(app->audiosink);
g_assert(app->demuxer);
g_assert(app->queue1);
g_assert(app->queue2);
bus = gst_pipeline_get_bus(GST_PIPELINE(app->pipeline));
gst_bus_add_watch(bus, (GstBusFunc)bus_callback, app);
gst_object_unref(bus);
//gst_app_src_set_emit_signals(app->src, true);
g_signal_connect(app->src, "need-data", G_CALLBACK(start_feed), app);
g_signal_connect(app->src, "enough-data", G_CALLBACK(stop_feed), app);
gst_bin_add_many (GST_BIN (app->pipeline), (GstElement
*)app->src,app->demuxer,app->queue1,
app->audio_decoder,app->audiosink,app->queue2,app->video_decoder,app->videosink,
NULL);
/* link everything together */
if (!gst_element_link((GstElement *)app->src,(GstElement
*)app->demuxer)) {
DEBUG ("Failed to link source and demuxer !\n");
return -1;
}
/*if (!gst_element_link((GstElement *)app->demuxer, (GstElement
*)app->queue1)) {
DEBUG ("Failed to link demuxer and queue1 here!\n");
return -1;
}*/
if (!gst_element_link((GstElement *)app->audio_decoder, (GstElement
*)app->audiosink)) {
DEBUG ("Failed to link audio decoder and audio sink !\n");
return -1;
}
/*if (!gst_element_link((GstElement *)app->queue2, (GstElement
*)app->video_decoder)) {
DEBUG ("Failed to link queue2 and video_decoder !\n");
return -1;
}*/
if (!gst_element_link((GstElement *)app->video_decoder, (GstElement
*)app->videosink)) {
DEBUG ("Failed to link video decoder and video sink !\n");
return -1;
}
g_signal_connect(app->demuxer, "pad-added",G_CALLBACK(on_pad_added),
app->audio_decoder);
g_signal_connect(app->demuxer, "pad-added",G_CALLBACK(on_pad_added),
app->video_decoder);
state_ret = gst_element_set_state((GstElement *)app->pipeline,
GST_STATE_PLAYING);
if (state_ret == GST_STATE_CHANGE_FAILURE) {
DEBUG("Failed to start up pipeline!\n");
return 1;
}
DEBUG("set state returned %d\n", state_ret);
//g_timeout_add (15000, (GSourceFunc) terminate_playback, app->loop);
g_main_loop_run(app->loop);
state_ret = gst_element_set_state((GstElement *)app->pipeline,
GST_STATE_NULL);
DEBUG("set state null returned %d\n", state_ret);
gst_object_unref(app->pipeline);
return 1;
}
int main(int argc, char *argv[])
{
Display *disp;
Window root;
long fgcolor, bgcolor;
GC gc;
XGCValues gc_val;
XEvent event;
char *msg = "Hello, World!";
int screen;
disp = XOpenDisplay(NULL);
if (disp == NULL) {
fprintf(stderr, "Cannot open display\n");
exit(1);
}
screen = DefaultScreen(disp);
root = RootWindow(disp, screen);
fgcolor = BlackPixel(disp, screen);
bgcolor = WhitePixel(disp, screen);
window = XCreateSimpleWindow(disp, root, 100, 100, 1000, 840, 1,
fgcolor, bgcolor);
child_window = XCreateSimpleWindow(disp, window, 100, 100, 800, 600, 1,
fgcolor, bgcolor);
gc_val.foreground = fgcolor;
gc_val.background = bgcolor;
gc = XCreateGC(disp, child_window, GCForeground|GCBackground, &gc_val);
XSelectInput(disp, child_window, ExposureMask | KeyPressMask);
g_warning("map xwindow");
//XMapWindow(disp, window);
XMapWindow(disp, window);
XMapWindow(disp, child_window);
XSync(disp, FALSE);
//XDrawLine (disp, window, gc, 0, 0, 1000, 800);
//XDrawLine (disp, child_window, gc, 0, 0, 800, 600);
gstreamer_init(argc, argv);
XDestroyWindow( disp, window );
XDestroyWindow( disp, child_window );
XCloseDisplay( disp );
return 0;
}
Thanks in Advance
Jyoti
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freedesktop.org/archives/gstreamer-devel/attachments/20130612/e156b0c8/attachment.html>
More information about the gstreamer-devel
mailing list