0029112: Visualization - compilation fails on Ubuntu with libavutil 54.x (FFmpeg...
[occt.git] / src / Image / Image_VideoRecorder.hxx
1 // Created on: 2016-04-01
2 // Created by: Anastasia BORISOVA
3 // Copyright (c) 2016 OPEN CASCADE SAS
4 //
5 // This file is part of Open CASCADE Technology software library.
6 //
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
12 //
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
15
16 #ifndef Image_VideoRecorder_HeaderFile_
17 #define Image_VideoRecorder_HeaderFile_
18
19 #include <Image_PixMap.hxx>
20 #include <Resource_DataMapOfAsciiStringAsciiString.hxx>
21 #include <Standard_Transient.hxx>
22 #include <TCollection_AsciiString.hxx>
23
24 // forward declarations
25 struct AVFormatContext;
26 struct AVStream;
27 struct AVCodec;
28 struct AVFrame;
29 struct SwsContext;
30
31 // Undefine macro that clashes with name used by field of Image_VideoParams;
32 // this macro is defined in headers of older versions of libavutil
33 // (see definition of macro FF_API_PIX_FMT in version.h)
34 #ifdef PixelFormat
35 #undef PixelFormat
36 #endif
37
38 //! Auxiliary structure defining video parameters.
39 //! Please refer to FFmpeg documentation for defining text values.
40 struct Image_VideoParams
41 {
42   TCollection_AsciiString Format;           //!< [optional]  video format (container), if empty - will be determined from the file name
43   TCollection_AsciiString VideoCodec;       //!< [optional]  codec identifier, if empty - default codec from file format will be used
44   TCollection_AsciiString PixelFormat;      //!< [optional]  pixel format, if empty - default codec pixel format will be used
45   Standard_Integer        Width;            //!< [mandatory] video frame width
46   Standard_Integer        Height;           //!< [mandatory] video frame height
47   Standard_Integer        FpsNum;           //!< [mandatory] framerate numerator
48   Standard_Integer        FpsDen;           //!< [mandatory] framerate denumerator
49   Resource_DataMapOfAsciiStringAsciiString
50                           VideoCodecParams; //!< map of advanced video codec parameters
51
52   //! Empty constructor.
53   Image_VideoParams() : Width (0), Height (0), FpsNum (0), FpsDen (1) {}
54
55   //! Setup playback FPS.
56   void SetFramerate (const Standard_Integer theNumerator,
57                      const Standard_Integer theDenominator)
58   {
59     FpsNum = theNumerator;
60     FpsDen = theDenominator;
61   }
62
63   //! Setup playback FPS.
64   //! For fixed-fps content, timebase should be 1/framerate and timestamp increments should be identical to 1.
65   void SetFramerate (const Standard_Integer theValue)
66   {
67     FpsNum = theValue;
68     FpsDen = 1;
69   }
70 };
71
72 //! Video recording tool based on FFmpeg framework.
73 class Image_VideoRecorder : public Standard_Transient
74 {
75   DEFINE_STANDARD_RTTIEXT(Image_VideoRecorder, Standard_Transient)
76 public:
77
78   //! Empty constructor.
79   Standard_EXPORT Image_VideoRecorder();
80
81   //! Destructor.
82   Standard_EXPORT virtual ~Image_VideoRecorder();
83
84   //! Close the stream - stop recorder.
85   Standard_EXPORT void Close();
86
87   //! Open output stream - initialize recorder.
88   //! @param theFileName [in] video filename
89   //! @param theParams   [in] video parameters
90   Standard_EXPORT Standard_Boolean Open (const char* theFileName,
91                                          const Image_VideoParams& theParams);
92
93   //! Access RGBA frame, should NOT be re-initialized outside.
94   //! Note that image is expected to have upper-left origin.
95   Image_PixMap& ChangeFrame() { return myImgSrcRgba; }
96
97   //! Return current frame index.
98   int64_t FrameCount() const { return myFrameCount; }
99
100   //! Push new frame, should be called after Open().
101   Standard_Boolean PushFrame()
102   {
103     return writeVideoFrame (Standard_False);
104   }
105
106 protected:
107
108   //! Wrapper for av_strerror().
109   Standard_EXPORT TCollection_AsciiString formatAvError (const int theError) const;
110
111   //! Append video stream.
112   //! theParams     [in] video parameters
113   //! theDefCodecId [in] identifier of codec managed by FFmpeg library (AVCodecID enum)
114   Standard_EXPORT Standard_Boolean addVideoStream (const Image_VideoParams& theParams,
115                                                    const Standard_Integer   theDefCodecId);
116
117   //! Open video codec.
118   Standard_EXPORT Standard_Boolean openVideoCodec (const Image_VideoParams& theParams);
119
120   //! Write new video frame.
121   Standard_EXPORT Standard_Boolean writeVideoFrame (const Standard_Boolean theToFlush);
122
123 protected:
124
125   //! AVRational alias.
126   struct VideoRational
127   {
128     int num; //!< numerator
129     int den; //!< denominator
130   };
131
132 protected:
133
134   AVFormatContext* myAVContext;   //!< video context
135   AVStream*        myVideoStream; //!< video stream
136   AVCodec*         myVideoCodec;  //!< video codec
137   AVFrame*         myFrame;       //!< frame to record
138   SwsContext*      myScaleCtx;    //!< scale context for conversion from RGBA to YUV
139
140   Image_PixMap     myImgSrcRgba;  //!< input RGBA image
141   VideoRational    myFrameRate;   //!< video framerate
142   int64_t          myFrameCount;  //!< current frame index
143
144 };
145
146 DEFINE_STANDARD_HANDLE(Image_VideoRecorder, Standard_Transient)
147
148 #endif // Image_VideoRecorder_HeaderFile_