1 ///////////////////////////////////////////////////////////////////////////////
2 //
3 //    electricsheep for windows - collaborative screensaver
4 //    Copyright 2003 Nicholas Long <nlong@cox.net>
5 //	  electricsheep for windows is based of software
6 //	  written by Scott Draves <source@electricsheep.org>
7 //
8 //    This program is free software; you can redistribute it and/or modify
9 //    it under the terms of the GNU General Public License as published by
10 //    the Free Software Foundation; either version 2 of the License, or
11 //    (at your option) any later version.
12 //
13 //    This program is distributed in the hope that it will be useful,
14 //    but WITHOUT ANY WARRANTY; without even the implied warranty of
15 //    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 //    GNU General Public License for more details.
17 //
18 //    You should have received a copy of the GNU General Public License
19 //    along with this program; if not, write to the Free Software
20 //    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 //
22 ///////////////////////////////////////////////////////////////////////////////
23 #ifndef	_FRAME_H_
24 #define	_FRAME_H_
25 
26 #include	"base.h"
27 #include	"SmartPtr.h"
28 #include	"linkpool.h"
29 #include	"AlignedBuffer.h"
30 
31 #if defined(LIBAVCODEC_VERSION_INT) && (LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(55,28,1))
32 #define USE_NEW_FFMPEG_ALLOC_API
33 #endif
34 
35 #if defined(MAC) || (defined(WIN32) && defined(_MSC_VER))
36 #define USE_NEW_FFMPEG_API
37 #endif
38 
39 namespace ContentDecoder
40 {
41 class CVideoFrame;
42 
43 MakeSmartPointers( CVideoFrame );
44 
45 struct sMetaData
46 {
47 	fp4 m_Fade;
48 	std::string m_FileName;
49 	uint32 m_SheepID;
50 	uint32 m_SheepGeneration;
51 	time_t m_LastAccessTime;
52 	bool m_IsEdge;
53 	spCVideoFrame m_SecondFrame;
54 	bool m_IsSeam;
55 	fp4 m_TransitionProgress;
56 	uint32 m_FrameIdx;
57 	uint32 m_MaxFrameIdx;
58 };
59 
60 /*
61 	CVideoFrame.
62 	Base class for a decoded video frame.
63 	Will converts itself to specified format if needed.
64 */
65 class CVideoFrame
66 {
67 	protected:
68 		uint32	m_Width;
69 		uint32	m_Height;
70 		fp8		m_Pts;
71 
72 		sMetaData m_MetaData;
73 
74 		Base::spCAlignedBuffer m_spBuffer;
75 		AVFrame		*m_pFrame;
76 
77 	public:
CVideoFrame(AVCodecContext * _pCodecContext,AVPixelFormat _format,std::string _filename)78 		CVideoFrame( AVCodecContext *_pCodecContext, AVPixelFormat _format, std::string _filename ) : m_pFrame(NULL)
79 			{
80 				assert( _pCodecContext );
81 				if ( _pCodecContext == NULL)
82 					g_Log->Info( "_pCodecContext == NULL" );
83 
84 				m_MetaData.m_Fade = 1.f;
85 				m_MetaData.m_FileName = _filename;
86 				m_MetaData.m_LastAccessTime = 0;
87 				m_MetaData.m_SheepID = 0;
88 				m_MetaData.m_SheepGeneration = 0;
89 				m_MetaData.m_IsEdge = false;
90 				m_MetaData.m_IsSeam = false;
91 				m_MetaData.m_SecondFrame = NULL;
92 				m_MetaData.m_TransitionProgress = 0.f;
93 
94 				m_Width = static_cast<uint32>(_pCodecContext->width);
95 				m_Height = static_cast<uint32>(_pCodecContext->height);
96 
97 
98 #ifdef USE_NEW_FFMPEG_ALLOC_API
99                 m_pFrame = av_frame_alloc();
100 #else
101                 m_pFrame = avcodec_alloc_frame();
102 #endif
103 
104 				if (m_pFrame != NULL)
105 				{
106 					int32 numBytes = avpicture_get_size( _format, _pCodecContext->width, _pCodecContext->height );
107 					m_spBuffer = new Base::CAlignedBuffer( static_cast<uint32>(numBytes) * sizeof(uint8) );
108 					avpicture_fill( (AVPicture *)m_pFrame, m_spBuffer->GetBufferPtr(), _format, _pCodecContext->width, _pCodecContext->height );
109 				} else
110 					g_Log->Error( "m_pFrame == NULL" );
111 			}
112 
~CVideoFrame()113 			virtual ~CVideoFrame()
114 			{
115 				if( m_pFrame )
116 				{
117 #ifdef USE_NEW_FFMPEG_ALLOC_API
118                     av_frame_free( &m_pFrame );
119 #else
120 					avcodec_free_frame( &m_pFrame );
121 #endif
122 				}
123             }
124 
GetMetaData(sMetaData & _metadata)125 			inline void GetMetaData(sMetaData &_metadata)
126 			{
127 				_metadata = m_MetaData;
128 			}
129 
SetMetaData_Fade(fp4 _fade)130 			inline void SetMetaData_Fade(fp4 _fade)
131 			{
132 				m_MetaData.m_Fade = _fade;
133 			}
134 
SetMetaData_FileName(std::string _filename)135 			inline void SetMetaData_FileName(std::string _filename)
136 			{
137 				m_MetaData.m_FileName = _filename;
138 			}
139 
SetMetaData_SheepID(uint32 _sheepid)140 			inline void SetMetaData_SheepID(uint32 _sheepid)
141 			{
142 				m_MetaData.m_SheepID = _sheepid;
143 			}
144 
SetMetaData_SheepGeneration(uint32 _sheepgeneration)145 			inline void SetMetaData_SheepGeneration(uint32 _sheepgeneration)
146 			{
147 				m_MetaData.m_SheepGeneration = _sheepgeneration;
148 			}
149 
SetMetaData_IsEdge(bool _isedge)150 			inline void SetMetaData_IsEdge(bool _isedge)
151 			{
152 				m_MetaData.m_IsEdge = _isedge;
153 			}
154 
SetMetaData_atime(time_t _atime)155 			inline void SetMetaData_atime(time_t _atime)
156 			{
157 				m_MetaData.m_LastAccessTime = _atime;
158 			}
159 
SetMetaData_SecondFrame(CVideoFrame * pSecondFrame)160 			inline void SetMetaData_SecondFrame(CVideoFrame *pSecondFrame)
161 			{
162 				m_MetaData.m_SecondFrame = pSecondFrame;
163 			}
164 
SetMetaData_IsSeam(bool bIsSeam)165 			inline void SetMetaData_IsSeam(bool bIsSeam)
166 			{
167 				m_MetaData.m_IsSeam = bIsSeam;
168 			}
169 
SetMetaData_TransitionProgress(fp4 progress)170 			inline void SetMetaData_TransitionProgress(fp4 progress)
171 			{
172 				m_MetaData.m_TransitionProgress = progress;
173 			}
174 
SetMetaData_FrameIdx(uint32 idx)175 			inline void SetMetaData_FrameIdx(uint32 idx)
176 			{
177 				m_MetaData.m_FrameIdx = idx;
178 			}
179 
SetMetaData_MaxFrameIdx(uint32 idx)180 			inline void SetMetaData_MaxFrameIdx(uint32 idx)
181 			{
182 				m_MetaData.m_MaxFrameIdx = idx;
183 			}
184 
Pts(const fp8 _pts)185 			inline	void	Pts( const fp8 _pts )			{	m_Pts = _pts;		};
Pts(void)186 			inline	fp8		Pts( void )						{	return m_Pts;		};
Width()187 			inline	uint32	Width()							{	return m_Width;		};
Height()188 			inline	uint32	Height()						{	return m_Height;	};
189 
Frame()190 			inline	AVFrame	*Frame()	{	return m_pFrame;	};
191 
Data()192 			virtual inline uint8		*Data()
193 			{
194 				if( !m_pFrame )
195 					return NULL;
196 
197 				return m_pFrame->data[0];
198 			};
199 
StorageBuffer()200 			virtual inline Base::spCAlignedBuffer& StorageBuffer()
201 			{
202 				return m_spBuffer;
203 			};
204 
CopyBuffer()205 			virtual void CopyBuffer()
206 			{
207 				Base::CAlignedBuffer *newBuffer = new Base::CAlignedBuffer( m_spBuffer->Size() );
208 
209 				memcpy( newBuffer->GetBufferPtr(), m_spBuffer->GetBufferPtr(), m_spBuffer->Size() );
210 
211 
212 				m_spBuffer = newBuffer;
213 			};
214 
215 
Stride()216 			virtual inline int32	Stride()
217 			{
218 				if( !m_pFrame )
219 					return 0;
220 
221 				return m_pFrame->linesize[0];
222 			};
223 
224 			//POOLED( CVideoFrame, Memory::CLinkPool );
225 };
226 
227 
228 }
229 
230 #endif
231