278
279
void Pipeline::stop()
280
std::cout << "Stopping the GStreamer pipeline." << std::endl;
281
if (owner_->get_configuration()->get_verbose())
282
std::cout << "Stopping the GStreamer pipeline." << std::endl;
281
283
// FIXME: a segfault occurs here!
282
284
gst_element_set_state(GST_ELEMENT(pipeline_), GST_STATE_NULL);
283
285
//std::cout << "Deleting the GStreamer pipeline." << std::endl;
302
305
// TODO: add more input types like in Ekiga
303
306
if (config->videoSource() == "test")
305
std::cout << "Video source: videotestsrc" << std::endl;
309
std::cout << "Video source: videotestsrc" << std::endl;
306
310
videosrc_ = gst_element_factory_make("videotestsrc", "videosrc0");
308
312
else if (config->videoSource() == "x")
310
std::cout << "Video source: ximagesrc" << std::endl;
315
std::cout << "Video source: ximagesrc" << std::endl;
311
316
videosrc_ = gst_element_factory_make("ximagesrc", "videosrc0");
315
std::cout << "Video source: v4l2src" << std::endl;
320
// TODO:2010-08-06:aalex:We could rely on gstreamer-properties to configure the video source.
321
// Add -d gconf (gconfvideosrc)
323
std::cout << "Video source: v4l2src" << std::endl;
316
324
videosrc_ = gst_element_factory_make("v4l2src", "videosrc0");
325
std::string device_name(config->videoSource());
327
g_print("Using camera %s.\n", device_name.c_str());
328
g_object_set(videosrc_, "device", device_name.c_str(), NULL);
318
330
// TODO: use something else than g_assert to see if we could create the elements.
319
331
g_assert(videosrc_);
364
376
g_object_set(capsfilter0, "caps", the_caps, NULL);
365
377
gst_caps_unref(the_caps);
379
} else { // it's a videotestsrc
368
380
//TODO:2010-10-04:aalex:Use config.get_capture_* for test source as well
369
381
GstCaps *the_caps = gst_caps_from_string("video/x-raw-yuv, width=640, height=480, framerate=30/1");
370
382
g_object_set(capsfilter0, "caps", the_caps, NULL);
371
383
gst_caps_unref(the_caps);
373
is_linked = gst_element_link_pads(videosrc_, "src", capsfilter0, "sink");
385
is_linked = gst_element_link(videosrc_, capsfilter0);
374
386
if (!is_linked) {
375
387
g_print("Could not link %s to %s.\n", "videosrc_", "capfilter0");
378
390
source_is_linked = true;
391
} else { // it's a v4l2src
380
392
// Guess the right FPS to use with the video capture device
381
393
while (not source_is_linked)
383
g_object_set(capsfilter0, "caps", gst_caps_from_string(guess_source_caps(frame_rate_index).c_str()), NULL);
384
is_linked = gst_element_link_pads(videosrc_, "src", capsfilter0, "sink");
395
GstCaps *videocaps = gst_caps_from_string(guess_source_caps(frame_rate_index).c_str());
396
g_object_set(capsfilter0, "caps", videocaps, NULL);
397
gst_caps_unref(videocaps);
398
is_linked = gst_element_link(videosrc_, capsfilter0);
387
401
std::cout << "Failed to link video source. Trying another framerate." << std::endl;
388
402
++frame_rate_index;
389
if (frame_rate_index >= 10)
391
std::cout << "Giving up after 10 tries." << std::endl;
394
std::cout << "Success." << std::endl;
405
std::cout << "Success." << std::endl;
395
406
source_is_linked = true;
399
410
//Will now link capfilter0--ffmpegcolorspace0--tee.
400
is_linked = gst_element_link_pads(capsfilter0, "src", ffmpegcolorspace0, "sink");
411
is_linked = gst_element_link(capsfilter0, ffmpegcolorspace0);
401
412
if (!is_linked) {
402
413
g_print("Could not link %s to %s.\n", "capsfilter0", "ffmpegcolorspace0");
405
is_linked = gst_element_link_pads(ffmpegcolorspace0, "src", tee0, "sink");
416
is_linked = gst_element_link(ffmpegcolorspace0, tee0);
406
417
if (!is_linked) {
407
418
g_print("Could not link %s to %s.\n", "ffmpegcolorspace0", "tee0");
416
427
// output 0: the OpenGL uploader.
417
is_linked = gst_element_link_pads(queue0, "src", videosink_, "sink");
428
is_linked = gst_element_link(queue0, videosink_);
418
429
if (!is_linked) {
419
430
// FIXME:2010-08-06:aalex:We could get the name of the GST element for the clutter sink using gst_element_get_name
420
431
g_print("Could not link %s to %s.\n", "queue0", "cluttervideosink0");
428
439
g_print("Could not link %s to %s.\n", "tee0", "queue1");
431
is_linked = gst_element_link_pads(queue1, "src", gdkpixbufsink_, "sink");
442
is_linked = gst_element_link(queue1, gdkpixbufsink_);
432
443
if (!is_linked) {
433
444
g_print("Could not link %s to %s.\n", "queue1", "gdkpixbufsink0");
437
std::cout << "Will now setup the pipeline bus." << std::endl;
449
std::cout << "Will now setup the pipeline bus." << std::endl;
439
451
GstBus* bus = gst_pipeline_get_bus(GST_PIPELINE(pipeline_));
440
452
gst_bus_add_signal_watch(bus);
444
456
g_signal_connect(bus, "message", G_CALLBACK(bus_message_cb), this);
445
457
gst_object_unref(bus);
447
// TODO:2010-08-06:aalex:We could rely on gstremer-properties to configure the video source.
448
if (config->videoSource() != "test" and config->videoSource() != "x")
450
std::string device_name(config->videoSource());
451
g_print("Using camera %s.\n", device_name.c_str());
452
g_object_set(videosrc_, "device", device_name.c_str(), NULL);
456
460
GstStateChangeReturn ret;
457
461
ret = gst_element_set_state(GST_ELEMENT(pipeline_), GST_STATE_PLAYING);
484
487
std::string Pipeline::guess_source_caps(unsigned int framerateIndex) const
486
LOG_DEBUG("Trying to guess source FPS " << framerateIndex);
489
bool is_verbose = owner_->get_configuration()->get_verbose();
491
LOG_DEBUG("Trying to guess source FPS " << framerateIndex);
488
493
std::ostringstream capsStr;
489
494
GstStateChangeReturn ret = gst_element_set_state(videosrc_, GST_STATE_READY);
493
498
GstCaps *caps = gst_pad_get_caps(srcPad);
494
499
GstStructure *structure = gst_caps_get_structure(caps, 0);
495
500
const GValue *val = gst_structure_get_value(structure, "framerate");
496
LOG_DEBUG("Caps structure from v4l2src srcpad: " << gst_structure_to_string(structure));
502
LOG_DEBUG("Caps structure from v4l2src srcpad: " << gst_structure_to_string(structure));
497
503
gint framerate_numerator, framerate_denominator;
498
504
if (GST_VALUE_HOLDS_LIST(val))
521
527
capsSuffix += boost::lexical_cast<std::string>(framerate_denominator);
523
529
// TODO: handle interlaced video capture stream
524
//if (v4l2util::isInterlaced(deviceStr()))
525
// capsSuffix +=", interlaced=true";
531
if (v4l2util::isInterlaced(owner_->get_configuration()->videoSource()))
533
capsSuffix +=", interlaced=true";
527
535
// TODO: handle aspect ratio
528
//capsSuffix += ", pixel-aspect-ratio=";
536
// capsSuffix += ", pixel-aspect-ratio=1/1";
529
537
//capsSuffix += config_.pixelAspectRatio();
530
538
//capsSuffix += "4:3";
536
544
<< config->get_capture_height()
537
545
<< ", framerate="
539
LOG_DEBUG("Video source caps are " << capsStr.str());
548
LOG_DEBUG("Video source caps are " << capsStr.str());
540
549
ret = gst_element_set_state(videosrc_, GST_STATE_NULL);
541
550
if (ret not_eq GST_STATE_CHANGE_SUCCESS)
542
551
THROW_ERROR("Could not change v4l2src state to NULL");