Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

Frame Class Reference

#include <frame.h>

List of all members.

Public Member Functions

 Frame ()
 constructor
 ~Frame ()
Frameoperator= (const Frame &)
bool GetSSYBPack (int packNum, Pack &pack) const
 gets a subcode data packet
bool GetVAUXPack (int packNum, Pack &pack) const
 gets a video auxiliary data packet
bool GetAAUXPack (int packNum, Pack &pack) const
 gets an audio auxiliary data packet
bool GetTimeCode (TimeCode &timeCode) const
 gets the timecode information of this frame
bool GetRecordingDate (struct tm &recDate) const
 gets the date and time of recording of this frame
std::string GetRecordingDate (void) const
bool GetAudioInfo (AudioInfo &info) const
 gets the audio properties of this frame
bool GetVideoInfo (VideoInfo &info) const
int GetFrameSize (void) const
 gets the size of the frame
float GetFrameRate (void) const
 gets the frame rate of the video
bool IsPAL (void) const
 checks whether the frame is in PAL or NTSC format
bool IsNewRecording (void) const
 checks whether this frame is the first in a new recording
bool IsNormalSpeed (void) const
 checks whether this frame is playing at normal speed
bool IsComplete (void) const
 check whether we have received as many bytes as expected for this frame
int ExtractAudio (void *sound) const
 retrieves the audio data from the frame

Public Attributes

unsigned char * data
int bytesInFrame
 the number of bytes written to the frame
int16_t * audio_buffers [4]

Static Private Attributes

static bool maps_initialized = false
 flag for initializing the lookup maps once at startup
static int palmap_ch1 [2000]
 lookup tables for collecting the shuffled audio data
static int palmap_ch2 [2000]
static int palmap_2ch1 [2000]
static int palmap_2ch2 [2000]
static int ntscmap_ch1 [2000]
static int ntscmap_ch2 [2000]
static int ntscmap_2ch1 [2000]
static int ntscmap_2ch2 [2000]
static short compmap [4096]


Constructor & Destructor Documentation

Frame::Frame  ) 
 

constructor

All Frame objects share a set of lookup maps, which are initalized once (we are using a variant of the Singleton pattern).

Definition at line 94 of file frame.cc.

References audio_buffers, avcodec_mutex, compmap, data, DV_AUDIO_MAX_SAMPLES, Preferences::getInstance(), maps_initialized, ntscmap_2ch1, ntscmap_2ch2, ntscmap_ch1, ntscmap_ch2, palmap_2ch1, palmap_2ch2, palmap_ch1, and palmap_ch2.

00094              : bytesInFrame( 0 )
00095 {
00096 #if defined(HAVE_LIBAVCODEC)
00097     pthread_mutex_lock( &avcodec_mutex );
00098     av_register_all();
00099     libavcodec = avcodec_alloc_context();
00100     libavcodec->thread_count = 2;
00101     avcodec_open( libavcodec, &dvvideo_decoder );
00102     pthread_mutex_unlock( &avcodec_mutex );
00103     data = ( unsigned char* ) av_mallocz( 144000 );
00104 #if defined(HAVE_SWSCALE)
00105     imgConvertRgbCtx = NULL;
00106     imgConvertYuvCtx = NULL;
00107 #endif
00108 #else
00109     data = ( unsigned char* ) calloc( 1, 144000 );
00110 #endif
00111 
00112 #ifdef HAVE_LIBDV
00113     decoder = dv_decoder_new( FALSE,
00114                               Preferences::getInstance().dvDecoderClampLuma,
00115                               Preferences::getInstance().dvDecoderClampChroma );
00116     decoder->audio->arg_audio_emphasis = 2;
00117     this->SetPreferredQuality( );
00118     dv_set_audio_correction ( decoder, DV_AUDIO_CORRECT_AVERAGE );
00119     dv_set_error_log( decoder, NULL );
00120     encoder = NULL;
00121 #else
00122 
00123     if ( maps_initialized == false )
00124     {
00125 
00126         for ( int n = 0; n < 1944; ++n )
00127         {
00128             int sequence1 = ( ( n / 3 ) + 2 * ( n % 3 ) ) % 6;
00129             int sequence2 = sequence1 + 6;
00130             int block = 3 * ( n % 3 ) + ( ( n % 54 ) / 18 );
00131 
00132             block = 6 + block * 16;
00133             {
00134                 register int byte = 8 + 2 * ( n / 54 );
00135                 palmap_ch1[ n ] = sequence1 * 150 * 80 + block * 80 + byte;
00136                 palmap_ch2[ n ] = sequence2 * 150 * 80 + block * 80 + byte;
00137                 byte += ( n / 54 );
00138                 palmap_2ch1[ n ] = sequence1 * 150 * 80 + block * 80 + byte;
00139                 palmap_2ch2[ n ] = sequence2 * 150 * 80 + block * 80 + byte;
00140             }
00141         }
00142         for ( int n = 0; n < 1620; ++n )
00143         {
00144             int sequence1 = ( ( n / 3 ) + 2 * ( n % 3 ) ) % 5;
00145             int sequence2 = sequence1 + 5;
00146             int block = 3 * ( n % 3 ) + ( ( n % 45 ) / 15 );
00147 
00148             block = 6 + block * 16;
00149             {
00150                 register int byte = 8 + 2 * ( n / 45 );
00151                 ntscmap_ch1[ n ] = sequence1 * 150 * 80 + block * 80 + byte;
00152                 ntscmap_ch2[ n ] = sequence2 * 150 * 80 + block * 80 + byte;
00153                 byte += ( n / 45 );
00154                 ntscmap_2ch1[ n ] = sequence1 * 150 * 80 + block * 80 + byte;
00155                 ntscmap_2ch2[ n ] = sequence2 * 150 * 80 + block * 80 + byte;
00156             }
00157         }
00158         for ( int y = 0x700; y <= 0x7ff; ++y )
00159             compmap[ y ] = ( y - 0x600 ) << 6;
00160         for ( int y = 0x600; y <= 0x6ff; ++y )
00161             compmap[ y ] = ( y - 0x500 ) << 5;
00162         for ( int y = 0x500; y <= 0x5ff; ++y )
00163             compmap[ y ] = ( y - 0x400 ) << 4;
00164         for ( int y = 0x400; y <= 0x4ff; ++y )
00165             compmap[ y ] = ( y - 0x300 ) << 3;
00166         for ( int y = 0x300; y <= 0x3ff; ++y )
00167             compmap[ y ] = ( y - 0x200 ) << 2;
00168         for ( int y = 0x200; y <= 0x2ff; ++y )
00169             compmap[ y ] = ( y - 0x100 ) << 1;
00170         for ( int y = 0x000; y <= 0x1ff; ++y )
00171             compmap[ y ] = y;
00172         for ( int y = 0x800; y <= 0xfff; ++y )
00173             compmap[ y ] = -1 - compmap[ 0xfff - y ];
00174         maps_initialized = true;
00175     }
00176 #endif
00177     for ( int n = 0; n < 4; n++ )
00178         audio_buffers[ n ] = ( int16_t * ) malloc( 2 * DV_AUDIO_MAX_SAMPLES * sizeof( int16_t ) );
00179 }

Frame::~Frame  ) 
 

Definition at line 182 of file frame.cc.

References audio_buffers, avcodec_mutex, and data.

00183 {
00184 #if defined(HAVE_LIBAVCODEC)
00185     pthread_mutex_lock( &avcodec_mutex );
00186     avcodec_close( libavcodec );
00187     av_free( libavcodec );
00188 /*  if ( avformatEncoder )
00189     {
00190         av_write_trailer( avformatEncoder );
00191         av_destruct_packet( &avpacketEncoder );
00192         avcodec_close( avformatEncoder->streams[0]->codec );
00193         av_free( avformatEncoder->streams[0]->codec );
00194         av_free( avformatEncoder->streams[0] );
00195         av_free( avformatEncoder );
00196     }*/
00197     pthread_mutex_unlock( &avcodec_mutex );
00198     av_free( data );
00199 #if defined(HAVE_SWSCALE)
00200     if ( imgConvertRgbCtx )
00201         sws_freeContext( imgConvertRgbCtx );
00202     if ( imgConvertYuvCtx )
00203         sws_freeContext( imgConvertYuvCtx );
00204 #endif
00205 #else
00206     free( data );
00207 #endif
00208 
00209 #ifdef HAVE_LIBDV
00210     dv_decoder_free( decoder );
00211     if ( encoder )
00212         dv_encoder_free( encoder );
00213 #endif
00214 
00215     for ( int n = 0; n < 4; n++ )
00216         free( audio_buffers[ n ] );
00217 }


Member Function Documentation

int Frame::ExtractAudio void *  sound  )  const
 

retrieves the audio data from the frame

The DV frame contains audio data mixed in the video data blocks, which can be retrieved easily using this function.

The audio data consists of 16 bit, two channel audio samples (a 16 bit word for channel 1, followed by a 16 bit word for channel 2 etc.)

Parameters:
sound a pointer to a buffer that holds the audio data
Returns:
the number of bytes put into the buffer, or 0 if no audio data could be retrieved

Definition at line 785 of file frame.cc.

References audio_buffers, AudioInfo::channels, compmap, data, AudioInfo::frequency, GetAudioInfo(), info, IsPAL(), ntscmap_2ch1, ntscmap_ch1, ntscmap_ch2, palmap_2ch1, palmap_ch1, palmap_ch2, and AudioInfo::samples.

Referenced by PageMagick::AudioThread(), FXSelectedFrames::GetAudio(), AsyncAudioResample< input_t, output_t >::ReadAudio(), AudioResample< int16_ne_t, int16_ne_t >::Resample(), and AVI2File::WriteFrame().

00786 {
00787     AudioInfo info;
00788 
00789 #ifdef HAVE_LIBDV
00790 
00791     if ( GetAudioInfo( info ) == true )
00792     {
00793         int n, i;
00794         int16_t* s = ( int16_t * ) sound;
00795         if ( dv_decode_full_audio( decoder, data, ( int16_t ** ) audio_buffers ) == TRUE )
00796         {
00797             for ( n = 0; n < info.samples; ++n )
00798                 for ( i = 0; i < info.channels; i++ )
00799                     *s++ = audio_buffers[ i ][ n ];
00800         }
00801         else
00802         {
00803             info.samples = 0;
00804         }
00805     }
00806     else
00807         info.samples = 0;
00808 
00809 #else
00810     /* Collect the audio samples */
00811     char* s = ( char * ) sound;
00812 
00813     GetAudioInfo( info );
00814     switch ( info.frequency )
00815     {
00816     case 32000:
00817 
00818         /* This is 4 channel audio */
00819 
00820         if ( IsPAL() )
00821         {
00822             short * p = ( short* ) sound;
00823             for ( int n = 0; n < info.samples; ++n )
00824             {
00825                 register int r = ( ( unsigned char* ) data ) [ palmap_2ch1[ n ] + 1 ]; // LSB
00826                 *p++ = compmap[ ( ( ( unsigned char* ) data ) [ palmap_2ch1[ n ] ] << 4 ) + ( r >> 4 ) ];   // MSB
00827                 *p++ = compmap[ ( ( ( unsigned char* ) data ) [ palmap_2ch1[ n ] + 1 ] << 4 ) + ( r & 0x0f ) ];
00828             }
00829 
00830 
00831         }
00832         else
00833         {
00834             short* p = ( short* ) sound;
00835             for ( int n = 0; n < info.samples; ++n )
00836             {
00837                 register int r = ( ( unsigned char* ) data ) [ ntscmap_2ch1[ n ] + 1 ]; // LSB
00838                 *p++ = compmap[ ( ( ( unsigned char* ) data ) [ ntscmap_2ch1[ n ] ] << 4 ) + ( r >> 4 ) ];   // MSB
00839                 *p++ = compmap[ ( ( ( unsigned char* ) data ) [ ntscmap_2ch1[ n ] + 1 ] << 4 ) + ( r & 0x0f ) ];
00840             }
00841         }
00842         break;
00843 
00844     case 44100:
00845     case 48000:
00846 
00847         /* this can be optimized significantly */
00848 
00849         if ( IsPAL() )
00850         {
00851             for ( int n = 0; n < info.samples; ++n )
00852             {
00853                 *s++ = ( ( char* ) data ) [ palmap_ch1[ n ] + 1 ]; /* LSB */
00854                 *s++ = ( ( char* ) data ) [ palmap_ch1[ n ] ];     /* MSB */
00855                 *s++ = ( ( char* ) data ) [ palmap_ch2[ n ] + 1 ]; /* LSB */
00856                 *s++ = ( ( char* ) data ) [ palmap_ch2[ n ] ];     /* MSB */
00857             }
00858         }
00859         else
00860         {
00861             for ( int n = 0; n < info.samples; ++n )
00862             {
00863                 *s++ = ( ( char* ) data ) [ ntscmap_ch1[ n ] + 1 ]; /* LSB */
00864                 *s++ = ( ( char* ) data ) [ ntscmap_ch1[ n ] ];     /* MSB */
00865                 *s++ = ( ( char* ) data ) [ ntscmap_ch2[ n ] + 1 ]; /* LSB */
00866                 *s++ = ( ( char* ) data ) [ ntscmap_ch2[ n ] ];     /* MSB */
00867             }
00868         }
00869         break;
00870 
00871         /* we can't handle any other format in the moment */
00872 
00873     default:
00874         info.samples = 0;
00875     }
00876 
00877 #endif
00878     return info.samples * info.channels * 2;
00879 }

bool Frame::GetAAUXPack int  packNum,
Pack pack
const
 

gets an audio auxiliary data packet

Every DIF block in the audio section contains 5 bytes audio auxiliary data and 72 bytes of audio data. The function searches through all DIF blocks although AAUX packets are only allowed in certain defined DIF blocks.

Parameters:
packNum the AAUX package id to return
pack a reference to the variable where the result is stored
Returns:
true for success, false if no pack could be found

Definition at line 371 of file frame.cc.

References data, Pack::data, and IsPAL().

Referenced by GetAudioInfo(), and IsNewRecording().

00372 {
00373 #ifdef HAVE_LIBDV
00374     bool done = false;
00375     switch ( packNum )
00376     {
00377     case 0x50:
00378         memcpy( pack.data, &decoder->audio->aaux_as, 5 );
00379         done = true;
00380         break;
00381 
00382     case 0x51:
00383         memcpy( pack.data, &decoder->audio->aaux_asc, 5 );
00384         done = true;
00385         break;
00386 
00387     case 0x52:
00388         memcpy( pack.data, &decoder->audio->aaux_as1, 5 );
00389         done = true;
00390         break;
00391 
00392     case 0x53:
00393         memcpy( pack.data, &decoder->audio->aaux_asc1, 5 );
00394         done = true;
00395         break;
00396     }
00397     if ( done )
00398         return true;
00399 #endif
00400 
00401     /* number of DIF sequences is different for PAL and NTSC */
00402 
00403     int seqCount = IsPAL() ? 12 : 10;
00404 
00405     /* process all DIF sequences */
00406 
00407     for ( int i = 0; i < seqCount; ++i )
00408     {
00409 
00410         /* there are nine audio DIF blocks */
00411         for ( int j = 0; j < 9; ++j )
00412         {
00413 
00414             /* calculate address: 150 DIF blocks per sequence, 80 bytes
00415                per DIF block, audio blocks start at every 16th beginning
00416                with block 6, block has 3 bytes header, followed by one
00417                packet. */
00418 
00419             const unsigned char *s = &data[ i * 150 * 80 + 6 * 80 + j * 16 * 80 + 3 ];
00420             if ( s[ 0 ] == packNum )
00421             {
00422                 // printf("aaux %d: %2.2x %2.2x %2.2x %2.2x %2.2x\n",
00423                 // j, s[0], s[1], s[2], s[3], s[4]);
00424                 pack.data[ 0 ] = s[ 0 ];
00425                 pack.data[ 1 ] = s[ 1 ];
00426                 pack.data[ 2 ] = s[ 2 ];
00427                 pack.data[ 3 ] = s[ 3 ];
00428                 pack.data[ 4 ] = s[ 4 ];
00429                 return true;
00430             }
00431         }
00432     }
00433     return false;
00434 }

bool Frame::GetAudioInfo AudioInfo info  )  const
 

gets the audio properties of this frame

get the sampling frequency and the number of samples in this particular DV frame (which can vary)

Parameters:
info the AudioInfo record
Returns:
true, if audio properties could be determined

Definition at line 583 of file frame.cc.

References Pack::data, GetAAUXPack(), and IsPAL().

Referenced by ExportPipe::doExport(), ExportMJPEG::doExport(), ExportAVI::doExport(), ExportAudio::doExport(), Export1394::doExport(), ExtractAudio(), FXSelectedFrames::GetAudio(), PageMagickAudioTransition::GetFrame(), PageMagickOverwrite::GetFrame(), KinoCommon::importFile(), PageMagickInfo::Initialise(), kino2raw(), AsyncAudioResample< input_t, output_t >::ReadAudio(), AudioResample< int16_ne_t, int16_ne_t >::Resample(), and FileHandler::WriteFrame().

00584 {
00585 #ifdef HAVE_LIBDV
00586     info.frequency = dv_get_frequency( decoder );
00587     info.samples = dv_get_num_samples( decoder );
00588     info.frames = IsPAL() ? 50 : 60;
00589     info.channels = dv_get_num_channels( decoder );
00590     info.quantization = ( decoder->audio->aaux_as.pc4.qu == 0 ) ? 16 : 12;
00591     return true;
00592 #else
00593 
00594     int af_size;
00595     int smp;
00596     int flag;
00597     Pack pack50;
00598 
00599 
00600     info.channels = 2;
00601 
00602     /* Check whether this frame has a valid AAUX source packet
00603     (header == 0x50). If so, get the audio samples count. If not,
00604     skip this audio data. */
00605 
00606     if ( GetAAUXPack( 0x50, pack50 ) == true )
00607     {
00608 
00609         /* get size, sampling type and the 50/60 flag. The number of
00610         audio samples is dependend on all of these. */
00611 
00612         af_size = pack50.data[ 1 ] & 0x3f;
00613         smp = ( pack50.data[ 4 ] >> 3 ) & 0x07;
00614         flag = pack50.data[ 3 ] & 0x20;
00615 
00616         if ( flag == 0 )
00617         {
00618             info.frames = 60;
00619             switch ( smp )
00620             {
00621             case 0:
00622                 info.frequency = 48000;
00623                 info.samples = 1580 + af_size;
00624                 break;
00625             case 1:
00626                 info.frequency = 44100;
00627                 info.samples = 1452 + af_size;
00628                 break;
00629             case 2:
00630                 info.frequency = 32000;
00631                 info.samples = 1053 + af_size;
00632                 break;
00633             }
00634         }
00635         else
00636         { // 50 frames (PAL)
00637             info.frames = 50;
00638             switch ( smp )
00639             {
00640             case 0:
00641                 info.frequency = 48000;
00642                 info.samples = 1896 + af_size;
00643                 break;
00644             case 1:
00645                 info.frequency = 44100;
00646                 info.samples = 0; // I don't know
00647                 break;
00648             case 2:
00649                 info.frequency = 32000;
00650                 info.samples = 1264 + af_size;
00651                 break;
00652             }
00653         }
00654         return true;
00655     }
00656     else
00657     {
00658         return false;
00659     }
00660 #endif
00661 }

float Frame::GetFrameRate void   )  const
 

gets the frame rate of the video

Depending on the type (PAL or NTSC) of the frame, the frame rate is returned

Returns:
frames per second

Definition at line 691 of file frame.cc.

References IsPAL().

Referenced by Export::calculateAdjustedRate(), convertFramesToSmilTime(), convertSmilTimeToFrames(), FXSelectedFrames::GetAudio(), kino2raw(), SrtContext::printEntry(), PageMagick::showFrameInfo(), PageCapture::showFrameInfo(), showScenesThread(), and PageTimeline::Thread().

00692 {
00693     return IsPAL() ? 25.0 : 30000.0 / 1001.0;
00694 }

int Frame::GetFrameSize void   )  const
 

gets the size of the frame

Depending on the type (PAL or NTSC) of the frame, the length of the frame is returned

Returns:
the length of the frame in Bytes

Definition at line 679 of file frame.cc.

References IsPAL().

Referenced by IsComplete(), kino2raw(), operator=(), RawHandler::Write(), FileHandler::WriteFrame(), AVI2File::WriteFrame(), and AVI1File::WriteFrame().

00680 {
00681     return IsPAL() ? 144000 : 120000;
00682 }

string Frame::GetRecordingDate void   )  const
 

Definition at line 499 of file frame.cc.

Referenced by GetVideoInfo().

00500 {
00501     string recDate;
00502 #ifdef HAVE_LIBDV
00503 
00504     char s[ 64 ];
00505     if ( dv_get_recording_datetime( decoder, s ) )
00506         recDate = s;
00507     else
00508         recDate = "0000-00-00 00:00:00";
00509 #else
00510 
00511     struct tm date;
00512     ostringstream sb;
00513 
00514     if ( GetRecordingDate( date ) == true )
00515     {
00516         sb << setfill( '0' )
00517         << setw( 4 ) << date.tm_year + 1900 << '.'
00518         << setw( 2 ) << date.tm_mon + 1 << '.'
00519         << setw( 2 ) << date.tm_mday << '_'
00520         << setw( 2 ) << date.tm_hour << '-'
00521         << setw( 2 ) << date.tm_min << '-'
00522         << setw( 2 ) << date.tm_sec;
00523         sb >> recDate;
00524     }
00525     else
00526     {
00527         recDate = "0000.00.00_00-00-00";
00528     }
00529 #endif
00530     return recDate;
00531 }

bool Frame::GetRecordingDate struct tm &  recDate  )  const
 

gets the date and time of recording of this frame

Returns a struct tm with date and time of recording of this frame.

This code courtesy of Andy (http://www.videox.net/)

Parameters:
recDate the time and date of recording of this frame
Returns:
true for success, false if no date or time information could be found

Definition at line 445 of file frame.cc.

References Pack::data, and GetSSYBPack().

Referenced by PlayList::AutoSplit(), and FileHandler::WriteFrame().

00446 {
00447 #ifdef HAVE_LIBDV
00448     return dv_get_recording_datetime_tm( decoder, ( struct tm * ) &recDate );
00449 #else
00450 
00451     Pack pack62;
00452     Pack pack63;
00453 
00454     if ( GetSSYBPack( 0x62, pack62 ) == false )
00455         return false;
00456 
00457     int day = pack62.data[ 2 ];
00458     int month = pack62.data[ 3 ];
00459     int year = pack62.data[ 4 ];
00460 
00461     if ( GetSSYBPack( 0x63, pack63 ) == false )
00462         return false;
00463 
00464     int sec = pack63.data[ 2 ];
00465     int min = pack63.data[ 3 ];
00466     int hour = pack63.data[ 4 ];
00467 
00468     sec = ( sec & 0xf ) + 10 * ( ( sec >> 4 ) & 0x7 );
00469     min = ( min & 0xf ) + 10 * ( ( min >> 4 ) & 0x7 );
00470     hour = ( hour & 0xf ) + 10 * ( ( hour >> 4 ) & 0x3 );
00471     year = ( year & 0xf ) + 10 * ( ( year >> 4 ) & 0xf );
00472     month = ( month & 0xf ) + 10 * ( ( month >> 4 ) & 0x1 );
00473     day = ( day & 0xf ) + 10 * ( ( day >> 4 ) & 0x3 );
00474 
00475     if ( year < 25 )
00476         year += 2000;
00477     else
00478         year += 1900;
00479 
00480     recDate.tm_sec = sec;
00481     recDate.tm_min = min;
00482     recDate.tm_hour = hour;
00483     recDate.tm_mday = day;
00484     recDate.tm_mon = month - 1;
00485     recDate.tm_year = year - 1900;
00486     recDate.tm_wday = -1;
00487     recDate.tm_yday = -1;
00488     recDate.tm_isdst = -1;
00489 
00490     /* sanity check of the results */
00491 
00492     if ( mktime( &recDate ) == -1 )
00493         return false;
00494     return true;
00495 #endif
00496 }

bool Frame::GetSSYBPack int  packNum,
Pack pack
const
 

gets a subcode data packet

This function returns a SSYB packet from the subcode data section.

Parameters:
packNum the SSYB package id to return
pack a reference to the variable where the result is stored
Returns:
true for success, false if no pack could be found

Definition at line 239 of file frame.cc.

References data, Pack::data, and IsPAL().

Referenced by GetRecordingDate(), and GetTimeCode().

00240 {
00241 #ifdef HAVE_LIBDV
00242     pack.data[ 0 ] = packNum;
00243     dv_get_ssyb_pack( decoder, packNum, &pack.data[ 1 ] );
00244     return true;
00245 #else
00246     /* number of DIF sequences is different for PAL and NTSC */
00247 
00248     int seqCount = IsPAL() ? 12 : 10;
00249 
00250     /* process all DIF sequences */
00251 
00252     for ( int i = 0; i < seqCount; ++i )
00253     {
00254 
00255         /* there are two DIF blocks in the subcode section */
00256 
00257         for ( int j = 0; j < 2; ++j )
00258         {
00259 
00260             /* each block has 6 packets */
00261 
00262             for ( int k = 0; k < 6; ++k )
00263             {
00264 
00265                 /* calculate address: 150 DIF blocks per sequence, 80 bytes
00266                 per DIF block, subcode blocks start at block 1, block and
00267                 packet have 3 bytes header, packet is 8 bytes long
00268                 (including header) */
00269 
00270                 const unsigned char *s = &data[ i * 150 * 80 + 1 * 80 + j * 80 + 3 + k * 8 + 3 ];
00271                 // printf("ssyb %d: %2.2x %2.2x %2.2x %2.2x %2.2x\n",
00272                 // j * 6 + k, s[0], s[1], s[2], s[3], s[4]);
00273                 if ( s[ 0 ] == packNum )
00274                 {
00275                     //                  printf("GetSSYBPack[%x]: sequence %d, block %d, packet %d\n", packNum,i,j,k);
00276                     pack.data[ 0 ] = s[ 0 ];
00277                     pack.data[ 1 ] = s[ 1 ];
00278                     pack.data[ 2 ] = s[ 2 ];
00279                     pack.data[ 3 ] = s[ 3 ];
00280                     pack.data[ 4 ] = s[ 4 ];
00281                     return true;
00282                 }
00283             }
00284         }
00285     }
00286     return false;
00287 #endif
00288 }

bool Frame::GetTimeCode TimeCode timeCode  )  const
 

gets the timecode information of this frame

Returns a string with the timecode of this frame. The timecode is the relative location of this frame on the tape, and is defined by hour, minute, second and frame (within the last second).

Parameters:
timeCode the TimeCode struct
Returns:
true for success, false if no timecode information could be found

Definition at line 543 of file frame.cc.

References Pack::data, TimeCode::frame, GetSSYBPack(), TimeCode::hour, TimeCode::min, and TimeCode::sec.

Referenced by captureThread(), GetVideoInfo(), and FileHandler::WriteFrame().

00544 {
00545 #ifdef HAVE_LIBDV
00546     int timestamp[ 4 ];
00547 
00548     dv_get_timestamp_int( decoder, timestamp );
00549 
00550     timeCode.hour = timestamp[ 0 ];
00551     timeCode.min = timestamp[ 1 ];
00552     timeCode.sec = timestamp[ 2 ];
00553     timeCode.frame = timestamp[ 3 ];
00554 #else
00555 
00556     Pack tc;
00557 
00558     if ( GetSSYBPack( 0x13, tc ) == false )
00559         return false;
00560 
00561     int frame = tc.data[ 1 ];
00562     int sec = tc.data[ 2 ];
00563     int min = tc.data[ 3 ];
00564     int hour = tc.data[ 4 ];
00565 
00566     timeCode.frame = ( frame & 0xf ) + 10 * ( ( frame >> 4 ) & 0x3 );
00567     timeCode.sec = ( sec & 0xf ) + 10 * ( ( sec >> 4 ) & 0x7 );
00568     timeCode.min = ( min & 0xf ) + 10 * ( ( min >> 4 ) & 0x7 );
00569     timeCode.hour = ( hour & 0xf ) + 10 * ( ( hour >> 4 ) & 0x3 );
00570 #endif
00571 
00572     return true;
00573 }

bool Frame::GetVAUXPack int  packNum,
Pack pack
const
 

gets a video auxiliary data packet

Every DIF block in the video auxiliary data section contains 15 video auxiliary data packets, for a total of 45 VAUX packets. As the position of a VAUX packet is fixed, we could directly look it up, but I choose to walk through all data as with the other routines.

Parameters:
packNum the VAUX package id to return
pack a reference to the variable where the result is stored
Returns:
true for success, false if no pack could be found

Definition at line 302 of file frame.cc.

References data, Pack::data, and IsPAL().

00303 {
00304 #ifdef HAVE_LIBDV
00305     pack.data[ 0 ] = packNum;
00306     dv_get_vaux_pack( decoder, packNum, &pack.data[ 1 ] );
00307     //cerr << "VAUX: 0x"
00308     //<< setw(2) << setfill('0') << hex << (int) pack.data[0]
00309     //<< setw(2) << setfill('0') << hex << (int) pack.data[1]
00310     //<< setw(2) << setfill('0') << hex << (int) pack.data[2]
00311     //<< setw(2) << setfill('0') << hex << (int) pack.data[3]
00312     //<< setw(2) << setfill('0') << hex << (int) pack.data[4]
00313     //<< endl;
00314     return true;
00315 
00316 #else
00317     /* number of DIF sequences is different for PAL and NTSC */
00318 
00319     int seqCount = IsPAL() ? 12 : 10;
00320 
00321     /* process all DIF sequences */
00322 
00323     for ( int i = 0; i < seqCount; ++i )
00324     {
00325 
00326         /* there are three DIF blocks in the VAUX section */
00327 
00328         for ( int j = 0; j < 3; ++j )
00329         {
00330 
00331             /* each block has 15 packets */
00332 
00333             for ( int k = 0; k < 15; ++k )
00334             {
00335 
00336                 /* calculate address: 150 DIF blocks per sequence, 80 bytes
00337                 per DIF block, vaux blocks start at block 3, block has 3
00338                 bytes header, packets have no header and are 5 bytes
00339                 long. */
00340 
00341                 const unsigned char *s = &data[ i * 150 * 80 + 3 * 80 + j * 80 + 3 + k * 5 ];
00342                 //printf("vaux %d: %2.2x %2.2x %2.2x %2.2x %2.2x\n",
00343                 //  j * 15 + k, s[0],  s[1],  s[2],  s[3],  s[4]);
00344                 if ( s[ 0 ] == packNum )
00345                 {
00346                     pack.data[ 0 ] = s[ 0 ];
00347                     pack.data[ 1 ] = s[ 1 ];
00348                     pack.data[ 2 ] = s[ 2 ];
00349                     pack.data[ 3 ] = s[ 3 ];
00350                     pack.data[ 4 ] = s[ 4 ];
00351                     return true;
00352                 }
00353             }
00354         }
00355     }
00356     return false;
00357 #endif
00358 }

bool Frame::GetVideoInfo VideoInfo info  )  const
 

Definition at line 664 of file frame.cc.

References GetRecordingDate(), GetTimeCode(), and IsPAL().

00665 {
00666     GetTimeCode( info.timeCode );
00667     GetRecordingDate( info.recDate );
00668     info.isPAL = IsPAL();
00669     return true;
00670 }

bool Frame::IsComplete void   )  const
 

check whether we have received as many bytes as expected for this frame

Returns:
true if this frames is completed, false otherwise

Definition at line 768 of file frame.cc.

References bytesInFrame, and GetFrameSize().

00769 {
00770     return bytesInFrame >= GetFrameSize();
00771 }

bool Frame::IsNewRecording void   )  const
 

checks whether this frame is the first in a new recording

To determine this, the function looks at the recStartPoint bit in AAUX pack 51.

Returns:
true if this frame is the start of a new recording

Definition at line 723 of file frame.cc.

References Pack::data, data, and GetAAUXPack().

Referenced by FileHandler::WriteFrame().

00724 {
00725 #ifdef HAVE_LIBDV
00726     return dv_is_new_recording( decoder, data );
00727 #else
00728 
00729     Pack aauxSourceControl;
00730 
00731     /* if we can't find the packet, we return "no new recording" */
00732 
00733     if ( GetAAUXPack( 0x51, aauxSourceControl ) == false )
00734         return false;
00735 
00736     unsigned char recStartPoint = aauxSourceControl.data[ 2 ] & 0x80;
00737 
00738     return recStartPoint == 0 ? true : false;
00739 #endif
00740 }

bool Frame::IsNormalSpeed void   )  const
 

checks whether this frame is playing at normal speed

To determine this, the function looks at the speed bit in AAUX pack 51.

Returns:
true if this frame is playing at normal speed

Definition at line 751 of file frame.cc.

Referenced by captureThread(), and PageCapture::startCapture().

00752 {
00753     bool normal_speed = true;
00754 
00755 #ifdef HAVE_LIBDV
00756     /* don't do audio if speed is not 1 */
00757     return dv_is_normal_speed( decoder );
00758 #endif
00759 
00760     return ( normal_speed );
00761 }

bool Frame::IsPAL void   )  const
 

checks whether the frame is in PAL or NTSC format

Todo:
function can't handle "empty" frame
Returns:
true for PAL frame, false for a NTSC frame

Definition at line 703 of file frame.cc.

References data.

Referenced by _getOneSecond(), PlayList::AutoSplit(), ExportStills::doExport(), ExportPipe::doExport(), ExportMJPEG::doExport(), Export1394::doExport(), ExtractAudio(), GetAAUXPack(), GetAudioInfo(), FindDisplayer::getDisplayer(), GetFrameRate(), GetFrameSize(), getOneSecond(), GetSSYBPack(), GetVAUXPack(), GetVideoInfo(), KinoCommon::importFile(), PageMagickInfo::Initialise(), kino2raw(), DVPipeTool::output(), PageCapture::saveFrame(), KinoCommon::saveFrame(), KinoCommon::savePlayListAs(), and KinoCommon::setPreviewSize().

00704 {
00705     unsigned char dsf = data[ 3 ] & 0x80;
00706     bool pal = ( dsf == 0 ) ? false : true;
00707 
00708 #ifdef HAVE_LIBDV
00709     if ( !pal )
00710         pal = dv_is_PAL( decoder );
00711 #endif
00712     return pal;
00713 }

Frame & Frame::operator= const Frame  ) 
 

Definition at line 220 of file frame.cc.

References bytesInFrame, data, and GetFrameSize().

00221 {
00222     bytesInFrame = rhs.GetFrameSize();
00223     if ( bytesInFrame > 144000 )
00224         bytesInFrame = 144000;
00225     memcpy( data, rhs.data, bytesInFrame );
00226     ExtractHeader();
00227     return *this;
00228 }


Member Data Documentation

int16_t* Frame::audio_buffers[4]
 

Definition at line 122 of file frame.h.

Referenced by ExtractAudio(), Frame(), and ~Frame().

int Frame::bytesInFrame
 

the number of bytes written to the frame

Definition at line 107 of file frame.h.

Referenced by IsComplete(), and operator=().

static short Frame::compmap [static, private]
 

Definition at line 72 of file frame.cc.

Referenced by ExtractAudio(), and Frame().

unsigned char* Frame::data
 

Definition at line 105 of file frame.h.

Referenced by ExtractAudio(), Frame(), GetAAUXPack(), AVIFile::GetDVFrame(), RawHandler::GetFrame(), GetSSYBPack(), GetVAUXPack(), IsNewRecording(), IsPAL(), kino2raw(), operator=(), DVPipeTool::output(), PageMagick::StartRender(), RawHandler::Write(), AVI2File::WriteFrame(), AVI1File::WriteFrame(), and ~Frame().

static bool Frame::maps_initialized = false [static, private]
 

flag for initializing the lookup maps once at startup

Definition at line 63 of file frame.cc.

Referenced by Frame().

static int Frame::ntscmap_2ch1 [static, private]
 

Definition at line 70 of file frame.cc.

Referenced by ExtractAudio(), and Frame().

static int Frame::ntscmap_2ch2 [static, private]
 

Definition at line 71 of file frame.cc.

Referenced by Frame().

static int Frame::ntscmap_ch1 [static, private]
 

Definition at line 68 of file frame.cc.

Referenced by ExtractAudio(), and Frame().

static int Frame::ntscmap_ch2 [static, private]
 

Definition at line 69 of file frame.cc.

Referenced by ExtractAudio(), and Frame().

static int Frame::palmap_2ch1 [static, private]
 

Definition at line 66 of file frame.cc.

Referenced by ExtractAudio(), and Frame().

static int Frame::palmap_2ch2 [static, private]
 

Definition at line 67 of file frame.cc.

Referenced by Frame().

static int Frame::palmap_ch1 [static, private]
 

lookup tables for collecting the shuffled audio data

Definition at line 64 of file frame.cc.

Referenced by ExtractAudio(), and Frame().

static int Frame::palmap_ch2 [static, private]
 

Definition at line 65 of file frame.cc.

Referenced by ExtractAudio(), and Frame().


The documentation for this class was generated from the following files:
Generated on Sun Mar 11 22:12:54 2007 for Kino by  doxygen 1.4.2