0030700: Visualization, TKOpenGl - support PBR Metallic-Roughness shading model
[occt.git] / src / Media / Media_Frame.cxx
1 // Created by: Kirill GAVRILOV
2 // Copyright (c) 2019 OPEN CASCADE SAS
3 //
4 // This file is part of Open CASCADE Technology software library.
5 //
6 // This library is free software; you can redistribute it and/or modify it under
7 // the terms of the GNU Lesser General Public License version 2.1 as published
8 // by the Free Software Foundation, with special exception defined in the file
9 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10 // distribution for complete text of the license and disclaimer of any warranty.
11 //
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
14
15 // activate some C99 macros like UINT64_C in "stdint.h" which used by FFmpeg
16 #ifndef __STDC_CONSTANT_MACROS
17   #define __STDC_CONSTANT_MACROS
18 #endif
19
20 #include <Media_Frame.hxx>
21
22 #include <Media_Scaler.hxx>
23
24 #ifdef HAVE_FFMPEG
25 #include <Standard_WarningsDisable.hxx>
26 extern "C"
27 {
28   #include <libavcodec/avcodec.h>
29   #include <libavutil/imgutils.h>
30 };
31 #include <Standard_WarningsRestore.hxx>
32 #endif
33
34 IMPLEMENT_STANDARD_RTTIEXT(Media_Frame, Standard_Transient)
35
36 // =======================================================================
37 // function : FormatFFmpeg2Occt
38 // purpose  :
39 // =======================================================================
40 Image_Format Media_Frame::FormatFFmpeg2Occt (int theFormat)
41 {
42 #ifdef HAVE_FFMPEG
43   switch (theFormat)
44   {
45     case AV_PIX_FMT_RGBA:
46       return Image_Format_RGBA;
47     case AV_PIX_FMT_BGRA:
48       return Image_Format_BGRA;
49     case AV_PIX_FMT_RGB0:
50       return Image_Format_RGB32;
51     case AV_PIX_FMT_BGR0:
52       return Image_Format_BGR32;
53     case AV_PIX_FMT_RGB24:
54       return Image_Format_RGB;
55     case AV_PIX_FMT_BGR24:
56       return Image_Format_BGR;
57     case AV_PIX_FMT_GRAY8:
58       return Image_Format_Gray;
59     default:
60       return Image_Format_UNKNOWN;
61   }
62 #else
63   (void )theFormat;
64   return Image_Format_UNKNOWN;
65 #endif
66 }
67
68 // =======================================================================
69 // function : FormatOcct2FFmpeg
70 // purpose  :
71 // =======================================================================
72 int Media_Frame::FormatOcct2FFmpeg (Image_Format theFormat)
73 {
74 #ifdef HAVE_FFMPEG
75   switch (theFormat)
76   {
77     case Image_Format_RGBA:
78       return AV_PIX_FMT_RGBA;
79     case Image_Format_BGRA:
80       return AV_PIX_FMT_BGRA;
81     case Image_Format_RGB32:
82       return AV_PIX_FMT_RGB0;
83     case Image_Format_BGR32:
84       return AV_PIX_FMT_BGR0;
85     case Image_Format_RGB:
86       return AV_PIX_FMT_RGB24;
87     case Image_Format_BGR:
88       return AV_PIX_FMT_BGR24;
89     case Image_Format_Gray:
90       return AV_PIX_FMT_GRAY8;
91     case Image_Format_Alpha:
92       return AV_PIX_FMT_GRAY8;
93     case Image_Format_GrayF:
94     case Image_Format_AlphaF:
95     case Image_Format_RGF:
96     case Image_Format_RGBAF:
97     case Image_Format_RGBF:
98     case Image_Format_BGRAF:
99     case Image_Format_BGRF:
100     case Image_Format_UNKNOWN:
101       return AV_PIX_FMT_NONE; // unsupported
102   }
103   return AV_PIX_FMT_NONE;
104 #else
105   (void )theFormat;
106   return 0;
107 #endif
108 }
109
110 // =======================================================================
111 // function : Media_Frame
112 // purpose  :
113 // =======================================================================
114 Media_Frame::Media_Frame()
115 : myFrame (NULL),
116   myFramePts  (0.0),
117   myPixelRatio(1.0f),
118   myIsLocked  (false)
119 {
120 #ifdef HAVE_FFMPEG
121   myFrame = av_frame_alloc();
122 #endif
123   Unref();
124 }
125
126 // =======================================================================
127 // function : ~Media_Frame
128 // purpose  :
129 // =======================================================================
130 Media_Frame::~Media_Frame()
131 {
132 #ifdef HAVE_FFMPEG
133   av_frame_free (&myFrame);
134 #endif
135 }
136
137 // =======================================================================
138 // function : Unref
139 // purpose  :
140 // =======================================================================
141 void Media_Frame::Unref()
142 {
143 #ifdef HAVE_FFMPEG
144   av_frame_unref (myFrame);
145 #endif
146 }
147
148 // =======================================================================
149 // function : IsFullRangeYUV
150 // purpose  :
151 // =======================================================================
152 bool Media_Frame::IsFullRangeYUV() const
153 {
154 #ifdef HAVE_FFMPEG
155   return Format() == AV_PIX_FMT_YUVJ420P
156       || myFrame->color_range == AVCOL_RANGE_JPEG;
157 #else
158   return true;
159 #endif
160 }
161
162 // =======================================================================
163 // function : Swap
164 // purpose  :
165 // =======================================================================
166 void Media_Frame::Swap (const Handle(Media_Frame)& theFrame1,
167                         const Handle(Media_Frame)& theFrame2)
168 {
169   std::swap (theFrame1->myFrame, theFrame2->myFrame);
170 }
171
172 // =======================================================================
173 // function : IsEmpty
174 // purpose  :
175 // =======================================================================
176 bool Media_Frame::IsEmpty() const
177 {
178 #ifdef HAVE_FFMPEG
179   return myFrame->format == -1; // AV_PIX_FMT_NONE
180 #else
181   return true;
182 #endif
183 }
184
185 // =======================================================================
186 // function : SizeX
187 // purpose  :
188 // =======================================================================
189 int Media_Frame::SizeX() const
190 {
191 #ifdef HAVE_FFMPEG
192   return myFrame->width;
193 #else
194   return 0;
195 #endif
196 }
197
198 // =======================================================================
199 // function : SizeY
200 // purpose  :
201 // =======================================================================
202 int Media_Frame::SizeY() const
203 {
204 #ifdef HAVE_FFMPEG
205   return myFrame->height;
206 #else
207   return 0;
208 #endif
209 }
210
211 // =======================================================================
212 // function : Format
213 // purpose  :
214 // =======================================================================
215 int Media_Frame::Format() const
216 {
217 #ifdef HAVE_FFMPEG
218   return myFrame->format;
219 #else
220   return 0;
221 #endif
222 }
223
224 // =======================================================================
225 // function : Plane
226 // purpose  :
227 // =======================================================================
228 uint8_t* Media_Frame::Plane (int thePlaneId) const
229 {
230 #ifdef HAVE_FFMPEG
231   return myFrame->data[thePlaneId];
232 #else
233   (void )thePlaneId;
234   return NULL;
235 #endif
236 }
237
238 // =======================================================================
239 // function : LineSize
240 // purpose  :
241 // =======================================================================
242 int Media_Frame::LineSize (int thePlaneId) const
243 {
244 #ifdef HAVE_FFMPEG
245   return myFrame->linesize[thePlaneId];
246 #else
247   (void )thePlaneId;
248   return 0;
249 #endif
250 }
251
252 // =======================================================================
253 // function : BestEffortTimestamp
254 // purpose  :
255 // =======================================================================
256 int64_t Media_Frame::BestEffortTimestamp() const
257 {
258 #ifdef HAVE_FFMPEG
259   return myFrame->best_effort_timestamp;
260 #else
261   return 0;
262 #endif
263 }
264
265 // =======================================================================
266 // function : InitWrapper
267 // purpose  :
268 // =======================================================================
269 bool Media_Frame::InitWrapper (const Handle(Image_PixMap)& thePixMap)
270 {
271   Unref();
272   if (thePixMap.IsNull())
273   {
274     return false;
275   }
276
277 #ifdef HAVE_FFMPEG
278   myFrame->format = FormatOcct2FFmpeg (thePixMap->Format());
279   if (myFrame->format == AV_PIX_FMT_NONE)
280   {
281     return false;
282   }
283
284   myFrame->width       = (int )thePixMap->SizeX();
285   myFrame->height      = (int )thePixMap->SizeY();
286   myFrame->data[0]     = (uint8_t* )thePixMap->ChangeData();
287   myFrame->linesize[0] = (int      )thePixMap->SizeRowBytes();
288   for (int aPlaneIter = 1; aPlaneIter < AV_NUM_DATA_POINTERS; ++aPlaneIter)
289   {
290     myFrame->data    [aPlaneIter] = NULL;
291     myFrame->linesize[aPlaneIter] = 0;
292   }
293   return true;
294 #else
295   return false;
296 #endif
297 }