00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
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
00093
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
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
00209 if ( output_rate != 0 )
00210 {
00211 frame.ExtractAudio( input );
00212 AudioInfo info;
00213 frame.GetAudioInfo( info );
00214
00215
00216
00217
00218
00219
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
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