Menu

[r15]: / FFMS2 Wrapper VideoSource.cs  Maximize  Restore  History

Download this file

352 lines (291 with data), 12.0 kB

  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
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
//Title: FFMS2 .NET Wrapper Alpha v 0.1
//Author: Francisco José Soto Portillo (_TheAway)
//You are free to use and share this code
using System;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.Text;
using System.Collections;
using System.Drawing;
namespace FFMS2
{
#region Model data
/**
* Contiene los datos internos sobre cada track del video
* */
public struct TrackData
{
public int TrackType;
public string Codec;
}
public struct FFMS_FrameInfo
{
public long PTS;
public int RepeatPict;
public int KeyFrame;
};
public class Track
{
public IntPtr PTrack;
public string TrackName;
public int TrackType;
}
enum FFMS_SeekMode
{
FFMS_SEEK_LINEAR_NO_RW = -1,
FFMS_SEEK_LINEAR = 0,
FFMS_SEEK_NORMAL = 1,
FFMS_SEEK_UNSAFE = 2,
FFMS_SEEK_AGGRESSIVE = 3
};
public unsafe struct FFMS_SourceData
{
public int NumTracks;
public int NumFrames;
public string Source;
public ArrayList Tracks; //Arraylist de TrackData
}
public struct FFMS_Frame
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
public IntPtr[] Data;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
public int[] Linesize;
public int EncodedWidth;
public int EncodedHeight;
public int EncodedPixelFormat;
public int ScaledWidth;
public int ScaledHeight;
public int ConvertedPixelFormat;
public int KeyFrame;
public int RepeatPict;
public int InterlacedFrame;
public int TopFieldFirst;
public char PictType;
}
enum FFMS_Resizers
{
FFMS_RESIZER_FAST_BILINEAR = 0x01,
FFMS_RESIZER_BILINEAR = 0x02,
FFMS_RESIZER_BICUBIC = 0x04,
FFMS_RESIZER_X = 0x08,
FFMS_RESIZER_POINT = 0x10,
FFMS_RESIZER_AREA = 0x20,
FFMS_RESIZER_BICUBLIN = 0x40,
FFMS_RESIZER_GAUSS = 0x80,
FFMS_RESIZER_SINC = 0x100,
FFMS_RESIZER_LANCZOS = 0x200,
FFMS_RESIZER_SPLINE = 0x400
};
enum FFMS_AudioDelayModes
{
FFMS_DELAY_NO_SHIFT = -3,
FFMS_DELAY_TIME_ZERO = -2,
FFMS_DELAY_FIRST_VIDEO_TRACK = -1,
};
public struct FFMS_VideoProperties
{
public int FPSDenominator;
public int FPSNumerator;
public int RFFDenominator;
public int RFFNumerator;
public int NumFrames;
public int SARNum;
public int SARDen;
public int CropTop;
public int CropBottom;
public int CropLeft;
public int CropRight;
public int TopFieldFirst;
public int ColorSpace;
public int ColorRange;
public double FirstTime;
public double LastTime;
};
public struct FFMS_AudioProperties
{
public int SampleFormat;
public int SampleRate;
public int BitsPerSample;
public int Channels;
public Int64 ChannelLayout;
public Int64 NumSamples;
public double FirstTime;
public double LastTime;
};
#endregion
#region VideoSource
public class FFMS2Track
{
ArrayList TrackList;
FFMS_SourceData Data;
IntPtr VideoSource;
IntPtr AudioSource;
FFMS_ErrorInfo Error;
#region dinamic library functions
[DllImport("ffms2.dll", SetLastError = false, CharSet = CharSet.Ansi)]
private static extern IntPtr FFMS_GetTrackFromIndex(IntPtr Index, int Track);
[DllImport("ffms2.dll", SetLastError = false, CharSet = CharSet.Ansi)]
private static extern IntPtr FFMS_GetFrameInfo(IntPtr Track, int Frame);
[DllImport("ffms2.dll", SetLastError = false, CharSet = CharSet.Ansi)]
private static extern int FFMS_GetNumFrames(IntPtr Track);
[DllImport("ffms2.dll", SetLastError = false, CharSet = CharSet.Ansi)]
private static extern IntPtr FFMS_CreateVideoSource(string SourceFile, int Track, IntPtr FFMS_Index, int Threads, int SeekMode, ref FFMS_ErrorInfo ErrorInfo);
[DllImport("ffms2.dll", SetLastError = false, CharSet = CharSet.Ansi)]
private static extern IntPtr FFMS_CreateAudioSource(string SourceFile, int Track, IntPtr Index, ref FFMS_ErrorInfo ErrorInfo);
[DllImport("ffms2.dll", SetLastError = false, CharSet = CharSet.Ansi)]
private static extern IntPtr FFMS_GetFrame(IntPtr VideoSource, int n, ref FFMS_ErrorInfo ErrorInfo);
[DllImport("ffms2.dll", SetLastError = false, CharSet = CharSet.Ansi)]
private static extern int FFMS_GetAudio(IntPtr AudioSource, IntPtr AudioBuffer, long Start, long Count, ref FFMS_ErrorInfo ErrorInfo);
[DllImport("ffms2.dll", SetLastError = false, CharSet = CharSet.Ansi)]
private static extern int FFMS_SetOutputFormatV(IntPtr VideoSource, Int64 TargetFormats, int Width, int Height, int Resizer, ref FFMS_ErrorInfo ErrorInfo);
[DllImport("ffms2.dll", SetLastError = false, CharSet = CharSet.Ansi)]
private static extern int FFMS_GetPixFmt(string Name);
[DllImport("ffms2.dll", SetLastError = false, CharSet = CharSet.Ansi)]
private static extern IntPtr FFMS_GetVideoProperties(IntPtr VideoSource);
[DllImport("ffms2.dll", SetLastError = false, CharSet = CharSet.Ansi)]
private static extern IntPtr FFMS_GetAudioProperties(IntPtr AudioSource);
#endregion
#region Track
public FFMS2Track(FFMS_SourceData Data)
{
this.Data = Data;
TrackList = new ArrayList();
this.Error = new FFMS_ErrorInfo();
}
public void GetTrack(IntPtr Index, int Track)
{
Track Dummytrack = new Track();
Dummytrack.PTrack = FFMS_GetTrackFromIndex(Index, Track);
Dummytrack.TrackName = (string)((TrackData)Data.Tracks[Track]).Codec;
Dummytrack.TrackType = ((TrackData)Data.Tracks[Track]).TrackType;
TrackList.Add(Dummytrack);
}
public FFMS_ErrorInfo GetError()
{
return Error;
}
public FFMS_FrameInfo GetFrameInfo(int Track, int Frame)
{
IntPtr track = ((Track)TrackList[Track]).PTrack;
IntPtr ffmsfi = FFMS_GetFrameInfo(track, Frame);
FFMS_FrameInfo ffmsifi1 = (FFMS_FrameInfo)Marshal.PtrToStructure(ffmsfi, typeof(FFMS_FrameInfo));
return ffmsifi1;
}
public int GetNumFrames(int Track)
{
IntPtr track = ((Track)TrackList[Track]).PTrack;
return FFMS_GetNumFrames(track);
}
#endregion
#region VideoSource
/**
* Create a new VideoSource from File
*
* If Track integer isn't a video track throw an exception
*
* */
public void CreateVideoSource(string File, int Track, IntPtr Index, int Threads, int SeekMode)
{
Track track = (Track)TrackList[Track];
//int video_type = (int)FFMS_TrackType.FFMS_TYPE_VIDEO;
if (track.TrackType == (int)FFMS_TrackType.FFMS_TYPE_VIDEO)
this.VideoSource = FFMS_CreateVideoSource(File, Track, Index, Threads, SeekMode, ref Error);
else
throw new Exception("Track n#" + Track + " no es una pista de Video");
}
/**
* Selecciona el formato de salida del video.
*
* Debe inicializarse ante el VideoSource
*
* devuelve 0 si no hay errores
*
* */
public int SetVideoOutput(int Width, int Height, int Resizer, string TargetFormat)
{
int ret = 0;
if (VideoSource == IntPtr.Zero)
throw new Exception("No se ha inicializado el Video, use CreateVideoSource");
Int64 TargetFormats = (1 << FFMS_GetPixFmt(TargetFormat));
if (TargetFormats == -1)
throw new Exception("El formato de salida de video indicado no existe.");
ret = FFMS_SetOutputFormatV(VideoSource, TargetFormats, Width, Height, Resizer, ref Error);
return ret;
}
/**
* Selecciona y devuelve un frame del video
*
* Debe inicializarse ante el VideoSource
*
* devuelve el objeto FFMS_Frame
*
* */
public FFMS_Frame GetFrame(int NumFrame)
{
if (VideoSource == IntPtr.Zero)
throw new Exception("No se ha inicializado el Video, use CreateVideoSource");
IntPtr pFrame = FFMS_GetFrame(this.VideoSource, NumFrame, ref Error);
FFMS_Frame frame = (FFMS_Frame)Marshal.PtrToStructure(pFrame, typeof(FFMS_Frame));
return frame;
}
public FFMS_VideoProperties GetVideoProperties()
{
if (VideoSource == IntPtr.Zero)
throw new Exception("No se ha inicializado el Video, use CreateVideoSource");
IntPtr pVideo = FFMS_GetVideoProperties(this.VideoSource);
FFMS_VideoProperties video = (FFMS_VideoProperties)Marshal.PtrToStructure(pVideo, typeof(FFMS_VideoProperties));
return video;
}
public Bitmap ConvertToBitmap(FFMS_Frame frame)
{
Bitmap ret = null;
if (frame.ConvertedPixelFormat == 30)
ret = new Bitmap(frame.ScaledWidth, frame.ScaledHeight, frame.ScaledWidth * 4, System.Drawing.Imaging.PixelFormat.Format32bppRgb, frame.Data[0]);
return ret;
}
#endregion
#region AudioSource
/**
* Create a new AudioSource from File
*
* If Track integer isn't a audio track throw an exception
*
* */
public void CreateAudioSource(string File, int Track, int DelayMode, IntPtr Index)
{
Track track = (Track)TrackList[Track];
if (track.TrackType == (int)FFMS_TrackType.FFMS_TYPE_AUDIO)
this.AudioSource = FFMS_CreateAudioSource(File, Track, Index, ref Error);
else
throw new Exception("Track n#" + Track + " no es una pista de Audio");
}
public FFMS_AudioProperties GetAudioProperties()
{
if (AudioSource == IntPtr.Zero)
throw new Exception("No se ha inicializado el Audio, use CreateAudioSource");
IntPtr pAudio = FFMS_GetAudioProperties(this.AudioSource);
FFMS_AudioProperties audio = (FFMS_AudioProperties)Marshal.PtrToStructure(pAudio, typeof(FFMS_AudioProperties));
return audio;
}
public byte[] GetAudio(long Start, long Count)
{
byte[] ret;
if (AudioSource == IntPtr.Zero)
throw new Exception("No se ha inicializado el Audio, use CreateAudioSource");
FFMS_AudioProperties audioProperties = GetAudioProperties();
if ((Count + Start) >= audioProperties.NumSamples)
{
Count = audioProperties.NumSamples-Start-1;
}
int length = (int)((audioProperties.BitsPerSample / 8) * Count * audioProperties.Channels)+1;
ret = new byte[length];
IntPtr AudioBuffer = Marshal.AllocHGlobal(length);
int aux = FFMS_GetAudio(AudioSource, AudioBuffer, Start, Count, ref Error);
Marshal.Copy(AudioBuffer, ret, 0, (int)Count);
return ret;
}
#endregion
}
#endregion
}