forked from andrewkirillov/AForge.NET
-
Notifications
You must be signed in to change notification settings - Fork 22
/
Copy pathVideoFileWriter.h
336 lines (307 loc) · 11.4 KB
/
VideoFileWriter.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
// AForge FFMPEG Library
// AForge.NET framework
// http://www.aforgenet.com/framework/
//
// Copyright © AForge.NET, 2009-2011
// contacts@aforgenet.com
//
#pragma once
using namespace System;
using namespace System::Drawing;
using namespace System::Drawing::Imaging;
using namespace AForge::Video;
#include "VideoCodec.h"
namespace AForge { namespace Video { namespace FFMPEG
{
ref struct WriterPrivateData;
/// <summary>
/// Class for writing video files utilizing FFmpeg library.
/// </summary>
///
/// <remarks><para>The class allows to write video files using <a href="http://www.ffmpeg.org/">FFmpeg</a> library.</para>
///
/// <para><note>Make sure you have <b>FFmpeg</b> binaries (DLLs) in the output folder of your application in order
/// to use this class successfully. <b>FFmpeg</b> binaries can be found in Externals folder provided with AForge.NET
/// framework's distribution.</note></para>
///
/// <para>Sample usage:</para>
/// <code>
/// int width = 320;
/// int height = 240;
///
/// // create instance of video writer
/// VideoFileWriter writer = new VideoFileWriter( );
/// // create new video file
/// writer.Open( "test.avi", width, height, 25, VideoCodec.MPEG4 );
/// // create a bitmap to save into the video file
/// Bitmap image = new Bitmap( width, height, PixelFormat.Format24bppRgb );
/// // write 1000 video frames
/// for ( int i = 0; i < 1000; i++ )
/// {
/// image.SetPixel( i % width, i % height, Color.Red );
/// writer.WriteVideoFrame( image );
/// }
/// writer.Close( );
/// </code>
/// </remarks>
///
public ref class VideoFileWriter : IDisposable
{
public:
/// <summary>
/// Frame width of the opened video file.
/// </summary>
///
/// <exception cref="System::IO::IOException">Thrown if no video file was open.</exception>
///
property int Width
{
int get( )
{
CheckIfVideoFileIsOpen( );
return m_width;
}
}
/// <summary>
/// Frame height of the opened video file.
/// </summary>
///
/// <exception cref="System::IO::IOException">Thrown if no video file was open.</exception>
///
property int Height
{
int get( )
{
CheckIfVideoFileIsOpen( );
return m_height;
}
}
/// <summary>
/// Frame rate of the opened video file.
/// </summary>
///
/// <exception cref="System::IO::IOException">Thrown if no video file was open.</exception>
///
property int FrameRate
{
int get( )
{
CheckIfVideoFileIsOpen( );
return m_frameRate;
}
}
/// <summary>
/// Bit rate of the video stream.
/// </summary>
///
/// <exception cref="System::IO::IOException">Thrown if no video file was open.</exception>
///
property int BitRate
{
int get( )
{
CheckIfVideoFileIsOpen( );
return m_bitRate;
}
}
/// <summary>
/// Codec to use for the video file.
/// </summary>
///
/// <exception cref="System::IO::IOException">Thrown if no video file was open.</exception>
///
property VideoCodec Codec
{
VideoCodec get( )
{
CheckIfVideoFileIsOpen( );
return m_codec;
}
}
/// <summary>
/// The property specifies if a video file is opened or not by this instance of the class.
/// </summary>
property bool IsOpen
{
bool get ( )
{
return ( data != nullptr );
}
}
protected:
/// <summary>
/// Object's finalizer.
/// </summary>
///
!VideoFileWriter( )
{
Close( );
}
public:
/// <summary>
/// Initializes a new instance of the <see cref="VideoFileWriter"/> class.
/// </summary>
///
VideoFileWriter( void );
/// <summary>
/// Disposes the object and frees its resources.
/// </summary>
///
~VideoFileWriter( )
{
this->!VideoFileWriter( );
disposed = true;
}
/// <summary>
/// Create video file with the specified name and attributes.
/// </summary>
///
/// <param name="fileName">Video file name to create.</param>
/// <param name="width">Frame width of the video file.</param>
/// <param name="height">Frame height of the video file.</param>
///
/// <remarks><para>See documentation to the <see cref="Open( String^, int, int, int, VideoCodec )" />
/// for more information and the list of possible exceptions.</para>
///
/// <para><note>The method opens the video file using <see cref="VideoCodec::Default" />
/// codec and 25 fps frame rate.</note></para>
/// </remarks>
///
void Open( String^ fileName, int width, int height );
/// <summary>
/// Create video file with the specified name and attributes.
/// </summary>
///
/// <param name="fileName">Video file name to create.</param>
/// <param name="width">Frame width of the video file.</param>
/// <param name="height">Frame height of the video file.</param>
/// <param name="frameRate">Frame rate of the video file.</param>
///
/// <remarks><para>See documentation to the <see cref="Open( String^, int, int, int, VideoCodec )" />
/// for more information and the list of possible exceptions.</para>
///
/// <para><note>The method opens the video file using <see cref="VideoCodec::Default" />
/// codec.</note></para>
/// </remarks>
///
void Open( String^ fileName, int width, int height, int frameRate );
/// <summary>
/// Create video file with the specified name and attributes.
/// </summary>
///
/// <param name="fileName">Video file name to create.</param>
/// <param name="width">Frame width of the video file.</param>
/// <param name="height">Frame height of the video file.</param>
/// <param name="frameRate">Frame rate of the video file.</param>
/// <param name="codec">Video codec to use for compression.</param>
///
/// <remarks><para>The methods creates new video file with the specified name.
/// If a file with such name already exists in the file system, it will be overwritten.</para>
///
/// <para>When adding new video frames using <see cref="WriteVideoFrame(Bitmap^ frame)"/> method,
/// the video frame must have width and height as specified during file opening.</para>
/// </remarks>
///
/// <exception cref="ArgumentException">Video file resolution must be a multiple of two.</exception>
/// <exception cref="ArgumentException">Invalid video codec is specified.</exception>
/// <exception cref="VideoException">A error occurred while creating new video file. See exception message.</exception>
/// <exception cref="System::IO::IOException">Cannot open video file with the specified name.</exception>
///
void Open( String^ fileName, int width, int height, int frameRate, VideoCodec codec );
/// <summary>
/// Create video file with the specified name and attributes.
/// </summary>
///
/// <param name="fileName">Video file name to create.</param>
/// <param name="width">Frame width of the video file.</param>
/// <param name="height">Frame height of the video file.</param>
/// <param name="frameRate">Frame rate of the video file.</param>
/// <param name="codec">Video codec to use for compression.</param>
/// <param name="bitRate">Bit rate of the video stream.</param>
///
/// <remarks><para>The methods creates new video file with the specified name.
/// If a file with such name already exists in the file system, it will be overwritten.</para>
///
/// <para>When adding new video frames using <see cref="WriteVideoFrame(Bitmap^ frame)"/> method,
/// the video frame must have width and height as specified during file opening.</para>
///
/// <para><note>The bit rate parameter represents a trade-off value between video quality
/// and video file size. Higher bit rate value increase video quality and result in larger
/// file size. Smaller values result in opposite – worse quality and small video files.</note></para>
/// </remarks>
///
/// <exception cref="ArgumentException">Video file resolution must be a multiple of two.</exception>
/// <exception cref="ArgumentException">Invalid video codec is specified.</exception>
/// <exception cref="VideoException">A error occurred while creating new video file. See exception message.</exception>
/// <exception cref="System::IO::IOException">Cannot open video file with the specified name.</exception>
///
void Open( String^ fileName, int width, int height, int frameRate, VideoCodec codec, int bitRate );
/// <summary>
/// Write new video frame into currently opened video file.
/// </summary>
///
/// <param name="frame">Bitmap to add as a new video frame.</param>
///
/// <remarks><para>The specified bitmap must be either color 24 or 32 bpp image or grayscale 8 bpp (indexed) image.</para>
/// </remarks>
///
/// <exception cref="System::IO::IOException">Thrown if no video file was open.</exception>
/// <exception cref="ArgumentException">The provided bitmap must be 24 or 32 bpp color image or 8 bpp grayscale image.</exception>
/// <exception cref="ArgumentException">Bitmap size must be of the same as video size, which was specified on opening video file.</exception>
/// <exception cref="VideoException">A error occurred while writing new video frame. See exception message.</exception>
///
void WriteVideoFrame( Bitmap^ frame );
/// <summary>
/// Write new video frame with a specific timestamp into currently opened video file.
/// </summary>
///
/// <param name="frame">Bitmap to add as a new video frame.</param>
/// <param name="timestamp">Frame timestamp, total time since recording started.</param>
///
/// <remarks><para>The specified bitmap must be either color 24 or 32 bpp image or grayscale 8 bpp (indexed) image.</para>
///
/// <para><note>The <paramref name="timestamp"/> parameter allows user to specify presentation
/// time of the frame being saved. However, it is user's responsibility to make sure the value is increasing
/// over time.</note></para>
/// </remarks>
///
/// <exception cref="System::IO::IOException">Thrown if no video file was open.</exception>
/// <exception cref="ArgumentException">The provided bitmap must be 24 or 32 bpp color image or 8 bpp grayscale image.</exception>
/// <exception cref="ArgumentException">Bitmap size must be of the same as video size, which was specified on opening video file.</exception>
/// <exception cref="VideoException">A error occurred while writing new video frame. See exception message.</exception>
///
void WriteVideoFrame( Bitmap^ frame, TimeSpan timestamp );
/// <summary>
/// Close currently opened video file if any.
/// </summary>
///
void Close( );
private:
int m_width;
int m_height;
int m_frameRate;
int m_bitRate;
VideoCodec m_codec;
private:
// Checks if video file was opened
void CheckIfVideoFileIsOpen( )
{
if ( data == nullptr )
{
throw gcnew System::IO::IOException( "Video file is not open, so can not access its properties." );
}
}
// Check if the object was already disposed
void CheckIfDisposed( )
{
if ( disposed )
{
throw gcnew System::ObjectDisposedException( "The object was already disposed." );
}
}
private:
// private data of the class
WriterPrivateData^ data;
bool disposed;
};
} } }