Medical Imaging Interaction Toolkit  2016.11.0
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,
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)