+void MltDeviceCapture::setOverlay(const QString &path)
+{
+ if (m_mltProducer == NULL || !m_mltProducer->is_valid()) return;
+ Mlt::Producer parentProd(m_mltProducer->parent());
+ if (parentProd.get_producer() == NULL) {
+ kDebug() << "PLAYLIST BROKEN, CANNOT INSERT CLIP //////";
+ return;
+ }
+
+ Mlt::Service service(parentProd.get_service());
+ if (service.type() != tractor_type) {
+ kWarning() << "// TRACTOR PROBLEM";
+ return;
+ }
+ Mlt::Tractor tractor(service);
+ if ( tractor.count() < 2) {
+ kWarning() << "// TRACTOR PROBLEM";
+ return;
+ }
+ mlt_service_lock(service.get_service());
+ Mlt::Producer trackProducer(tractor.track(0));
+ Mlt::Playlist trackPlaylist((mlt_playlist) trackProducer.get_service());
+
+ trackPlaylist.remove(0);
+ if (path.isEmpty()) {
+ mlt_service_unlock(service.get_service());
+ return;
+ }
+
+ // Add overlay clip
+ char *tmp = qstrdup(path.toUtf8().constData());
+ Mlt::Producer *clip = new Mlt::Producer (*m_mltProfile, "loader", tmp);
+ delete[] tmp;
+ clip->set_in_and_out(0, 99999);
+ trackPlaylist.insert_at(0, clip, 1);
+
+ // Add transition
+ mlt_service serv = m_mltProducer->parent().get_service();
+ mlt_service nextservice = mlt_service_get_producer(serv);
+ mlt_properties properties = MLT_SERVICE_PROPERTIES(nextservice);
+ QString mlt_type = mlt_properties_get(properties, "mlt_type");
+ if (mlt_type != "transition") {
+ // transition does not exist, add it
+ Mlt::Field *field = tractor.field();
+ Mlt::Transition *transition = new Mlt::Transition(*m_mltProfile, "composite");
+ transition->set_in_and_out(0, 0);
+ transition->set("geometry", "0/0:100%x100%:70");
+ transition->set("fill", 1);
+ transition->set("operator", "and");
+ transition->set("a_track", 0);
+ transition->set("b_track", 1);
+ field->plant_transition(*transition, 0, 1);
+ }
+ mlt_service_unlock(service.get_service());
+ //delete clip;
+}
+
+void MltDeviceCapture::setOverlayEffect(const QString &tag, QStringList parameters)
+{
+ if (m_mltProducer == NULL || !m_mltProducer->is_valid()) return;
+ Mlt::Service service(m_mltProducer->parent().get_service());
+ Mlt::Tractor tractor(service);
+ Mlt::Producer trackProducer(tractor.track(0));
+ Mlt::Playlist trackPlaylist((mlt_playlist) trackProducer.get_service());
+ Mlt::Service trackService(trackProducer.get_service());
+
+ mlt_service_lock(service.get_service());
+
+ // delete previous effects
+ Mlt::Filter *filter;
+ filter = trackService.filter(0);
+ if (filter && !tag.isEmpty()) {
+ QString currentService = filter->get("mlt_service");
+ if (currentService == tag) {
+ // Effect is already there
+ mlt_service_unlock(service.get_service());
+ return;
+ }
+ }
+ while (filter) {
+ trackService.detach(*filter);
+ delete filter;
+ filter = trackService.filter(0);
+ }
+
+ if (tag.isEmpty()) {
+ mlt_service_unlock(service.get_service());
+ return;
+ }
+
+ char *tmp = qstrdup(tag.toUtf8().constData());
+ filter = new Mlt::Filter(*m_mltProfile, tmp);
+ delete[] tmp;
+ if (filter && filter->is_valid()) {
+ for (int j = 0; j < parameters.count(); j++) {
+ filter->set(parameters.at(j).section('=', 0, 0).toUtf8().constData(), parameters.at(j).section('=', 1, 1).toUtf8().constData());
+ }
+ trackService.attach(*filter);
+ }
+ mlt_service_unlock(service.get_service());
+}
+
+void MltDeviceCapture::mirror(bool activate)
+{
+ if (m_mltProducer == NULL || !m_mltProducer->is_valid()) return;
+ Mlt::Service service(m_mltProducer->parent().get_service());
+ Mlt::Tractor tractor(service);
+ Mlt::Producer trackProducer(tractor.track(1));
+ Mlt::Playlist trackPlaylist((mlt_playlist) trackProducer.get_service());
+ Mlt::Service trackService(trackProducer.get_service());
+
+ mlt_service_lock(service.get_service());
+
+ // delete previous effects
+ Mlt::Filter *filter;
+ filter = trackService.filter(0);
+ while (filter) {
+ trackService.detach(*filter);
+ delete filter;
+ filter = trackService.filter(0);
+ }
+
+ if (!activate) {
+ mlt_service_unlock(service.get_service());
+ return;
+ }
+
+ filter = new Mlt::Filter(*m_mltProfile, "mirror");
+ if (filter && filter->is_valid()) {
+ filter->set("mirror", "flip");
+ trackService.attach(*filter);
+ }
+ 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;
+}
+
+