From dc7a5edefeb3962f28b487dc236be8ecaab19137 Mon Sep 17 00:00:00 2001 From: Jean-Baptiste Mardelle Date: Wed, 26 Dec 2012 15:13:59 +0100 Subject: [PATCH] Workaround audio capture issue:http://www.kdenlive.org/mantis/view.php?id=2841 - using default as ALSA device works correctly --- src/kdenlivesettings.kcfg | 7 +- src/kdenlivesettingsdialog.cpp | 13 +-- src/mltdevicecapture.cpp | 19 +++-- src/recmonitor.cpp | 49 +++++++---- src/recmonitor.h | 2 +- src/widgets/configcapture_ui.ui | 143 ++++++++++++++++---------------- 6 files changed, 133 insertions(+), 100 deletions(-) diff --git a/src/kdenlivesettings.kcfg b/src/kdenlivesettings.kcfg index 4726b1f2..2df1a816 100644 --- a/src/kdenlivesettings.kcfg +++ b/src/kdenlivesettings.kcfg @@ -356,10 +356,15 @@ + + + + 2 + - hw:0,0 + default diff --git a/src/kdenlivesettingsdialog.cpp b/src/kdenlivesettingsdialog.cpp index 847bad75..c213043f 100644 --- a/src/kdenlivesettingsdialog.cpp +++ b/src/kdenlivesettingsdialog.cpp @@ -385,9 +385,10 @@ void KdenliveSettingsDialog::initDevices() m_configSdl.kcfg_video_driver->addItem(i18n("Ascii art library"), "aalib"); #endif - // Fill the list of audio playback devices + // Fill the list of audio playback / recording devices m_configSdl.kcfg_audio_device->addItem(i18n("Default"), QString()); m_configCapture.kcfg_rmd_alsa_device->addItem(i18n("Default"), QString()); + m_configCapture.kcfg_v4l_alsadevice->addItem(i18n("Default"), "default"); if (!KStandardDirs::findExe("aplay").isEmpty()) { m_readProcess.setOutputChannelMode(KProcess::OnlyStdoutChannel); m_readProcess.setProgram("aplay", QStringList() << "-l"); @@ -396,12 +397,11 @@ void KdenliveSettingsDialog::initDevices() } else { // If aplay is not installed on the system, parse the /proc/asound/pcm file QFile file("/proc/asound/pcm"); - if (file.open(QIODevice::ReadOnly)) { + if (file.open(QIODevice::ReadOnly | QIODevice::Text)) { QTextStream stream(&file); - QString line; + QString line = stream.readLine(); QString deviceId; - while (!stream.atEnd()) { - line = stream.readLine(); + while (!line.isNull()) { if (line.contains("playback")) { deviceId = line.section(':', 0, 0); m_configSdl.kcfg_audio_device->addItem(line.section(':', 1, 1), "plughw:" + QString::number(deviceId.section('-', 0, 0).toInt()) + ',' + QString::number(deviceId.section('-', 1, 1).toInt())); @@ -411,9 +411,10 @@ void KdenliveSettingsDialog::initDevices() m_configCapture.kcfg_rmd_alsa_device->addItem(line.section(':', 1, 1).simplified(), "plughw:" + QString::number(deviceId.section('-', 0, 0).toInt()) + ',' + QString::number(deviceId.section('-', 1, 1).toInt())); m_configCapture.kcfg_v4l_alsadevice->addItem(line.section(':', 1, 1).simplified(), "hw:" + QString::number(deviceId.section('-', 0, 0).toInt()) + ',' + QString::number(deviceId.section('-', 1, 1).toInt())); } + line = stream.readLine(); } file.close(); - } + } else kDebug()<<" / / / /CANNOT READ PCM"; } // Add pulseaudio capture option diff --git a/src/mltdevicecapture.cpp b/src/mltdevicecapture.cpp index 948e86e6..6a23773d 100644 --- a/src/mltdevicecapture.cpp +++ b/src/mltdevicecapture.cpp @@ -184,7 +184,8 @@ void MltDeviceCapture::stop() if (m_mltConsumer) { m_mltConsumer->set("refresh", 0); - m_mltConsumer->stop(); + m_mltConsumer->purge(); + m_mltConsumer->stop(); //if (!m_mltConsumer->is_stopped()) m_mltConsumer->stop(); } if (m_mltProducer) { @@ -449,7 +450,7 @@ bool MltDeviceCapture::slotStartCapture(const QString ¶ms, const QString &pa renderProps->set("mlt_service", "avformat"); renderProps->set("target", path.toUtf8().constData()); renderProps->set("real_time", -KdenliveSettings::mltthreads()); - renderProps->set("terminate_on_pause", 0); + //renderProps->set("terminate_on_pause", 0); renderProps->set("mlt_profile", m_activeProfile.toUtf8().constData()); @@ -518,19 +519,25 @@ bool MltDeviceCapture::slotStartCapture(const QString ¶ms, const QString &pa } - tmp = qstrdup(playlist.toUtf8().constData()); if (xmlPlaylist) { // create an xml producer - m_mltProducer = new Mlt::Producer(*m_mltProfile, "xml-string", tmp); + m_mltProducer = new Mlt::Producer(*m_mltProfile, "xml-string", playlist.toUtf8().constData()); } else { // create a producer based on mltproducer parameter - m_mltProducer = new Mlt::Producer(*m_mltProfile, tmp); + m_mltProducer = new Mlt::Producer(*m_mltProfile, playlist.toUtf8().constData()); } - delete[] tmp; if (m_mltProducer == NULL || !m_mltProducer->is_valid()) { kDebug()<<"//// ERROR CREATRING PROD"; + if (m_mltConsumer) { + delete m_mltConsumer; + m_mltConsumer = NULL; + } + if (m_mltProducer) { + delete m_mltProducer; + m_mltProducer = NULL; + } return false; } diff --git a/src/recmonitor.cpp b/src/recmonitor.cpp index 1a1d1426..35304225 100644 --- a/src/recmonitor.cpp +++ b/src/recmonitor.cpp @@ -451,6 +451,7 @@ void RecMonitor::slotStartPreview(bool play) QString producer; QStringList dvargs = KdenliveSettings::dvgrabextra().simplified().split(' ', QString::SkipEmptyParts); int ix = device_selector->currentIndex(); + bool isXml; videoBox->setHidden(ix != VIDEO4LINUX && ix != BLACKMAGIC && ix != FIREWIRE); switch (ix) { case FIREWIRE: @@ -499,10 +500,10 @@ void RecMonitor::slotStartPreview(bool play) path = KStandardDirs::locateLocal("appdata", "profiles/video4linux"); buildMltDevice(path); profile = ProfilesDialog::getVideoProfile(path); - producer = getV4lXmlPlaylist(profile); + producer = getV4lXmlPlaylist(profile, &isXml); //producer = QString("avformat-novalidate:video4linux2:%1?width:%2&height:%3&frame_rate:%4").arg(KdenliveSettings::video4vdevice()).arg(profile.width).arg(profile.height).arg((double) profile.frame_rate_num / profile.frame_rate_den); - if (!m_captureDevice->slotStartPreview(producer, true)) { + if (!m_captureDevice->slotStartPreview(producer, isXml)) { // v4l capture failed to start video_frame->setText(i18n("Failed to start Video4Linux,\ncheck your parameters...")); videoBox->setHidden(true); @@ -590,6 +591,7 @@ void RecMonitor::slotRecord() QString v4lparameters; MltVideoProfile profile; bool showPreview; + bool isXml; QString capturename = KdenliveSettings::dvgrabfilename(); if (capturename.isEmpty()) capturename = "capture"; @@ -600,7 +602,7 @@ void RecMonitor::slotRecord() profile = ProfilesDialog::getVideoProfile(path); //m_videoBox->setRatio((double) profile.display_aspect_num / profile.display_aspect_den); buildMltDevice(path); - playlist = getV4lXmlPlaylist(profile); + playlist = getV4lXmlPlaylist(profile, &isXml); v4lparameters = KdenliveSettings::v4l_parameters(); @@ -639,7 +641,7 @@ void RecMonitor::slotRecord() showPreview = m_previewSettings->isChecked(); if (!rec_video->isChecked()) showPreview = false; - if (m_captureDevice->slotStartCapture(v4lparameters, m_captureFile.path(), playlist, showPreview)) { + if (m_captureDevice->slotStartCapture(v4lparameters, m_captureFile.path(), playlist, showPreview, isXml)) { videoBox->setHidden(false); m_isCapturing = true; m_recAction->setEnabled(false); @@ -649,6 +651,9 @@ void RecMonitor::slotRecord() else { video_frame->setText(i18n("Failed to start Video4Linux,\ncheck your parameters...")); videoBox->setHidden(true); + m_recAction->blockSignals(true); + m_recAction->setChecked(false); + m_recAction->blockSignals(false); m_isCapturing = false; } break; @@ -742,22 +747,34 @@ void RecMonitor::slotRecord() } } -const QString RecMonitor::getV4lXmlPlaylist(MltVideoProfile profile) { - - QString playlist = QString("").arg(profile.width).arg(profile.height).arg(profile.progressive).arg(profile.sample_aspect_num).arg(profile.sample_aspect_den).arg(profile.display_aspect_num).arg(profile.display_aspect_den).arg(profile.frame_rate_num).arg(profile.frame_rate_den).arg(profile.colorspace); +const QString RecMonitor::getV4lXmlPlaylist(MltVideoProfile profile, bool *isXml) +{ + QString playlist; + if (rec_video->isChecked() && rec_audio->isChecked()) { + // We want to capture audio and video, use xml playlist + *isXml = true; + playlist = QString("").arg(profile.width).arg(profile.height).arg(profile.progressive).arg(profile.sample_aspect_num).arg(profile.sample_aspect_den).arg(profile.display_aspect_num).arg(profile.display_aspect_den).arg(profile.frame_rate_num).arg(profile.frame_rate_den).arg(profile.colorspace); - if (rec_video->isChecked()) { playlist.append(QString("producer1000000loopvideo4linux2:%1?width:%2&height:%3&frame_rate:%4avformat-novalidate").arg(KdenliveSettings::video4vdevice()).arg(profile.width).arg(profile.height).arg((double) profile.frame_rate_num / profile.frame_rate_den)); - } + + playlist.append(QString("producer1000000alsa:%1?channels=%20-1avformat-novalidate").arg(KdenliveSettings::v4l_alsadevicename()).arg(KdenliveSettings::alsachannels())); - if (rec_audio->isChecked()) { - playlist.append(QString("producer1000000loopalsa:%50-1avformat-novalidate").arg(KdenliveSettings::v4l_alsadevicename())); + playlist.append(""); + playlist.append(""); + playlist.append(""); } - playlist.append(""); - if (rec_video->isChecked()) playlist.append(""); - if (rec_audio->isChecked()) playlist.append(""); - playlist.append(""); - + else if (rec_audio->isChecked()) { + // Audio only recording + *isXml = false; + playlist =QString("alsa:%1?channels=%2").arg(KdenliveSettings::v4l_alsadevicename()).arg(KdenliveSettings::alsachannels()); + } + else { + // Video only recording + *isXml = false; + playlist =QString("video4linux2:%1?width:%2&height:%3&frame_rate:%4").arg(KdenliveSettings::video4vdevice()).arg(profile.width).arg(profile.height).arg((double) profile.frame_rate_num / profile.frame_rate_den); + + } + return playlist; } diff --git a/src/recmonitor.h b/src/recmonitor.h index aeb10290..16063faf 100644 --- a/src/recmonitor.h +++ b/src/recmonitor.h @@ -108,7 +108,7 @@ private: /** @brief Build MLT producer for device, using path as profile. */ void buildMltDevice(const QString &path); /** @brief Create string containing an XML playlist for v4l capture. */ - const QString getV4lXmlPlaylist(MltVideoProfile profile); + const QString getV4lXmlPlaylist(MltVideoProfile profile, bool *isXml); private slots: void slotStartPreview(bool play = true); diff --git a/src/widgets/configcapture_ui.ui b/src/widgets/configcapture_ui.ui index 08652d62..294454c9 100644 --- a/src/widgets/configcapture_ui.ui +++ b/src/widgets/configcapture_ui.ui @@ -7,7 +7,7 @@ 0 0 405 - 479 + 492 @@ -63,7 +63,7 @@ - 0 + 1 @@ -181,14 +181,14 @@ FFmpeg - - + + - Detected devices + Channels - + @@ -198,10 +198,20 @@ - - + + - + Detected devices + + + + + + + ... + + + true @@ -212,7 +222,7 @@ - + @@ -222,7 +232,7 @@ - + 720x576 @@ -236,13 +246,20 @@ - + 25/1 + + + + + + + @@ -250,21 +267,21 @@ - + 59/54 - + Display aspect ratio: - + 4/3 @@ -278,13 +295,27 @@ - + + + + + Edit + + + + + + + Qt::Horizontal + + + @@ -292,7 +323,7 @@ - + Qt::Horizontal @@ -305,28 +336,14 @@ - - - - Edit - - - - - - - Qt::Horizontal - - - - + Capture audio (ALSA) - + Qt::Horizontal @@ -346,24 +363,7 @@ - - - - - 0 - 0 - - - - - - - - true - - - - + Qt::Vertical @@ -376,32 +376,32 @@ - - - - ... + + + + true - - + + - ... - - - true + Capture video (Video4Linux2) - - + + - Device + ... - - + + + + + 0 @@ -410,10 +410,13 @@ - - - - Capture video (Video4Linux2) + + + + + 0 + 0 + -- 2.39.2