all repos — mgba @ ce2fe95814765702fd5bed1f1596ebbd7f766c11

mGBA Game Boy Advance Emulator

src/platform/qt/GIFView.cpp (view raw)

  1/* Copyright (c) 2013-2014 Jeffrey Pfau
  2 *
  3 * This Source Code Form is subject to the terms of the Mozilla Public
  4 * License, v. 2.0. If a copy of the MPL was not distributed with this
  5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  6#include "GIFView.h"
  7
  8#ifdef USE_FFMPEG
  9
 10#include "CoreController.h"
 11#include "GBAApp.h"
 12#include "LogController.h"
 13
 14#include <QMap>
 15
 16using namespace QGBA;
 17
 18GIFView::GIFView(QWidget* parent)
 19	: QWidget(parent)
 20{
 21	m_ui.setupUi(this);
 22
 23	connect(m_ui.start, &QAbstractButton::clicked, this, &GIFView::startRecording);
 24	connect(m_ui.stop, &QAbstractButton::clicked, this, &GIFView::stopRecording);
 25
 26	connect(m_ui.selectFile, &QAbstractButton::clicked, this, &GIFView::selectFile);
 27	connect(m_ui.filename, &QLineEdit::textChanged, this, &GIFView::setFilename);
 28	connect(m_ui.fmtGif, &QAbstractButton::clicked, this, &GIFView::changeExtension);
 29	connect(m_ui.fmtApng, &QAbstractButton::clicked, this, &GIFView::changeExtension);
 30	connect(m_ui.fmtWebP, &QAbstractButton::clicked, this, &GIFView::changeExtension);
 31
 32	FFmpegEncoderInit(&m_encoder);
 33	FFmpegEncoderSetAudio(&m_encoder, nullptr, 0);
 34}
 35
 36GIFView::~GIFView() {
 37	stopRecording();
 38}
 39
 40void GIFView::setController(std::shared_ptr<CoreController> controller) {
 41	connect(controller.get(), &CoreController::stopping, this, &GIFView::stopRecording);
 42	connect(this, &GIFView::recordingStarted, controller.get(), &CoreController::setAVStream);
 43	connect(this, &GIFView::recordingStopped, controller.get(), &CoreController::clearAVStream, Qt::DirectConnection);
 44	QSize size(controller->screenDimensions());
 45	FFmpegEncoderSetDimensions(&m_encoder, size.width(), size.height());
 46}
 47
 48void GIFView::startRecording() {
 49	if (m_ui.fmtWebP->isChecked()) {
 50		FFmpegEncoderSetContainer(&m_encoder, "webp");
 51		FFmpegEncoderSetVideo(&m_encoder, "libwebp_anim", 0, m_ui.frameskip->value());
 52	} else if (m_ui.fmtApng->isChecked()) {
 53		FFmpegEncoderSetContainer(&m_encoder, "apng");
 54		FFmpegEncoderSetVideo(&m_encoder, "apng", 0, m_ui.frameskip->value());
 55	} else {
 56		FFmpegEncoderSetContainer(&m_encoder, "gif");
 57		FFmpegEncoderSetVideo(&m_encoder, "gif", 0, m_ui.frameskip->value());
 58	}
 59	FFmpegEncoderSetLooping(&m_encoder, m_ui.loop->isChecked());
 60	if (!FFmpegEncoderOpen(&m_encoder, m_filename.toUtf8().constData())) {
 61		LOG(QT, ERROR) << tr("Failed to open output file: %1").arg(m_filename);
 62		return;
 63	}
 64	m_ui.start->setEnabled(false);
 65	m_ui.stop->setEnabled(true);
 66	m_ui.frameskip->setEnabled(false);
 67	m_ui.loop->setEnabled(false);
 68	m_ui.fmtWebP->setEnabled(false);
 69	m_ui.fmtApng->setEnabled(false);
 70	m_ui.fmtGif->setEnabled(false);
 71	m_ui.fmtWebP->setEnabled(false);
 72	emit recordingStarted(&m_encoder.d);
 73}
 74
 75void GIFView::stopRecording() {
 76	emit recordingStopped();
 77	FFmpegEncoderClose(&m_encoder);
 78	m_ui.stop->setEnabled(false);
 79	m_ui.start->setEnabled(!m_filename.isEmpty());
 80	m_ui.frameskip->setEnabled(true);
 81	m_ui.loop->setEnabled(true);
 82	m_ui.fmtWebP->setEnabled(true);
 83	m_ui.fmtApng->setEnabled(true);
 84	m_ui.fmtGif->setEnabled(true);
 85}
 86
 87void GIFView::selectFile() {
 88	QString filename = GBAApp::app()->getSaveFileName(this, tr("Select output file"), tr("Graphics Interchange Format (*.gif);;WebP ( *.webp);;Animated Portable Network Graphics (*.png *.apng)"));
 89	m_ui.filename->setText(filename);
 90}
 91
 92void GIFView::setFilename(const QString& filename) {
 93	m_filename = filename;
 94	if (!FFmpegEncoderIsOpen(&m_encoder)) {
 95		m_ui.start->setEnabled(!filename.isEmpty());
 96		if (filename.endsWith(".gif")) {
 97			m_ui.fmtGif->setChecked(true);
 98		} else if (filename.endsWith(".png") || filename.endsWith(".apng")) {
 99			m_ui.fmtApng->setChecked(true);
100		} else if (filename.endsWith(".webp")) {
101			m_ui.fmtWebP->setChecked(true);
102		}
103	}
104}
105
106void GIFView::changeExtension() {
107	if (m_filename.isEmpty()) {
108		return;
109	}
110	QString filename = m_filename;
111	int index = m_filename.lastIndexOf(".");
112	if (index >= 0) {
113		filename.truncate(index);
114	}
115	if (m_ui.fmtGif->isChecked()) {
116		filename += ".gif";
117	} else if (m_ui.fmtWebP->isChecked()) {
118		filename += ".webp";
119	} else if (m_ui.fmtApng->isChecked()) {
120		filename += ".png";
121	}
122	m_ui.filename->setText(filename);
123}
124
125#endif