summaryrefslogtreecommitdiff
path: root/inc/OpenGl_AVIWriter.hxx
blob: c96b5901d024cd9e9a0e82ab108c53d8e20e98b5 (plain)
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
// File:      OpenGl_AVIWriter.hxx
// Created:   15.04.07 12:53
// Author:    Alexey MORENOV & Alexander GRIGORIEV
// Copyright: Open CASCADE 2007

#ifndef __OPENGL_AVIWRITER_H
#define __OPENGL_AVIWRITER_H

#ifdef WNT
#define THIS void 

#include <InterfaceGraphic_WNT.hxx>
#include <stdlib.h>
#include <vfw.h>
#include <TCollection_AsciiString.hxx>

/**
 * Class providing the API to record AVI files using a codec installed in the
 * system -- Only on Windows NT/2k/XP/Vista platform under MS Visual Studio.
 * The following tasks are supported:
 * <ol>
 *
 * <li> Creation of AVI data stream: launched by the constructor.<br>
 * The constructor accepts the filename, FOURCC video code and the frame rate
 * setting as parameters.<br>
 * The default codec name used here is MPG4. To use a different codec, pass
 * its FOURCC value as the input parameter for dwCodec.
 * For example,
 * <ul>
 * <li>pass mmioFOURCC('D','I','V','X') to use DIVX codec, or</li>
 * <li>pass mmioFOURCC('I','V','5','0') to use IV50 codec etc...</li>
 * </ul>
 * Also, you can pass just 0 to avoid the codecs altogether. In that case,
 * the frames would be saved as they are without any compression; However,
 * the output movie file size would be very huge in that case.
 * <br>
 * Finally, make sure you have the codec installed on the machine before
 * passing its Fourcc here.
 * </li>
 * <li>
 * Start the recording: call the method StartRecording(). This method should be
 * called at least once; execution of the constructor does not begin the
 * process.
 * </li>
 * <li>
 * Stop the recording: call the method StopRecording(). Can be omitted if the
 * next to execute would be the destructor.
 * </li>
 * <li>
 * Close the AVI file and exit the process of recording. This is done
 * automatically by the destructor.
 * </li>
 * </ol>
 */
class OpenGl_AVIWriter
{
public:

  /**
   * Constructor. Initializes the internal data structures, prepares for the
   * creation of an AVI stream when the first frame is ready to be captured.
   * @param theFileName
   *   Name of the output movie file to create.
   * @param theCodec
   *   FourCC of the Video Codec to be used for compression
   * @param theFrameRate
   *   The Frames Per Second (FPS) setting to be used for the movie
   */
  Standard_EXPORT OpenGl_AVIWriter(const char * theFileName, 
                                   DWORD theCodec = mmioFOURCC('M','P','G','4'),
                                   Standard_Integer theFrameRate = 25);

  /**
   * Destructor: closes the movie file and flushes all the frames
   */
  Standard_EXPORT ~OpenGl_AVIWriter     ();

  /**
   * Begin the recording.
   */
  Standard_EXPORT void    StartRecording(const HANDLE hWin = NULL);

  /**
   * Stop the recording (can be restarted using StartRecording()).
   */
  Standard_EXPORT void    StopRecording ();

  /**
   * Query the state of recording.
   */
  inline Standard_Boolean IsRecording   () const { return myIsAllowRecord; }

  /**
   * Returns the last error message, if any.
   */
  inline Standard_EXPORT const TCollection_AsciiString&
                          GetLastErrorMessage() const
  { return myErrMsg; }

  /**
   * Get the instance of AVI Writer class.
   */ 
  static Standard_EXPORT OpenGl_AVIWriter *
                          GetInstance   ();

  /**
   * Get the Window handle that contains the actual OpenGl context.
   */
  inline HANDLE           HWindow () const
  { return myhWindow; }

  /// Inserts the given HBitmap into the movie as a new Frame at the end.
  HRESULT         AppendNewFrame(HBITMAP hBitmap);

  /// Inserts the given bitmap bits into the movie as a new Frame at the end.
  /// The width, height and nBitsPerPixel are the width, height and bits per pixel
  /// of the bitmap pointed to by the input pBits.
  HRESULT         AppendNewFrame(int nWidth,
                                 int nHeight,
                                 LPVOID pBits,
                                 int nBitsPerPixel);

private:

  void call_avi();

private:
  static OpenGl_AVIWriter       * MyAVIWriterInstance;
  Standard_Boolean                myIsAllowRecord;

  BYTE                          * mypBits;
  UINT                            myWidth;
  UINT                            myHeight;

  HDC                   myhAviDC;
  HANDLE                myhHeap;
  HANDLE                myhWindow;   // window containing the OGL context 
  LPVOID                mylpBits;    // Useful to hold the bitmap content if any
  LONG                  mylSample;   // Keeps track of the current Frame Index
  PAVIFILE              mypAviFile;
  PAVISTREAM            mypAviStream;
  PAVISTREAM            mypAviCompressedStream;
  AVISTREAMINFO         myAviStreamInfo;
  AVICOMPRESSOPTIONS    myAviCompressOptions;
  char *                myFileName; // Holds the Output Movie File Name
  TCollection_AsciiString myErrMsg; // Holds the Last Error Message, if any

  int                   myAppendFuncSelector;  //0=Dummy 1=FirstTime 2=Usual

  HRESULT               AppendFrameFirstTime(HBITMAP );
  HRESULT               AppendFrameUsual(HBITMAP);
  HRESULT               AppendDummy(HBITMAP);
  HRESULT       (OpenGl_AVIWriter::*pAppendFrame[3])(HBITMAP hBitmap);

  HRESULT               AppendFrameBitsFirstTime(int, int, LPVOID,int );
  HRESULT               AppendFrameBitsUsual(int, int, LPVOID,int );
  HRESULT               AppendDummyBits(int, int, LPVOID,int );
  HRESULT       (OpenGl_AVIWriter::*pAppendFrameBits[3])(int, int, LPVOID, int);

  /// Takes care of creating the memory, streams, compression options etc.
  /// required for the movie
  HRESULT InitMovieCreation(int nFrameWidth,int nFrameHeight,int nBitsPerPixel);

  /// Takes care of releasing the memory and movie related handles
  void ReleaseMemory();

  /// Sets the Error Message
  void SetErrorMessage(const char * theErrMsg);
};

Standard_EXPORT void OpenGl_AVIWriter_AVIWriter(void * pp,
                                                int  nWidth,
                                                int  nHeight,
                                                int  nBitsPerPixel);

Standard_EXPORT Standard_Boolean OpenGl_AVIWriter_AllowWriting(void * hWin);

#endif // WNT
#endif