00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include <AR/config.h>
00012 #include <AR/ar.h>
00013 #include <AR/video.h>
00014
00015
00016 #include <glib.h>
00017
00018
00019 #include <gst/gst.h>
00020
00021
00022 #include <string.h>
00023
00024
00025 #define GSTREAMER_TEST_LAUNCH_CFG "videotestsrc ! capsfilter caps=video/x-raw-rgb,bpp=24 ! identity name=artoolkit ! fakesink"
00026
00027
00028 struct _AR2VideoParamT {
00029
00030
00031 int width, height;
00032
00033
00034 ARUint8 *videoBuffer;
00035
00036
00037 GstElement *pipeline;
00038
00039
00040 GstElement *probe;
00041
00042 };
00043
00044
00045 static AR2VideoParamT *gVid = NULL;
00046
00047 static gboolean
00048 cb_have_data (GstPad *pad,
00049 GstBuffer *buffer,
00050 gpointer u_data)
00051 {
00052
00053 const GstCaps *caps;
00054 GstStructure *str;
00055
00056 gint width,height;
00057 gdouble rate;
00058
00059 AR2VideoParamT *vid = (AR2VideoParamT*)u_data;
00060
00061 if (vid == NULL) return FALSE;
00062
00063
00064
00065 if (vid->videoBuffer == NULL && buffer)
00066 {
00067 g_print("libARvideo error! Buffer not allocated\n");
00068 }
00069
00070 if (vid->videoBuffer)
00071 {
00072 memcpy(vid->videoBuffer, buffer->data, buffer->size);
00073 }
00074
00075 return TRUE;
00076 }
00077
00078
00079 static
00080 void video_caps_notify(GObject* obj, GParamSpec* pspec, gpointer data) {
00081
00082 const GstCaps *caps;
00083 GstStructure *str;
00084
00085 gint width,height;
00086 gdouble rate;
00087
00088 AR2VideoParamT *vid = (AR2VideoParamT*)data;
00089
00090 caps = gst_pad_get_negotiated_caps((GstPad*)obj);
00091
00092 if (caps) {
00093
00094 str=gst_caps_get_structure(caps,0);
00095
00096
00097 gst_structure_get_int(str,"width",&width);
00098 gst_structure_get_int(str,"height",&height);
00099 gst_structure_get_double(str,"framerate",&rate);
00100
00101 g_print("libARvideo: GStreamer negotiated %dx%d @%3.3fps\n", width, height,rate);
00102
00103 vid->width = width;
00104 vid->height = height;
00105
00106 g_print("libARvideo: allocating %d bytes\n",(vid->width * vid->height * AR_PIX_SIZE_DEFAULT));
00107
00108
00109 arMalloc(vid->videoBuffer, ARUint8, (vid->width * vid->height * AR_PIX_SIZE_DEFAULT) );
00110
00111
00112
00113 }
00114 }
00115
00116
00117 int
00118 arVideoOpen( char *config ) {
00119 if( gVid != NULL ) {
00120 printf("Device has been opened!!\n");
00121 return -1;
00122 }
00123 gVid = ar2VideoOpen( config );
00124 if( gVid == NULL ) return -1;
00125 }
00126
00127 int
00128 arVideoClose( void )
00129 {
00130 return ar2VideoClose(gVid);
00131 }
00132
00133 int
00134 arVideoDispOption( void )
00135 {
00136 return 0;
00137 }
00138
00139 int
00140 arVideoInqSize( int *x, int *y ) {
00141
00142 ar2VideoInqSize(gVid,x,y);
00143
00144 return 0;
00145 }
00146
00147 ARUint8
00148 *arVideoGetImage( void )
00149 {
00150 return ar2VideoGetImage(gVid);
00151 }
00152
00153 int
00154 arVideoCapStart( void ) {
00155
00156 ar2VideoCapStart(gVid);
00157 return 0;
00158 }
00159
00160 int
00161 arVideoCapStop( void )
00162 {
00163 ar2VideoCapStop(gVid);
00164 return 0;
00165 }
00166
00167 int arVideoCapNext( void )
00168 {
00169 return ar2VideoCapNext(gVid);;
00170 }
00171
00172
00173
00174 AR2VideoParamT*
00175 ar2VideoOpen(char *config_in ) {
00176
00177 AR2VideoParamT *vid = 0;
00178 GError *error = 0;
00179 int i;
00180 GstPad *pad, *peerpad;
00181 GstXML *xml;
00182 GstStateChangeReturn _ret;
00183 int is_live;
00184 char *config;
00185
00186
00187 if (!config_in || !(config_in[0])) {
00188
00189 char *envconf = getenv ("ARTOOLKIT_CONFIG");
00190 if (envconf && envconf[0]) {
00191 config = envconf;
00192 g_printf ("Using config string from environment [%s].\n", envconf);
00193 } else {
00194 config = NULL;
00195
00196 g_printf ("Warning: no video config string supplied, using default!.\n");
00197
00198
00199 config = GSTREAMER_TEST_LAUNCH_CFG;
00200
00201 }
00202
00203 } else {
00204 config = config_in;
00205 g_printf ("Using supplied video config string [%s].\n", config_in);
00206 }
00207
00208
00209 gst_init(0,0);
00210
00211
00212 arMalloc( vid, AR2VideoParamT, 1 );
00213
00214
00215 vid->videoBuffer = NULL;
00216
00217
00218 g_print ("libARvideo: %s\n", gst_version_string());
00219
00220 #if 0
00221 xml = gst_xml_new();
00222
00223
00224 if (gst_xml_parse_file(xml,config,NULL))
00225 {
00226
00227
00228 } else
00229 {
00230 vid->pipeline = gst_xml_get_element(xml,"pipeline");
00231 }
00232
00233 #endif
00234
00235 vid->pipeline = gst_parse_launch (config, &error);
00236
00237 if (!vid->pipeline) {
00238 g_print ("Parse error: %s\n", error->message);
00239 return 0;
00240 };
00241
00242
00243 vid->probe = gst_bin_get_by_name(GST_BIN(vid->pipeline), "artoolkit");
00244
00245 if (!vid->probe) {
00246 g_print("Pipeline has no element named 'artoolkit'!\n");
00247 return 0;
00248 };
00249
00250
00251 pad = gst_element_get_pad (vid->probe, "src");
00252
00253
00254 peerpad = gst_pad_get_peer(pad);
00255
00256
00257 gst_pad_add_buffer_probe (pad, G_CALLBACK (cb_have_data), vid);
00258
00259 g_signal_connect(pad, "notify::caps", G_CALLBACK(video_caps_notify), vid);
00260
00261
00262 gst_element_set_state (vid->pipeline, GST_STATE_READY);
00263
00264
00265 if (gst_element_get_state (vid->pipeline, NULL, NULL, -1) == GST_STATE_CHANGE_FAILURE) {
00266 g_error ("libARvideo: failed to put GStreamer into READY state!\n");
00267 } else {
00268
00269 is_live = (_ret == GST_STATE_CHANGE_NO_PREROLL) ? 1 : 0;
00270 g_print ("libARvideo: GStreamer pipeline is READY!\n");
00271 }
00272
00273
00274 _ret = gst_element_set_state (vid->pipeline, GST_STATE_PAUSED);
00275
00276 is_live = (_ret == GST_STATE_CHANGE_NO_PREROLL) ? 1 : 0;
00277
00278
00279 if (gst_element_get_state (vid->pipeline, NULL, NULL, -1) == GST_STATE_CHANGE_FAILURE) {
00280 g_error ("libARvideo: failed to put GStreamer into PAUSED state!\n");
00281 } else {
00282 g_print ("libARvideo: GStreamer pipeline is PAUSED!\n",is_live);
00283 }
00284
00285
00286 gst_object_unref (pad);
00287
00288
00289 gst_object_unref (peerpad);
00290
00291
00292 if (is_live) {
00293
00294 g_print ("libARvdeo: need special prerolling for live sources\n");
00295
00296
00297 gst_element_set_state (vid->pipeline, GST_STATE_PLAYING);
00298
00299
00300 if (gst_element_get_state (vid->pipeline, NULL, NULL, -1) == GST_STATE_CHANGE_FAILURE) {
00301 g_error ("libARvideo: failed to put GStreamer into PLAYING state!\n");
00302 } else {
00303 g_print ("libARvideo: GStreamer pipeline is PLAYING!\n");
00304 }
00305
00306
00307 gst_element_set_state (vid->pipeline, GST_STATE_PAUSED);
00308
00309
00310 if (gst_element_get_state (vid->pipeline, NULL, NULL, -1) == GST_STATE_CHANGE_FAILURE) {
00311 g_error ("libARvideo: failed to put GStreamer into PAUSED state!\n");
00312 } else {
00313 g_print ("libARvideo: GStreamer pipeline is PAUSED!\n");
00314 }
00315 }
00316
00317 #if 0
00318
00319 gst_xml_write_file (GST_ELEMENT (vid->pipeline), stdout);
00320 #endif
00321
00322
00323 return vid;
00324 };
00325
00326
00327 int
00328 ar2VideoClose(AR2VideoParamT *vid) {
00329
00330
00331 gst_element_set_state (vid->pipeline, GST_STATE_NULL);
00332
00333
00334 gst_object_unref (GST_OBJECT (vid->pipeline));
00335
00336 return 0;
00337 }
00338
00339
00340 ARUint8*
00341 ar2VideoGetImage(AR2VideoParamT *vid) {
00342
00343 return vid->videoBuffer;
00344 }
00345
00346 int
00347 ar2VideoCapStart(AR2VideoParamT *vid)
00348 {
00349 GstStateChangeReturn _ret;
00350
00351
00352 _ret = gst_element_set_state (vid->pipeline, GST_STATE_PLAYING);
00353
00354 if (_ret == GST_STATE_CHANGE_ASYNC)
00355 {
00356
00357
00358 if (gst_element_get_state (vid->pipeline,
00359 NULL, NULL, GST_CLOCK_TIME_NONE) == GST_STATE_CHANGE_FAILURE)
00360 {
00361 g_error ("libARvideo: failed to put GStreamer into PLAYING state!\n");
00362 return 0;
00363
00364 } else {
00365 g_print ("libARvideo: GStreamer pipeline is PLAYING!\n");
00366 }
00367 }
00368 return 1;
00369 }
00370
00371 int
00372 ar2VideoCapStop(AR2VideoParamT *vid) {
00373
00374 return gst_element_set_state (vid->pipeline, GST_STATE_PAUSED);
00375 }
00376
00377 int
00378 ar2VideoCapNext(AR2VideoParamT *vid)
00379 {
00380 return 0;
00381 }
00382
00383 int
00384 ar2VideoInqSize(AR2VideoParamT *vid, int *x, int *y )
00385 {
00386
00387 *x = vid->width;
00388 *y = vid->height;
00389
00390 }
00391