Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
QmitkFFmpegWriter.cpp
Go to the documentation of this file.
1 /*===================================================================
2 
3 The Medical Imaging Interaction Toolkit (MITK)
4 
5 Copyright (c) German Cancer Research Center,
6 Division of Medical and Biological Informatics.
7 All rights reserved.
8 
9 This software is distributed WITHOUT ANY WARRANTY; without
10 even the implied warranty of MERCHANTABILITY or FITNESS FOR
11 A PARTICULAR PURPOSE.
12 
13 See LICENSE.txt or http://www.mitk.org for details.
14 
15 ===================================================================*/
16 
17 #include "QmitkFFmpegWriter.h"
18 #include <QMessageBox>
19 #include <mitkExceptionMacro.h>
20 #include <mitkLogMacros.h>
21 
23  : QObject(parent), m_Process(new QProcess(this)), m_Framerate(0), m_IsRunning(false)
24 {
25  this->connect(m_Process, SIGNAL(error(QProcess::ProcessError)), this, SLOT(OnProcessError(QProcess::ProcessError)));
26 
27  this->connect(
28  m_Process, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(OnProcessFinished(int, QProcess::ExitStatus)));
29 }
30 
32 {
33 }
34 
36 {
37  return m_FFmpegPath;
38 }
39 
40 void QmitkFFmpegWriter::SetFFmpegPath(const QString &path)
41 {
42  m_FFmpegPath = path;
43 }
44 
46 {
47  return m_Size;
48 }
49 
50 void QmitkFFmpegWriter::SetSize(const QSize &size)
51 {
52  m_Size = size;
53 }
54 
55 void QmitkFFmpegWriter::SetSize(int width, int height)
56 {
57  m_Size = QSize(width, height);
58 }
59 
61 {
62  return m_Framerate;
63 }
64 
66 {
67  m_Framerate = framerate;
68 }
69 
71 {
72  return m_OutputPath;
73 }
74 
75 void QmitkFFmpegWriter::SetOutputPath(const QString &path)
76 {
77  m_OutputPath = path;
78 }
79 
81 {
82  if (m_FFmpegPath.isEmpty())
83  mitkThrow() << "FFmpeg/Libav path is empty!";
84 
85  if (m_Size.isNull())
86  mitkThrow() << "Invalid video frame size!";
87 
88  if (m_Framerate <= 0)
89  mitkThrow() << "Invalid framerate!";
90 
91  if (m_OutputPath.isEmpty())
92  mitkThrow() << "Output path is empty!";
93 
94  m_Process->start(m_FFmpegPath,
95  QStringList() << "-y"
96  << "-f"
97  << "rawvideo"
98  << "-pix_fmt"
99  << "rgb24"
100  << "-s"
101  << QString("%1x%2").arg(m_Size.width()).arg(m_Size.height())
102  << "-r"
103  << QString("%1").arg(m_Framerate)
104  << "-i"
105  << "-"
106  << "-vf"
107  << "vflip"
108  << "-pix_fmt"
109  << "yuv420p"
110  << "-crf"
111  << "18"
112  << m_OutputPath);
113 
114  m_Process->waitForStarted();
115  m_IsRunning = true;
116 }
117 
119 {
120  return m_IsRunning;
121 }
122 
123 void QmitkFFmpegWriter::WriteFrame(const unsigned char *frame)
124 {
125  if (frame == nullptr || !m_Process->isOpen())
126  return;
127 
128  m_Process->write(reinterpret_cast<const char *>(frame), m_Size.width() * m_Size.height() * 3);
129  m_Process->waitForBytesWritten();
130 }
131 
133 {
134  m_IsRunning = false;
135  m_Process->closeWriteChannel();
136 }
137 
138 void QmitkFFmpegWriter::OnProcessError(QProcess::ProcessError error)
139 {
140  m_IsRunning = false;
141 
142  MITK_ERROR << QString::fromLatin1(m_Process->readAllStandardError()).toStdString();
143 
144  switch (error)
145  {
146  case QProcess::FailedToStart:
147  mitkThrow() << "FFmpeg/Libav failed to start!";
148 
149  case QProcess::Crashed:
150  mitkThrow() << "FFmpeg/Libav crashed!";
151 
152  case QProcess::Timedout:
153  mitkThrow() << "FFmpeg/Libav timed out!";
154 
155  case QProcess::WriteError:
156  mitkThrow() << "Could not write to FFmpeg/Libav!";
157 
158  case QProcess::ReadError:
159  mitkThrow() << "Could not read from FFmpeg/Libav!";
160 
161  default:
162  mitkThrow() << "An unknown error occurred!";
163  }
164 }
165 
166 void QmitkFFmpegWriter::OnProcessFinished(int exitCode, QProcess::ExitStatus exitStatus)
167 {
168  m_IsRunning = false;
169 
170  if (exitStatus != QProcess::CrashExit)
171  {
172  if (exitCode != 0)
173  {
174  m_Process->close();
175  mitkThrow() << QString("FFmpeg/Libav exit code: %1").arg(exitCode).toStdString().c_str();
176  }
177  }
178 
179  m_Process->close();
180 }
QString GetOutputPath() const
#define MITK_ERROR
Definition: mitkLogMacros.h:24
void WriteFrame(const unsigned char *frame)
int GetFramerate() const
void SetFramerate(int framerate)
void SetFFmpegPath(const QString &path)
#define mitkThrow()
void SetSize(const QSize &size)
QSize GetSize() const
QString GetFFmpegPath() const
QmitkFFmpegWriter(QObject *parent=nullptr)
void SetOutputPath(const QString &path)