frame.h

Go to the documentation of this file.
00001 /*
00002 * frame.h -- utilities for process digital video frames
00003 * Copyright (C) 2000 Arne Schirmacher <arne@schirmacher.de>
00004 *
00005 * This program is free software; you can redistribute it and/or modify
00006 * it under the terms of the GNU General Public License as published by
00007 * the Free Software Foundation; either version 2 of the License, or
00008 * (at your option) any later version.
00009 *
00010 * This program is distributed in the hope that it will be useful,
00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013 * GNU General Public License for more details.
00014 *
00015 * You should have received a copy of the GNU General Public License
00016 * along with this program; if not, write to the Free Software Foundation,
00017 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00018 */
00019 
00020 #ifndef _FRAME_H
00021 #define _FRAME_H 1
00022 
00023 #include "config.h"
00024 
00025 #include <iostream>
00026 using std::cerr;
00027 using std::endl;
00028 
00029 #include <time.h>
00030 #include <string>
00031 #include <stdio.h>
00032 using std::string;
00033 
00034 #include <samplerate.h>
00035 
00036 #include "endian_types.h"
00037 
00038 #ifdef WITH_LIBDV
00039 #include <libdv/dv.h>
00040 #include <libdv/dv_types.h>
00041 #endif
00042 
00043 #if defined(HAVE_LIBAVCODEC)
00044 extern "C"
00045 {
00046 #   include <avcodec.h>
00047 }
00048 #endif
00049 
00050 #define FRAME_MAX_WIDTH 720
00051 #define FRAME_MAX_HEIGHT 576
00052 
00053 typedef struct Pack
00054 {
00056         unsigned char data[ 5 ];
00057 }
00058 Pack;
00059 
00060 typedef struct TimeCode
00061 {
00062         int hour;
00063         int min;
00064         int sec;
00065         int frame;
00066 }
00067 TimeCode;
00068 
00069 
00070 typedef struct AudioInfo
00071 {
00072         int frames;
00073         int frequency;
00074         int samples;
00075         int channels;
00076         int quantization;
00077 }
00078 AudioInfo;
00079 
00080 
00081 class VideoInfo
00082 {
00083 public:
00084         int width;
00085         int height;
00086         bool isPAL;
00087         TimeCode timeCode;
00088         struct tm       recDate;
00089 
00090         VideoInfo();
00091 
00092         //    string GetTimeCodeString();
00093         //    string GetRecDateString();
00094 }
00095 ;
00096 
00097 
00098 class Frame
00099 {
00100 public:
00102         unsigned char data[ 144000 ];
00104         int bytesInFrame;
00105 
00106 #if defined(HAVE_LIBAVCODEC)
00107 
00108         AVCodecContext libavcodec;
00109 #endif
00110 
00111 #ifdef WITH_LIBDV
00112 
00113         dv_decoder_t *decoder;
00114 #endif
00115 
00116         int16_t *audio_buffers[ 4 ];
00117 
00118 public:
00119         Frame();
00120         ~Frame();
00121 
00122         bool GetSSYBPack( int packNum, Pack &pack ) const;
00123         bool GetVAUXPack( int packNum, Pack &pack ) const;
00124         bool GetAAUXPack( int packNum, Pack &pack ) const;
00125         bool GetTimeCode( TimeCode &timeCode ) const;
00126         bool GetRecordingDate( struct tm &recDate ) const;
00127         string GetRecordingDate( void ) const;
00128         bool GetAudioInfo( AudioInfo &info ) const;
00129         bool GetVideoInfo( VideoInfo &info ) const;
00130         int GetFrameSize( void ) const;
00131         float GetFrameRate( void ) const;
00132         bool IsPAL( void ) const;
00133         bool IsNewRecording( void ) const;
00134         bool IsNormalSpeed( void ) const;
00135         bool IsComplete( void ) const;
00136         int ExtractAudio( void *sound ) const;
00137 #ifdef WITH_LIBDV
00138 
00139         void SetPreferredQuality( );
00140         int ExtractAudio( int16_t **channels ) const;
00141         void ExtractHeader( void );
00142         void Deinterlace( uint8_t *pdst, uint8_t *psrc, int stride, int height );
00143         int ExtractRGB( void *rgb );
00144         int ExtractPreviewRGB( void *rgb );
00145         int ExtractYUV( void *yuv );
00146         int ExtractYUV420( uint8_t *yuv, uint8_t *output[ 3 ] );
00147         int ExtractPreviewYUV( void *yuv );
00148         bool IsWide( void ) const;
00149         int GetWidth();
00150         int GetHeight();
00151         void SetRecordingDate( time_t *datetime, int frame );
00152         void SetTimeCode( int frame );
00153         bool EncodeAudio( AudioInfo &info, int16_t **channels );
00154         void GetUpperField( void *image, int bpp );
00155         void GetLowerField( void *image, int bpp );
00156         static int CalculateNumberSamples( int frequency, int iteration );
00157 #endif
00158 
00159 private:
00161         static bool maps_initialized;
00163         static int palmap_ch1[ 2000 ];
00164         static int palmap_ch2[ 2000 ];
00165         static int palmap_2ch1[ 2000 ];
00166         static int palmap_2ch2[ 2000 ];
00167         static int ntscmap_ch1[ 2000 ];
00168         static int ntscmap_ch2[ 2000 ];
00169         static int ntscmap_2ch1[ 2000 ];
00170         static int ntscmap_2ch2[ 2000 ];
00171         static short compmap[ 4096 ];
00172         //FILE *libdv_log;
00173 };
00174 
00175 typedef enum {
00176     AUDIO_RESAMPLE_SRC_SINC_BEST_QUALITY = 0,
00177     AUDIO_RESAMPLE_SRC_SINC_MEDIUM_QUALITY = 1,
00178     AUDIO_RESAMPLE_SRC_SINC_FASTEST = 2,
00179     AUDIO_RESAMPLE_SRC_ZERO_ORDER_HOLD = 3,
00180     AUDIO_RESAMPLE_SRC_LINEAR = 4,
00181     AUDIO_RESAMPLE_INTERNAL = 5
00182 }
00183 AudioResampleType;
00184 
00185 #define BUFFER_LEN 20480
00186 
00187 template <class input_t, class output_t> class AudioResample
00188 {
00189 protected:
00190         int output_rate;
00191         input_t *input;
00192 
00193 public:
00194         AudioResample( int rate ) : output_rate( rate )
00195         {
00196                 input = new input_t[ BUFFER_LEN ];
00197                 output = new output_t[ BUFFER_LEN ];
00198         }
00199         virtual ~AudioResample()
00200         {
00201                 delete[] input;
00202                 delete[] output;
00203         }
00204         virtual void Resample( input_t *samples, int input_rate, int channels, int samples_this_frame )
00205         { }
00206         void Resample( Frame &frame )
00207         {
00208                 //cout << "Resample -----------------" << endl;
00209                 if ( output_rate != 0 )
00210                 {
00211                         frame.ExtractAudio( input );
00212                         AudioInfo info;
00213                         frame.GetAudioInfo( info );
00214                         /*
00215                         cout << "Audio info: " << endl
00216                              << "  dec-..->frequency: " 
00217                              << info.frequency << endl
00218                              << "  samples: " 
00219                              << info.samples << endl;
00220                         */
00221                         if ( info.frequency && output_rate != info.frequency )
00222                         {
00223                                 Resample( input,
00224                                           info.frequency,
00225                                           info.channels,
00226                                           info.samples );
00227                         }
00228                         else
00229                         {
00230                                 for (int i=0; i<info.channels*info.samples; i++)
00231                                         output[i] = input[i];
00232 
00233                                 size = info.channels*info.samples*sizeof(output_t);
00234                         }
00235                 }
00236                 else
00237                 {
00238                         size = 0;
00239                 }
00240                 // cout << "size: " << size << endl;
00241         }
00242         void SetOutputFrequency( int output_rate )
00243         {
00244                 this->output_rate = output_rate;
00245         }
00246         int GetOutputFrequency( )
00247         {
00248                 return this->output_rate;
00249         }
00250 
00251         output_t *output;
00252         int size;
00253 };
00254 
00255 template <class input_t, class output_t> class InternalAudioResample : public AudioResample<input_t, output_t>
00256 {
00257 public:
00258         InternalAudioResample( ) : AudioResample<input_t,output_t>( 0 )
00259         { }
00260         
00261         InternalAudioResample( int output_rate ) : AudioResample<input_t,output_t>( output_rate )
00262         { }
00263         virtual ~InternalAudioResample()
00264         { }
00269         void Resample( input_t *input, int input_rate, int channels, int samples )
00270         {
00271                 float ratio = ( float ) this->output_rate / ( float ) input_rate;
00272                 this->size = ( int ) ( ( float ) samples * ratio );
00273 
00274                 int rounding = 1 << 15;
00275                 unsigned int xfactor = ( samples << 16 ) / this->size;
00276                 unsigned int xmax = xfactor * this->size;
00277                 unsigned int i = 0;
00278                 unsigned int o = 0;
00279                 this->size *= sizeof(output_t) * channels;
00280 
00281                 for ( unsigned int xft = 0; xft < xmax; xft += xfactor )
00282                 {
00283                         i = ( ( xft + rounding ) >> 16 ) * channels;
00284                         for (int c=0; c < channels; c++)
00285                                 this->output[o+c] = input[i+c];
00286                         o += channels;
00287                 }
00288 
00289         }
00290 };
00291 
00292 template <class input_t, class output_t> class SrcAudioResample : public AudioResample<input_t, output_t>
00293 {
00294 public:
00295         SrcAudioResample( int converter ) : AudioResample<input_t,output_t>( 0 )
00296         {
00297                 int srcError = 0;
00298                 state = src_new( converter, 2, &srcError );
00299                 if ( srcError != 0 )
00300                         cerr << "SRC: " << src_strerror( srcError ) << endl;
00301         }
00302         SrcAudioResample( int converter, int output_rate ) : AudioResample<input_t,output_t>( output_rate )
00303         {
00304                 int srcError = 0;
00305                 state = src_new( converter, 2, &srcError );
00306                 if ( srcError != 0 )
00307                         cerr << "SRC: " << src_strerror( srcError ) << endl;
00308         }
00309         virtual ~SrcAudioResample()
00310         {
00311                 src_delete( state );
00312         }
00313         void Resample( input_t *input, int input_rate, int channels, int samples )
00314         {
00315                 SRC_DATA data;
00316                 static float input_buffer[ BUFFER_LEN ];
00317                 static float output_buffer[ BUFFER_LEN ];
00318 
00319                 for ( int i = 0; i < samples * channels; ++i )
00320                         input_buffer[ i ] = ( float ) input[ i ] / 32768.0;
00321 
00322                 data.data_in = input_buffer;
00323                 data.data_out = output_buffer;
00324                 data.src_ratio = ( float ) this->output_rate / ( float ) input_rate;
00325                 data.input_frames = samples;
00326                 data.output_frames = BUFFER_LEN / channels;
00327                 data.end_of_input = 0;
00328                 int result = src_process ( state, &data );
00329                 if ( result != 0 )
00330                         cerr << "SRC: " << src_strerror( result ) << endl;
00331                 this->size = data.output_frames_gen * channels * sizeof(output_t);
00332                 for ( int i = 0; i < data.output_frames_gen * channels; ++i )
00333                 {
00334                         float sample = output_buffer[ i ];
00335                         if ( sample > 1.0 )
00336                                 sample = 1.0;
00337                         if ( sample < -1.0 )
00338                                 sample = -1.0;
00339                         if ( sample >= 0 )
00340                                 this->output[ i ] = ( long int )( 32767.0 * sample );
00341                         else
00342                                 this->output[ i ] = ( long int )( 32768.0 * sample );
00343                 }
00344         }
00345 
00346 private:
00347         SRC_STATE *state;
00348 };
00349 
00350 template <class input_t, class output_t> class AudioResampleFactory
00351 {
00352 public:
00353         static AudioResample<input_t, output_t> *createAudioResample( AudioResampleType type, int output_rate = 0 )
00354         {
00355                 switch ( type )
00356                 {
00357                 case AUDIO_RESAMPLE_SRC_SINC_BEST_QUALITY:
00358                         return new SrcAudioResample<input_t, output_t>( SRC_SINC_BEST_QUALITY, output_rate );
00359                 case AUDIO_RESAMPLE_SRC_SINC_MEDIUM_QUALITY:
00360                         return new SrcAudioResample<input_t, output_t>( SRC_SINC_MEDIUM_QUALITY, output_rate );
00361                 case AUDIO_RESAMPLE_SRC_SINC_FASTEST:
00362                         return new SrcAudioResample<input_t, output_t>( SRC_SINC_FASTEST, output_rate );
00363                 case AUDIO_RESAMPLE_SRC_ZERO_ORDER_HOLD:
00364                         return new SrcAudioResample<input_t, output_t>( SRC_ZERO_ORDER_HOLD, output_rate );
00365                 case AUDIO_RESAMPLE_SRC_LINEAR:
00366                         return new SrcAudioResample<input_t, output_t>( SRC_LINEAR, output_rate );
00367                 default:
00368                         return new InternalAudioResample<input_t, output_t>( output_rate );
00369                 }
00370         }
00371 };
00372 
00373 class FramePool
00374 {
00375 public:
00376         virtual Frame *GetFrame( ) = 0;
00377         virtual void DoneWithFrame( Frame * ) = 0;
00378 };
00379 
00380 extern FramePool *GetFramePool( );
00381 
00382 #endif

Generated on Tue Jan 22 17:07:29 2008 for MUAN by  doxygen 1.4.7