Medical Imaging Interaction Toolkit  2018.4.99-389bf124
Medical Imaging Interaction Toolkit
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 (DKFZ)
6 All rights reserved.
7 
8 Use of this source code is governed by a 3-clause BSD license that can be
9 found in the LICENSE file.
10 
11 ============================================================================*/
12 
13 #include "QmitkFFmpegWriter.h"
14 #include <QMessageBox>
15 #include <mitkExceptionMacro.h>
16 #include <mitkLogMacros.h>
17 
19  : QObject(parent), m_Process(new QProcess(this)), m_Framerate(0), m_IsRunning(false)
20 {
21  this->connect(m_Process, SIGNAL(error(QProcess::ProcessError)), this, SLOT(OnProcessError(QProcess::ProcessError)));
22 
23  this->connect(
24  m_Process, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(OnProcessFinished(int, QProcess::ExitStatus)));
25 }
26 
28 {
29 }
30 
32 {
33  return m_FFmpegPath;
34 }
35 
36 void QmitkFFmpegWriter::SetFFmpegPath(const QString &path)
37 {
38  m_FFmpegPath = path;
39 }
40 
42 {
43  return m_Size;
44 }
45 
46 void QmitkFFmpegWriter::SetSize(const QSize &size)
47 {
48  m_Size = size;
49 }
50 
51 void QmitkFFmpegWriter::SetSize(int width, int height)
52 {
53  m_Size = QSize(width, height);
54 }
55 
57 {
58  return m_Framerate;
59 }
60 
62 {
63  m_Framerate = framerate;
64 }
65 
67 {
68  return m_OutputPath;
69 }
70 
71 void QmitkFFmpegWriter::SetOutputPath(const QString &path)
72 {
73  m_OutputPath = path;
74 }
75 
77 {
78  if (m_FFmpegPath.isEmpty())
79  mitkThrow() << "FFmpeg/Libav path is empty!";
80 
81  if (m_Size.isNull())
82  mitkThrow() << "Invalid video frame size!";
83 
84  if (m_Framerate <= 0)
85  mitkThrow() << "Invalid framerate!";
86 
87  if (m_OutputPath.isEmpty())
88  mitkThrow() << "Output path is empty!";
89 
90  m_Process->start(m_FFmpegPath,
91  QStringList() << "-y"
92  << "-f"
93  << "rawvideo"
94  << "-pix_fmt"
95  << "rgb24"
96  << "-s"
97  << QString("%1x%2").arg(m_Size.width()).arg(m_Size.height())
98  << "-r"
99  << QString("%1").arg(m_Framerate)
100  << "-i"
101  << "-"
102  << "-vf"
103  << "vflip"
104  << "-pix_fmt"
105  << "yuv420p"
106  << "-crf"
107  << "18"
108  << m_OutputPath);
109 
110  m_Process->waitForStarted();
111  m_IsRunning = true;
112 }
113 
115 {
116  return m_IsRunning;
117 }
118 
119 void QmitkFFmpegWriter::WriteFrame(const unsigned char *frame)
120 {
121  if (frame == nullptr || !m_Process->isOpen())
122  return;
123 
124  m_Process->write(reinterpret_cast<const char *>(frame), m_Size.width() * m_Size.height() * 3);
125  m_Process->waitForBytesWritten();
126 }
127 
129 {
130  m_IsRunning = false;
131  m_Process->closeWriteChannel();
132 }
133 
134 void QmitkFFmpegWriter::OnProcessError(QProcess::ProcessError error)
135 {
136  m_IsRunning = false;
137 
138  MITK_ERROR << QString::fromLatin1(m_Process->readAllStandardError()).toStdString();
139 
140  switch (error)
141  {
142  case QProcess::FailedToStart:
143  mitkThrow() << "FFmpeg/Libav failed to start!";
144 
145  case QProcess::Crashed:
146  mitkThrow() << "FFmpeg/Libav crashed!";
147 
148  case QProcess::Timedout:
149  mitkThrow() << "FFmpeg/Libav timed out!";
150 
151  case QProcess::WriteError:
152  mitkThrow() << "Could not write to FFmpeg/Libav!";
153 
154  case QProcess::ReadError:
155  mitkThrow() << "Could not read from FFmpeg/Libav!";
156 
157  default:
158  mitkThrow() << "An unknown error occurred!";
159  }
160 }
161 
162 void QmitkFFmpegWriter::OnProcessFinished(int exitCode, QProcess::ExitStatus exitStatus)
163 {
164  m_IsRunning = false;
165 
166  if (exitStatus != QProcess::CrashExit)
167  {
168  if (exitCode != 0)
169  {
170  m_Process->close();
171  mitkThrow() << QString("FFmpeg/Libav exit code: %1").arg(exitCode).toStdString().c_str();
172  }
173  }
174 
175  m_Process->close();
176 }
#define MITK_ERROR
Definition: mitkLogMacros.h:20
void WriteFrame(const unsigned char *frame)
void SetFramerate(int framerate)
~QmitkFFmpegWriter() override
void SetFFmpegPath(const QString &path)
#define mitkThrow()
QString GetFFmpegPath() const
void SetSize(const QSize &size)
QmitkFFmpegWriter(QObject *parent=nullptr)
void SetOutputPath(const QString &path)
QString GetOutputPath() const