Hi: I went through all steps Klen has done and stuck in the end, help is needed...
Basically I try to do the similar thing as Klen, port maemo Camera example to qt4-maemo5-gles1 version example Hellogl_es (I choose to use gles1 version for my later project purpose)type of GLWidget, to draw video overy the GLWidget, I create the gstreamer pipe line in a CameraN900.cc in initialize_pipe()function (which is called in CameraN900:CameraN900()) as:
Camera_src ! csp_filter ! app_sink
and I only require "video/x-raw-rgb" caps when connect camera_src and csp_filter, unlike Klen case, it seems request raw-rgb work in my case (this is in fact the maemo example_camera.c did)
unlike the camera.cpp in qtcartonizer I set:
gst_element_set_state(m_pipeline, GST_STATE_PLAYING); //the qtcartonizer set it to GST_STATE_NULL
///////////////The CameraN900:initialize_pipe() code//////////////////////////////////////
Code:
---------
bool CameraN900::initialize_pipeline()
{
GstElement *camera_src, *app_sink;
GstElement *image_queue, *image_filter;
GstElement *csp_filter;
GstCaps *caps;
GstBus *bus;
gst_init( NULL, NULL);
m_pipeline = gst_pipeline_new("test-camera");
bus = gst_pipeline_get_bus(GST_PIPELINE(m_pipeline));
//gst_bus_add_watch(bus, (GstBusFunc)bus_callback, &m_appData);
gst_object_unref(GST_OBJECT(bus));
camera_src = gst_element_factory_make(VIDEO_SRC, "camera_src");
csp_filter = gst_element_factory_make("ffmpegcolorspace", "csp_filter");
app_sink = gst_element_factory_make("appsink", "app_sink");
if(!(m_pipeline && camera_src && csp_filter && app_sink))
{
qDebug() << "Couldn't create pipeline elements";
return FALSE;
}
m_appsink = GST_APP_SINK(app_sink);
g_object_set(G_OBJECT(app_sink),
"signal-handoffs", TRUE, NULL);
g_object_set (G_OBJECT (app_sink), "emit-signals", TRUE, NULL);
g_signal_connect (app_sink, "new-buffer", G_CALLBACK (new_buffer_callback), NULL);
gst_bin_add_many(GST_BIN(m_pipeline), camera_src, csp_filter, app_sink, NULL);
caps = gst_caps_new_simple("video/x-raw-rgb",
"width", G_TYPE_INT, 320,
"height", G_TYPE_INT, 240,
NULL);
if(!gst_element_link_filtered(camera_src, csp_filter, caps))
{
qDebug () << "capability not supported for link camera->csp-filter";
return FALSE;
}
gst_caps_unref(caps);
if(!gst_element_link_many(csp_filter,app_sink, NULL))
{
qDebug () << "gst pipeline init fail";
return FALSE;
}
gst_element_set_state(m_pipeline, GST_STATE_PLAYING); //GST_STATE_NULL);
qDebug () << "gst init N900 ok";
return TRUE;
}
---------
//////////////////////////////////////////////////////////
hoping the camera will play from the very start. I then connect the CameraN900 with the original glwidget through GLWidget::initializeGL() by adding the following line in the end (class GLWidget has a member CameraN900 *camn900; ):
The initializeGL function for GLWidget
GLWidget::initializeGL{
...
camn900 = new CameraN900(); // start to play at the end, in play mode
}
The main drawing function paintGL in glwidget.cc looks
Code:
---------
void GLWidget :: paintGL()
{
QPainter painter;
painter.begin(this);
glEnable(GL_TEXTURE_2D);
camn900->refresh_buffer(); //manually call appsink to fatch for data in the buffer
unsigned char* data=(unsigned char *) GST_BUFFER_DATA (camn900->buffer);
glBindTexture(GL_TEXTURE_2D, m_uiTexture);
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, 320,240, 0, GL_RGB, GL_UNSIGNED_BYTE, data );
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
paintTextured();//paint the video as background
painter.end();
swapBuffers();
}
---------
in CameraN900.cc (adapted from qtcartonize's camera.cpp) I have
Code:
---------
static GstBuffer* gstbuffer;
void CameraN900::refresh_buffer(){
if(m_appsink!=NULL){
qDebug () << " in refresh_buffer(), do gst_app_sink_pull_buffer()...";
gstbuffer = gst_app_sink_pull_buffer(m_appsink); //buffer us a static GstBuffer *
buffer = (unsigned char *) GST_BUFFER_DATA (gstbuffer);
qDebug () << "refresh buffer done";
// buffer is a class member of CameraN900
}
}
---------
I have done things like in mainwindow.cc
Code:
---------
...
glwidget->setFixedWidth(320);
glwidget->setFixedHeight(240);
...
---------
to make sure glwidget has same size as video frame.
Now the application stucks at gst_app_sink_pull_buffer call without moving, seems pull buffer is waiting for a never ready buffer to come, I'm lost here what to do, could anyone please shed me some light? I feel I'm very close to a happy end...
BR/ zr_yao

Reply With Quote


