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