Torque3D Documentation / _generateds / oggTheoraDecoder.h

oggTheoraDecoder.h

Engine/source/core/ogg/oggTheoraDecoder.h

More...

Classes:

class

Decodes a Theora substream into frame packets.

class

Descriptor for surface format that this stream should decode into.

class

A single decoded Theora video frame.

Detailed Description

  1
  2//-----------------------------------------------------------------------------
  3// Copyright (c) 2012 GarageGames, LLC
  4//
  5// Permission is hereby granted, free of charge, to any person obtaining a copy
  6// of this software and associated documentation files (the "Software"), to
  7// deal in the Software without restriction, including without limitation the
  8// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  9// sell copies of the Software, and to permit persons to whom the Software is
 10// furnished to do so, subject to the following conditions:
 11//
 12// The above copyright notice and this permission notice shall be included in
 13// all copies or substantial portions of the Software.
 14//
 15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 20// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 21// IN THE SOFTWARE.
 22//-----------------------------------------------------------------------------
 23
 24#ifndef _OGGTHEORADECODER_H_
 25#define _OGGTHEORADECODER_H_
 26
 27#ifndef _OGGINPUTSTREAM_H_
 28   #include "core/ogg/oggInputStream.h"
 29#endif
 30#ifndef _TSTREAM_H_
 31   #include "core/stream/tStream.h"
 32#endif
 33#ifndef _RAWDATA_H_
 34   #include "core/util/rawData.h"
 35#endif
 36#ifndef _GFXENUMS_H_
 37   #include "gfx/gfxEnums.h"
 38#endif
 39#ifndef _THREADSAFEDEQUE_H_
 40   #include "platform/threads/threadSafeDeque.h"
 41#endif
 42#include "theora/theoradec.h"
 43
 44
 45/// A single decoded Theora video frame.
 46class OggTheoraFrame : public RawData
 47{
 48   public:
 49   
 50      typedef RawData Parent;
 51      
 52      OggTheoraFrame() :mFrameNumber(0), mFrameTime(0), mFrameDuration(0) {}
 53      OggTheoraFrame( S8* data, U32 size, bool ownMemory = false )
 54         : Parent( data, size, ownMemory ), mFrameNumber(0), mFrameTime(0), mFrameDuration(0) {}
 55         
 56      /// Serial number of this frame in the stream.
 57      U32 mFrameNumber;
 58      
 59      /// Playtime in seconds at which to display this frame.
 60      F32 mFrameTime;
 61      
 62      /// Seconds to display this frame.
 63      F32 mFrameDuration;
 64};
 65
 66
 67/// Decodes a Theora substream into frame packets.
 68///
 69/// Frame packets contain raw pixel data in the set pixel format (default is R8G8B8).
 70/// Reading on a thread is safe, but remember to keep a reference to the OggInputStream
 71/// master from the worker thread.
 72class OggTheoraDecoder : public OggDecoder,
 73                         public IInputStream< OggTheoraFrame* >
 74{
 75   public:
 76   
 77      typedef OggDecoder Parent;
 78      
 79      /// Y'CbCr pixel format of the source video stream.
 80      /// For informational purposes only.  Packet out is determined
 81      /// by PacketFormat.
 82      enum EPixelFormat
 83      {
 84         PIXEL_FORMAT_444,    // Full Y, full Cb, full Cr.
 85         PIXEL_FORMAT_422,    // Full Y, half-width Cb, half-width Cr.
 86         PIXEL_FORMAT_420,    // Full Y, half-widht+height Cb, half-width+height Cr.
 87         PIXEL_FORMAT_Unknown
 88      };
 89            
 90      /// Descriptor for surface format that this stream should
 91      /// decode into.  This saves an otherwise potentitally necessary
 92      /// swizzling step.
 93      ///
 94      /// @note The output channel ordering will be in device format, i.e.
 95      ///   least-significant first.
 96      struct PacketFormat
 97      {
 98         /// Pixel format.
 99         GFXFormat mFormat;
100         
101         /// Bytes per scanline.
102         U32 mPitch;
103         
104         /// Default descriptor sets up for RGB.
105         PacketFormat()
106            : mFormat( GFXFormatR8G8B8 ),
107              mPitch( 0 ) {}
108         
109         ///
110         PacketFormat( GFXFormat format, U32 pitch )
111            : mFormat( format ),
112              mPitch( pitch ) {}
113      };
114      
115      ///
116      enum ETranscoder
117      {
118         TRANSCODER_Auto,           ///< Auto-detect from current formats and processor capabilities.
119         TRANSCODER_Generic,        ///< Generic transcoder that handles all source and target formats; 32bit integer + lookup tables.
120         TRANSCODER_SSE2420RGBA,    ///< SSE2 transcoder with fixed 4:2:0 to RGBA conversion; 32bit integer + lookup tables.
121      };
122            
123   protected:
124   
125      typedef IPositionable< U32>* TimeSourceRef;
126      
127      /// @name libtheora Data
128      /// @{
129            
130      ///
131      th_comment mTheoraComment;
132      
133      ///
134      th_info mTheoraInfo;
135      
136      ///
137      th_setup_info* mTheoraSetup;
138      
139      ///
140      th_dec_ctx* mTheoraDecoder;
141      
142      /// @}
143      
144      ///
145      PacketFormat mPacketFormat;
146            
147      ///
148      F32 mFrameDuration;
149
150      ///
151      F32 mCurrentFrameTime;
152      
153      ///
154      U32 mCurrentFrameNumber;
155            
156      /// If this is set, the decoder will drop frames that are
157      /// already outdated with respect to the time source.
158      ///
159      /// @note Times are in milliseconds and in video time.
160      TimeSourceRef mTimeSource;
161      
162      /// Transcoder to use for color space conversion.  If the current
163      /// setting is invalid, will fall back to generic.
164      ETranscoder mTranscoder;
165      
166      ///
167      ThreadSafeDeque< OggTheoraFrame*> mFreePackets;
168      
169      #ifdef TORQUE_DEBUG
170      U32 mLock;
171      #endif
172      
173      /// Generic transcoder going from any of the Y'CbCr pixel formats to
174      /// any RGB format (that is supported by GFXFormatUtils).
175      void _transcode( th_ycbcr_buffer ycbcr, U8* buffer, U32 width, U32 height );
176#if defined( TORQUE_CPU_X86 )
177      /// Transcoder with fixed 4:2:0 to RGBA conversion using SSE2 assembly. Unused on 64 bit archetecture.
178      void _transcode420toRGBA_SSE2( th_ycbcr_buffer ycbcr, U8* buffer, U32 width, U32 height, U32 pitch );
179#endif
180      // OggDecoder.
181      virtual bool _detect( ogg_page* startPage );
182      virtual bool _init();
183      virtual bool _packetin( ogg_packet* packet );
184
185      ///
186      U32 _getPixelOffset( th_ycbcr_buffer buffer, U32 plane, U32 x, U32 y ) const
187      {
188         switch( getDecoderPixelFormat() )
189         {
190            case PIXEL_FORMAT_444:  break;
191            case PIXEL_FORMAT_422:  if( plane != 0 ) x >>= 1; break;
192            case PIXEL_FORMAT_420:  if( plane != 0 ) { x >>= 1; y >>= 1; } break;
193            
194            default:
195               AssertFatal( false, "OggTheoraDecoder::_getPixelOffset() - invalid pixel format" );
196         }
197         
198         return ( y * buffer[ plane ].stride + x );
199      }
200
201      ///
202      U8* _getPixelPtr( th_ycbcr_buffer buffer, U32 plane, U32 offset, U32 x, U32 y ) const
203      {
204         return ( buffer[ plane ].data + offset + _getPixelOffset( buffer, plane, x, y ) );
205      }
206      
207      ///
208      U32 _getPictureOffset( th_ycbcr_buffer buffer, U32 plane )
209      {
210         return _getPixelOffset( buffer, plane, mTheoraInfo.pic_x, mTheoraInfo.pic_y );
211      }
212            
213   public:
214   
215      ///
216      OggTheoraDecoder( const ThreadSafeRef< OggInputStream>& stream );
217      
218      ~OggTheoraDecoder();
219      
220      /// Return the width of video image frames in pixels.
221      /// @note This returns the actual picture width rather than Theora's internal encoded frame width.
222      U32 getFrameWidth() const { return mTheoraInfo.pic_width; }
223      
224      /// Return the height of video image frames in pixels.
225      /// @note This returns the actual picture height rather than Theora's internal encoded frame height.
226      U32 getFrameHeight() const { return mTheoraInfo.pic_height; }
227      
228      ///
229      F32 getFramesPerSecond() const { return ( F32( mTheoraInfo.fps_numerator ) / F32( mTheoraInfo.fps_denominator ) ); }
230      
231      ///
232      EPixelFormat getDecoderPixelFormat() const
233      {
234         switch( mTheoraInfo.pixel_fmt )
235         {
236            case TH_PF_444:   return PIXEL_FORMAT_444;
237            case TH_PF_422:   return PIXEL_FORMAT_422;
238            case TH_PF_420:   return PIXEL_FORMAT_420;
239            default:          return PIXEL_FORMAT_Unknown;
240         }
241      }
242      
243      ///
244      const PacketFormat& getPacketFormat() const { return mPacketFormat; }
245      
246      ///
247      void setPacketFormat( const PacketFormat& format ) { mPacketFormat = format; }
248      
249      /// Set the reference time source.  Frames will be dropped if the decoder
250      /// falls behind the time of this source.
251      ///
252      /// @note The time source must have at least the same lifetime as the decoder.
253      void setTimeSource( const TimeSourceRef& timeSource ) { mTimeSource = timeSource; }
254            
255      /// Set the Y'CbCr->RGB transcoder to use.
256      void setTranscoder( ETranscoder transcoder ) { mTranscoder = transcoder; }
257      
258      ///
259      void reusePacket( OggTheoraFrame* packet ) { mFreePackets.pushBack( packet ); }
260         
261      // OggDecoder.
262      virtual const char* getName() const { return "Theora"; }
263      
264      // IInputStream.
265      virtual U32 read( OggTheoraFrame** buffer, U32 num );
266};
267
268#endif // !_OGGTHEORADECODER_H_
269