From: Jean-Baptiste Mardelle Date: Sun, 12 Jun 2011 16:00:42 +0000 (+0000) Subject: Some update for decklink capture & use mlt_threads for proxies X-Git-Url: https://git.sesse.net/?a=commitdiff_plain;h=0871a6e39f765e4bdd043bcd04d2c34ed0f3a250;p=kdenlive Some update for decklink capture & use mlt_threads for proxies svn path=/trunk/kdenlive/; revision=5706 --- diff --git a/src/abstractmonitor.cpp b/src/abstractmonitor.cpp index 4b2d5b7d..270bd4f6 100644 --- a/src/abstractmonitor.cpp +++ b/src/abstractmonitor.cpp @@ -19,11 +19,16 @@ #include "abstractmonitor.h" +#include "kdenlivesettings.h" #include +#include + VideoPreviewContainer::VideoPreviewContainer(QWidget *parent) : - QFrame(parent) + QFrame(parent), + m_dar(1.0), + m_refresh(false) { setFrameShape(QFrame::NoFrame); setFocusPolicy(Qt::ClickFocus); @@ -38,50 +43,71 @@ VideoPreviewContainer::~VideoPreviewContainer() qDeleteAll(m_imageQueue); } +//virtual +void VideoPreviewContainer::resizeEvent( QResizeEvent * /*event*/ ) +{ + updateDisplayZone(); +} + +void VideoPreviewContainer::setRatio(double ratio) +{ + m_dar = ratio; + updateDisplayZone(); +} + + +void VideoPreviewContainer::updateDisplayZone() +{ + QRect rect = this->frameRect(); + int paintW = rect.height() * m_dar + 0.5; + if (paintW > rect.width()) { + int paintH = rect.width() / m_dar + 0.5; + int diff = (rect.height() - paintH) / 2; + rect.adjust(0, diff, 0, 0); + rect.setHeight(paintH); + } + else { + int diff = (rect.width() - paintW) / 2; + rect.adjust(diff, 0, 0, 0); + rect.setWidth(paintW); + } + m_displayRect = rect; + m_refresh = true; +} void VideoPreviewContainer::setImage(QImage img) { if (m_imageQueue.count() > 2) { - delete m_imageQueue.takeLast();//replace(10, new QImage(img)); + delete m_imageQueue.takeLast(); } m_imageQueue.prepend(new QImage(img)); + update(); } void VideoPreviewContainer::stop() { - m_refreshTimer.stop(); + //m_refreshTimer.stop(); qDeleteAll(m_imageQueue); m_imageQueue.clear(); } void VideoPreviewContainer::start() { - m_refreshTimer.start(); + //m_refreshTimer.start(); } // virtual -void VideoPreviewContainer::paintEvent(QPaintEvent */*event*/) +void VideoPreviewContainer::paintEvent(QPaintEvent *event) { - if (m_imageQueue.isEmpty()) return; - QImage *img = m_imageQueue.takeFirst(); - QPainter painter(this); - double ar = (double) img->width() / img->height(); - QRect rect = this->frameRect(); - int paintW = rect.height() * ar + 0.5; - if (paintW > rect.width()) { - paintW = rect.width() / ar + 0.5; - int diff = (rect.height() - paintW) / 2; - rect.adjust(0, diff, 0, 0); - rect.setHeight(paintW); - } - else { - int diff = (rect.width() - paintW) / 2; - rect.adjust(diff, 0, 0, 0); - rect.setWidth(paintW); - } - - painter.drawImage(rect, *img); - delete img; + if (m_imageQueue.isEmpty()) return; + QImage *img = m_imageQueue.takeFirst(); + QPainter painter(this); + if (m_refresh) { + painter.fillRect(event->rect(), QColor(KdenliveSettings::window_background())); + m_refresh = false; + } + painter.drawImage(m_displayRect, *img); + delete img; } diff --git a/src/abstractmonitor.h b/src/abstractmonitor.h index 85469a13..1167e6c4 100644 --- a/src/abstractmonitor.h +++ b/src/abstractmonitor.h @@ -36,16 +36,32 @@ class VideoPreviewContainer : public QFrame public: VideoPreviewContainer(QWidget *parent = 0); ~VideoPreviewContainer(); + /** @brief Set the image to be displayed, will be put in the queue. */ void setImage(QImage img); + /** @brief Start the display refresh timer. */ void start(); + /** @brief Stop the display refresh timer. */ void stop(); + /** @brief Set the display ratio for this display. */ + void setRatio(double ratio); protected: virtual void paintEvent(QPaintEvent */*event*/); + virtual void resizeEvent(QResizeEvent * event); private: + /** @brief The display aspect ratio for profile. */ + double m_dar; + /** @brief When true, the whole widget surface will be repainted, useful when resizing widget. */ + bool m_refresh; + /** @brief The rectangle defining the area for painting our image. */ + QRect m_displayRect; + /** @brief The queue of images to be displayed. */ QList m_imageQueue; + /** @brief We refresh the image with a timer, since this widget is only for preview during capture. */ QTimer m_refreshTimer; + /** @brief Re-calculate the display zone after a resize or aspect ratio change. */ + void updateDisplayZone(); }; diff --git a/src/kdenlivesettings.kcfg b/src/kdenlivesettings.kcfg index c9116df5..6f046430 100644 --- a/src/kdenlivesettings.kcfg +++ b/src/kdenlivesettings.kcfg @@ -504,7 +504,7 @@ - vcodec=mpeg2video b=12000k minrate=0 pix_fmt=yuv420p g=15 acodec=mp2 ac=2 ab=128k ar=48000 threads=%threads + vcodec=mpeg2video qscale=10 acodec=mp2 ac=2 ab=128k ar=48000 threads=%threads @@ -765,6 +765,11 @@ true + + + + 0 + diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 1674d785..9e369e30 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -4213,7 +4213,7 @@ void MainWindow::slotUpdateColorScopes() if (!m_gfxScopesList.at(i)->widget()->visibleRegion().isEmpty() && !(static_cast(m_gfxScopesList.at(i)->widget())->autoRefreshEnabled())) request = true; static_cast(m_gfxScopesList.at(i)->widget())->slotActiveMonitorChanged(); } - if (request) { + if (request && m_monitorManager->activeRenderer()) { m_monitorManager->activeRenderer()->sendFrameUpdate(); } } diff --git a/src/mltdevicecapture.cpp b/src/mltdevicecapture.cpp index f9e647f1..914ce5ae 100644 --- a/src/mltdevicecapture.cpp +++ b/src/mltdevicecapture.cpp @@ -65,20 +65,17 @@ static void rec_consumer_frame_preview(mlt_consumer, MltDeviceCapture * self, ml if (self->sendFrameForAnalysis && frame_ptr->convert_image) { self->emitFrameUpdated(frame); } - if (self->doCapture > 0) { + if (self->doCapture > 0) { self->doCapture --; if (self->doCapture == 0) self->saveFrame(frame); } -/* if (self->analyseAudio) { + //TODO: connect record monitor to audio scopes + /* + if (self->analyseAudio) { self->showAudio(frame); } - if (frame.get_double("_speed") == 0.0) { - self->emitConsumerStopped(); - } else if (frame.get_double("_speed") < 0.0 && mlt_frame_get_position(frame_ptr) <= 0) { - self->pause(); - self->emitConsumerStopped(); - }*/ + */ } @@ -90,13 +87,15 @@ MltDeviceCapture::MltDeviceCapture(QString profile, VideoPreviewContainer *surfa m_mltProducer(NULL), m_mltProfile(NULL), m_droppedFrames(0), - m_livePreview(true), + m_livePreview(KdenliveSettings::recording_preview()), m_captureDisplayWidget(surface), m_winid((int) surface->winId()), - m_analyseAudio(KdenliveSettings::monitor_audio()) + analyseAudio(KdenliveSettings::monitor_audio()), + processingImage(false) { if (profile.isEmpty()) profile = KdenliveSettings::current_profile(); buildConsumer(profile); + connect(this, SIGNAL(unblockPreview()), this, SLOT(slotPreparePreview())); } MltDeviceCapture::~MltDeviceCapture() @@ -133,18 +132,17 @@ void MltDeviceCapture::buildConsumer(const QString &profileName) // OpenGL monitor m_mltConsumer = new Mlt::Consumer(*m_mltProfile, "sdl_audio"); m_mltConsumer->set("preview_off", 1); - m_mltConsumer->set("preview_format", mlt_image_rgb24a); + m_mltConsumer->set("preview_format", mlt_image_rgb24); m_mltConsumer->listen("consumer-frame-show", this, (mlt_listener) consumer_gl_frame_show); } else { m_mltConsumer = new Mlt::Consumer(*m_mltProfile, "sdl_preview"); m_mltConsumer->set("window_id", m_winid); + m_mltConsumer->listen("consumer-frame-show", this, (mlt_listener) rec_consumer_frame_preview); } - m_mltConsumer->set("resize", 1); + //m_mltConsumer->set("resize", 1); //m_mltConsumer->set("terminate_on_pause", 1); m_mltConsumer->set("window_background", KdenliveSettings::window_background().name().toUtf8().constData()); - m_mltConsumer->set("rescale", "nearest"); - - m_mltConsumer->listen("consumer-frame-show", this, (mlt_listener) rec_consumer_frame_preview); + //m_mltConsumer->set("rescale", "nearest"); QString audioDevice = KdenliveSettings::audiodevicename(); if (!audioDevice.isEmpty()) @@ -158,7 +156,7 @@ void MltDeviceCapture::buildConsumer(const QString &profileName) if (!audioDriver.isEmpty()) m_mltConsumer->set("audio_driver", audioDriver.toUtf8().constData()); - //m_mltConsumer->set("progressive", 1); + //m_mltConsumer->set("progressive", 0); //m_mltConsumer->set("buffer", 1); //m_mltConsumer->set("real_time", 0); } @@ -166,6 +164,7 @@ void MltDeviceCapture::buildConsumer(const QString &profileName) void MltDeviceCapture::stop() { bool isPlaylist = false; + disconnect(this, SIGNAL(imageReady(QImage)), this, SIGNAL(frameUpdated(QImage))); m_captureDisplayWidget->stop(); if (m_mltConsumer) { m_mltConsumer->set("refresh", 0); @@ -231,25 +230,37 @@ void MltDeviceCapture::doRefresh() void MltDeviceCapture::emitFrameUpdated(Mlt::Frame& frame) { - mlt_image_format format = mlt_image_rgb24a; + /* + //TEST: is it better to convert the frame in a thread outside of MLT?? + if (processingImage) return; + mlt_image_format format = (mlt_image_format) frame.get_int("format"); //mlt_image_rgb24; + int width = frame.get_int("width"); + int height = frame.get_int("height"); + unsigned char *buffer = (unsigned char *) frame.get_data("image"); + if (format == mlt_image_yuv422) { + QtConcurrent::run(this, &MltDeviceCapture::uyvy2rgb, (unsigned char *) buffer, width, height); + } + */ + + mlt_image_format format = mlt_image_rgb24; int width = 0; int height = 0; const uchar* image = frame.get_image(format, width, height); QImage qimage(width, height, QImage::Format_ARGB32); - memcpy(qimage.bits(), image, width * height * 4); + memcpy(qimage.bits(), image, width * height * 3); emit frameUpdated(qimage.rgbSwapped()); } void MltDeviceCapture::showFrame(Mlt::Frame& frame) { - mlt_image_format format = mlt_image_rgb24a; + mlt_image_format format = mlt_image_rgb24; int width = 0; int height = 0; const uchar* image = frame.get_image(format, width, height); - QImage qimage(width, height, QImage::Format_ARGB32_Premultiplied); - memcpy(qimage.scanLine(0), image, width * height * 4); + QImage qimage(width, height, QImage::Format_RGB888); + memcpy(qimage.scanLine(0), image, width * height * 3); emit showImageSignal(qimage); - if (m_analyseAudio) showAudio(frame); + if (sendFrameForAnalysis && frame.get_frame()->convert_image) { emit frameUpdated(qimage.rgbSwapped()); } @@ -304,6 +315,7 @@ bool MltDeviceCapture::slotStartPreview(const QString &producer, bool xmlFormat) m_mltConsumer = NULL; return 0; } + connect(this, SIGNAL(imageReady(QImage)), this, SIGNAL(frameUpdated(QImage))); return 1; } @@ -311,29 +323,49 @@ void MltDeviceCapture::gotCapturedFrame(Mlt::Frame& frame) { if (m_mltProducer) { int dropped = m_mltProducer->get_int("dropped"); - if (dropped != m_droppedFrames) { + if (dropped > m_droppedFrames) { m_droppedFrames = dropped; emit droppedFrames(m_droppedFrames); } } - if (!m_livePreview) return; + m_frameCount++; + if (m_livePreview == 2) return; + if (m_livePreview == 0 && (m_frameCount % 10 > 0)) return; mlt_image_format format = mlt_image_rgb24a; int width = 0; int height = 0; - const uchar* image = frame.get_image(format, width, height); - QImage qimage(width, height, QImage::Format_ARGB32); - memcpy(qimage.bits(), image, width * height * 4); - m_captureDisplayWidget->setImage(qimage.rgbSwapped()); + //QImage image(width, height, QImage::Format_ARGB32_Premultiplied); + uint8_t *data = frame.get_image(format, width, height, 0); + QImage image((uchar *)data, width, height, QImage::Format_ARGB32_Premultiplied); + + /*uchar *buffer = frame.get_image(format, width, height); + memcpy(image.bits(), buffer, width * height * 4);*/ + m_captureDisplayWidget->setImage(image.rgbSwapped()); + + //TEST: is it better to process frame conversion ouside MLT??? + /* + if (!m_livePreview || processingImage) return; + + mlt_image_format format = (mlt_image_format) frame.get_int("format"); //mlt_image_rgb24a; + int width = frame.get_int("width"); + int height = frame.get_int("height"); + unsigned char *buffer = (unsigned char *) frame.get_data("image"); + //unsigned char *buffer = frame.get_image(format, width, height); + //convert from uyvy422 to rgba + if (format == mlt_image_yuv422) { + QtConcurrent::run(this, &MltDeviceCapture::uyvy2rgb, (unsigned char *) buffer, width, height); + //CaptureHandler::uyvy2rgb((uchar *)frameBytes, (uchar *)image.bits(), videoFrame->GetWidth(), videoFrame->GetHeight()); + }*/ } void MltDeviceCapture::saveFrame(Mlt::Frame& frame) { - mlt_image_format format = mlt_image_rgb24a; + mlt_image_format format = mlt_image_rgb24; int width = 0; int height = 0; const uchar* image = frame.get_image(format, width, height); - QImage qimage(width, height, QImage::Format_ARGB32); - memcpy(qimage.bits(), image, width * height * 4); + QImage qimage(width, height, QImage::Format_RGB888); + memcpy(qimage.bits(), image, width * height * 3); // Re-enable overlay Mlt::Service service(m_mltProducer->parent().get_service()); @@ -363,10 +395,11 @@ void MltDeviceCapture::captureFrame(const QString &path) doCapture = 5; } -bool MltDeviceCapture::slotStartCapture(const QString ¶ms, const QString &path, const QString &playlist, bool livePreview, bool xmlPlaylist) +bool MltDeviceCapture::slotStartCapture(const QString ¶ms, const QString &path, const QString &playlist, int livePreview, bool xmlPlaylist) { stop(); m_livePreview = livePreview; + m_frameCount = 0; m_droppedFrames = 0; if (m_mltProfile) delete m_mltProfile; char *tmp = qstrdup(m_activeProfile.toUtf8().constData()); @@ -376,7 +409,7 @@ bool MltDeviceCapture::slotStartCapture(const QString ¶ms, const QString &pa kDebug()<<"-- CREATING CAP: "<set("terminate_on_pause", 1); + m_mltConsumer->set("real_time", KdenliveSettings::mltthreads()); delete[] tmp; QStringList paramList = params.split(" ", QString::SkipEmptyParts); @@ -400,7 +433,7 @@ bool MltDeviceCapture::slotStartCapture(const QString ¶ms, const QString &pa } // FIXME: the event object returned by the listen gets leaked... - m_mltConsumer->listen("consumer-frame-show", this, (mlt_listener) rec_consumer_frame_show); + m_mltConsumer->listen("consumer-frame-render", this, (mlt_listener) rec_consumer_frame_show); tmp = qstrdup(playlist.toUtf8().constData()); if (xmlPlaylist) { // create an xml producer @@ -416,7 +449,7 @@ bool MltDeviceCapture::slotStartCapture(const QString ¶ms, const QString &pa kDebug()<<"//// ERROR CREATRING PROD"; return false; } - + m_mltConsumer->connect(*m_mltProducer); if (m_mltConsumer->start() == -1) { delete m_mltConsumer; @@ -563,3 +596,84 @@ void MltDeviceCapture::mirror(bool activate) mlt_service_unlock(service.get_service()); } +void MltDeviceCapture::uyvy2rgb(unsigned char *yuv_buffer, int width, int height) +{ + processingImage = true; + QImage image(width, height, QImage::Format_RGB888); + unsigned char *rgb_buffer = image.bits(); + + int len; + int r, g, b; + int Y, U, V, Y2; + int rgb_ptr, y_ptr, t; + + len = width * height / 2; + + rgb_ptr = 0; + y_ptr = 0; + + for (t = 0; t < len; t++) { + + + Y = yuv_buffer[y_ptr]; + U = yuv_buffer[y_ptr+1]; + Y2 = yuv_buffer[y_ptr+2]; + V = yuv_buffer[y_ptr+3]; + y_ptr += 4; + + r = ((298 * (Y - 16) + 409 * (V - 128) + 128) >> 8); + + g = ((298 * (Y - 16) - 100 * (U - 128) - 208 * (V - 128) + 128) >> 8); + + b = ((298 * (Y - 16) + 516 * (U - 128) + 128) >> 8); + + if (r > 255) r = 255; + if (g > 255) g = 255; + if (b > 255) b = 255; + + if (r < 0) r = 0; + if (g < 0) g = 0; + if (b < 0) b = 0; + + rgb_buffer[rgb_ptr] = r; + rgb_buffer[rgb_ptr+1] = g; + rgb_buffer[rgb_ptr+2] = b; + rgb_ptr += 3; + + + r = ((298 * (Y2 - 16) + 409 * (V - 128) + 128) >> 8); + + g = ((298 * (Y2 - 16) - 100 * (U - 128) - 208 * (V - 128) + 128) >> 8); + + b = ((298 * (Y2 - 16) + 516 * (U - 128) + 128) >> 8); + + if (r > 255) r = 255; + if (g > 255) g = 255; + if (b > 255) b = 255; + + if (r < 0) r = 0; + if (g < 0) g = 0; + if (b < 0) b = 0; + + rgb_buffer[rgb_ptr] = r; + rgb_buffer[rgb_ptr+1] = g; + rgb_buffer[rgb_ptr+2] = b; + rgb_ptr += 3; + } + //emit imageReady(image); + m_captureDisplayWidget->setImage(image); + emit unblockPreview(); + //processingImage = false; +} + +void MltDeviceCapture::slotPreparePreview() +{ + QTimer::singleShot(1000, this, SLOT(slotAllowPreview())); +} + +void MltDeviceCapture::slotAllowPreview() +{ + processingImage = false; +} + + diff --git a/src/mltdevicecapture.h b/src/mltdevicecapture.h index 2a332bf9..9603326e 100644 --- a/src/mltdevicecapture.h +++ b/src/mltdevicecapture.h @@ -28,6 +28,8 @@ #include "abstractmonitor.h" #include "mlt/framework/mlt_types.h" +#include + namespace Mlt { class Consumer; @@ -76,7 +78,7 @@ Q_OBJECT public: /** @brief Starts the MLT Video4Linux process. * @param surface The widget onto which the frame should be painted */ - bool slotStartCapture(const QString ¶ms, const QString &path, const QString &playlist, bool livePreview, bool xmlPlaylist = true); + bool slotStartCapture(const QString ¶ms, const QString &path, const QString &playlist, int livePreview, bool xmlPlaylist = true); bool slotStartPreview(const QString &producer, bool xmlFormat = false); /** @brief A frame arrived from the MLT Video4Linux process. */ void gotCapturedFrame(Mlt::Frame& frame); @@ -92,13 +94,22 @@ Q_OBJECT public: /** @brief This will add a horizontal flip effect, easier to work when filming yourself. */ void mirror(bool activate); + /** @brief This property is used to decide if the renderer should send audio data for monitoring. */ + bool analyseAudio; + + /** @brief True if we are processing an image (yuv > rgb) when recording. */ + bool processingImage; + private: Mlt::Consumer * m_mltConsumer; Mlt::Producer * m_mltProducer; Mlt::Profile *m_mltProfile; QString m_activeProfile; int m_droppedFrames; - bool m_livePreview; + /** @brief When true, images will be displayed on monitor while capturing. */ + int m_livePreview; + /** @brief Count captured frames, used to display only one in ten images while capturing. */ + int m_frameCount; /** @brief The surface onto which the captured frames should be painted. */ VideoPreviewContainer *m_captureDisplayWidget; @@ -106,8 +117,7 @@ private: /** @brief A human-readable description of this renderer. */ int m_winid; - /** @brief This property is used to decide if the renderer should send audio data for monitoring. */ - bool m_analyseAudio; + void uyvy2rgb(unsigned char *yuv_buffer, int width, int height); QString m_capturePath; @@ -115,8 +125,11 @@ private: * @param profileName The MLT profile to use for the consumer */ void buildConsumer(const QString &profileName = QString()); -private slots: +private slots: + void slotPreparePreview(); + void slotAllowPreview(); + signals: /** @brief A frame's image has to be shown. * @@ -129,6 +142,10 @@ signals: void frameSaved(const QString); void droppedFrames(int); + + void unblockPreview(); + void imageReady(QImage); + public slots: diff --git a/src/projectlist.cpp b/src/projectlist.cpp index cddce5e8..a9087e4e 100644 --- a/src/projectlist.cpp +++ b/src/projectlist.cpp @@ -2182,6 +2182,8 @@ void ProjectList::slotGenerateProxy(const QString id) else s.replace(' ', '='); parameters << s; } + + parameters.append(QString("real_time=-%1").arg(KdenliveSettings::mltthreads())); // currently, when rendering an xml file through melt, the display ration is lost, so we enforce it manualy double display_ratio = KdenliveDoc::getDisplayRatio(url); diff --git a/src/recmonitor.cpp b/src/recmonitor.cpp index 9083abc2..76c5714a 100644 --- a/src/recmonitor.cpp +++ b/src/recmonitor.cpp @@ -158,6 +158,9 @@ RecMonitor::RecMonitor(QString name, MonitorManager *manager, QWidget *parent) : kDebug() << "/////// BUILDING MONITOR, ID: " << video_frame->winId(); slotVideoDeviceChanged(device_selector->currentIndex()); + recording_preview->setToolTip(i18n("Capture preview settings")); + recording_preview->setCurrentIndex(KdenliveSettings::recording_preview()); + connect(recording_preview, SIGNAL(currentIndexChanged(int)), this, SLOT(slotChangeRecordingPreview(int))); } RecMonitor::~RecMonitor() @@ -210,7 +213,7 @@ void RecMonitor::slotVideoDeviceChanged(int ix) { QString capturefile; QString capturename; - enable_preview->setHidden(ix != VIDEO4LINUX && ix != BLACKMAGIC); + recording_preview->setHidden(ix != VIDEO4LINUX && ix != BLACKMAGIC); m_fwdAction->setVisible(ix == FIREWIRE); m_discAction->setVisible(ix == FIREWIRE); m_rewAction->setVisible(ix == FIREWIRE); @@ -386,6 +389,7 @@ void RecMonitor::slotStopCapture() if (m_captureDevice) { m_captureDevice->stop(); } + recording_preview->setEnabled(true); m_isCapturing = false; m_isPlaying = false; m_playAction->setEnabled(true); @@ -542,6 +546,7 @@ void RecMonitor::slotRecord() return; } if (m_captureProcess->state() == QProcess::NotRunning) { + m_logger.clear(); m_recAction->setChecked(true); QString extension = "mpg"; if (device_selector->currentIndex() == SCREENGRAB) extension = "ogv"; //KdenliveSettings::screengrabextension(); @@ -568,6 +573,7 @@ void RecMonitor::slotRecord() case VIDEO4LINUX: path = KStandardDirs::locateLocal("appdata", "profiles/video4linux"); profile = ProfilesDialog::getVideoProfile(path); + m_videoBox->setRatio((double) profile.display_aspect_num / profile.display_aspect_den); buildMltDevice(path); playlist = QString("producer100000pausevideo4linux2:%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); @@ -589,11 +595,12 @@ void RecMonitor::slotRecord() playlist.append(""); - if (m_captureDevice->slotStartCapture(KdenliveSettings::v4l_parameters(), m_captureFile.path(), playlist, enable_preview->isChecked())) { + if (m_captureDevice->slotStartCapture(KdenliveSettings::v4l_parameters(), m_captureFile.path(), playlist, recording_preview->currentIndex())) { m_videoBox->setHidden(false); m_isCapturing = true; m_recAction->setEnabled(false); m_stopAction->setEnabled(true); + recording_preview->setEnabled(false); } else { video_frame->setText(i18n("Failed to start Video4Linux,\ncheck your parameters...")); @@ -605,16 +612,18 @@ void RecMonitor::slotRecord() case BLACKMAGIC: path = KdenliveSettings::current_profile(); profile = ProfilesDialog::getVideoProfile(path); + m_videoBox->setRatio((double) profile.display_aspect_num / profile.display_aspect_den); buildMltDevice(path); playlist = QString("producer100000pause%1decklink").arg(KdenliveSettings::decklink_capturedevice()); - if (m_captureDevice->slotStartCapture(KdenliveSettings::decklink_parameters(), m_captureFile.path(), QString("decklink:%1").arg(KdenliveSettings::decklink_capturedevice()), enable_preview->isChecked(), false)) { + if (m_captureDevice->slotStartCapture(KdenliveSettings::decklink_parameters(), m_captureFile.path(), QString("decklink:%1").arg(KdenliveSettings::decklink_capturedevice()), recording_preview->currentIndex(), false)) { m_videoBox->setHidden(false); m_isCapturing = true; slotSetInfoMessage(i18n("Capturing to %1", m_captureFile.fileName())); m_recAction->setEnabled(false); m_stopAction->setEnabled(true); + recording_preview->setEnabled(false); } else { video_frame->setText(i18n("Failed to start Decklink,\ncheck your parameters...")); @@ -880,6 +889,10 @@ void RecMonitor::buildMltDevice(const QString &path) } } +void RecMonitor::slotChangeRecordingPreview(int ix) +{ + KdenliveSettings::setRecording_preview(ix); +} #include "recmonitor.moc" diff --git a/src/recmonitor.h b/src/recmonitor.h index 64721381..d9bd734c 100644 --- a/src/recmonitor.h +++ b/src/recmonitor.h @@ -124,6 +124,8 @@ private slots: void slotUpdateFreeSpace(); void slotSetInfoMessage(const QString &message); void slotDroppedFrames(int dropped); + /** @brief Change setting for preview while recording. */ + void slotChangeRecordingPreview(int ix); public slots: void refreshRecMonitor(bool visible); diff --git a/src/widgets/recmonitor_ui.ui b/src/widgets/recmonitor_ui.ui index 13e8aec9..6194a34f 100644 --- a/src/widgets/recmonitor_ui.ui +++ b/src/widgets/recmonitor_ui.ui @@ -6,8 +6,8 @@ 0 0 - 371 - 186 + 291 + 184 @@ -80,16 +80,6 @@ - - - - Preview while capturing - - - true - - - @@ -103,6 +93,25 @@ + + + + + Quick preview + + + + + Full preview + + + + + No preview + + + +