~ubuntu-branches/ubuntu/hoary/kdemultimedia/hoary

« back to all changes in this revision

Viewing changes to mpeglib/lib/output/avSyncer.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Martin Schulze
  • Date: 2003-01-22 15:00:51 UTC
  • Revision ID: james.westby@ubuntu.com-20030122150051-uihwkdoxf15mi1tn
Tags: upstream-2.2.2
ImportĀ upstreamĀ versionĀ 2.2.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
  encapsulates the syncing methods, to use it in other classes
 
3
  Copyright (C) 1999  Martin Vogt
 
4
 
 
5
  This program is free software; you can redistribute it and/or modify
 
6
  it under the terms of the GNU Library General Public License as published by
 
7
  the Free Software Foundation.
 
8
 
 
9
  For more information look at the file COPYRIGHT in this package
 
10
 
 
11
 */
 
12
 
 
13
 
 
14
#include "avSyncer.h"
 
15
 
 
16
#include "audioDataArray.h"
 
17
#include "performance.h"
 
18
 
 
19
AVSyncer::AVSyncer(int bufferSize) {
 
20
  oneFrameTime=0;
 
21
  onePicFrameInAudioBytes=8192;
 
22
  this->bufferSize=bufferSize;
 
23
 
 
24
  abs_thread_mutex_init(&writeInMut);
 
25
  abs_thread_mutex_init(&changeMut);
 
26
 
 
27
  
 
28
  audioDataInsert=new AudioData();
 
29
  audioDataArray=new AudioDataArray(400);
 
30
  audioDataCurrent=audioDataArray->readAudioData();
 
31
  
 
32
  startAudio=new TimeStamp();
 
33
  endAudio=new TimeStamp();
 
34
  audioTime=new AudioTime();
 
35
  lAudioRunning=false;
 
36
  performance=new Performance();
 
37
 
 
38
  waitTime=new TimeStamp();
 
39
  diffTime=new TimeStamp();
 
40
  videoTimeStamp=new TimeStamp();
 
41
 
 
42
  lPerformance=false;
 
43
  lavSync=true;
 
44
 
 
45
 
 
46
}
 
47
 
 
48
 
 
49
AVSyncer::~AVSyncer() {
 
50
  delete audioDataArray;
 
51
  delete audioDataInsert;
 
52
  delete audioTime;
 
53
  delete startAudio;
 
54
  delete endAudio;
 
55
  abs_thread_mutex_destroy(&writeInMut);
 
56
  abs_thread_mutex_destroy(&changeMut);
 
57
  delete waitTime;
 
58
  delete diffTime;
 
59
  delete performance;
 
60
  delete videoTimeStamp;
 
61
}
 
62
 
 
63
 
 
64
 
 
65
int AVSyncer::audioSetup(int frequency,int stereo,int sign,
 
66
                         int big,int sixteen) {
 
67
  audioTime->setFormat(stereo,sixteen,frequency,sign,big);
 
68
  setAudioRunning(true);
 
69
  return true;
 
70
}
 
71
 
 
72
 
 
73
int AVSyncer::audioPlay(TimeStamp* startStamp,
 
74
                        TimeStamp* endStamp,char* , int size) {
 
75
 
 
76
 
 
77
 
 
78
 
 
79
  audioDataInsert->setStart(startStamp);
 
80
  audioDataInsert->setEnd(endStamp);
 
81
  audioDataInsert->setAudioTime(audioTime);
 
82
  audioDataInsert->setPCMLen(size);
 
83
 
 
84
  setAudioSync(audioDataInsert);
 
85
  return size;
 
86
}
 
87
 
 
88
 
 
89
 
 
90
void AVSyncer::audioClose(void) {
 
91
  lockSyncData();
 
92
  setAudioRunning(false);
 
93
  audioDataArray->clear();
 
94
  unlockSyncData();
 
95
}
 
96
 
 
97
 
 
98
 
 
99
 
 
100
 
 
101
int AVSyncer::getPreferredDeliverSize() {
 
102
  return onePicFrameInAudioBytes;
 
103
}
 
104
 
 
105
 
 
106
 
 
107
int AVSyncer::getFrameusec() {
 
108
  lockSyncData();
 
109
  int back=oneFrameTime;
 
110
  unlockSyncData();
 
111
  return back; 
 
112
}
 
113
 
 
114
void AVSyncer::setAudioBufferSize(int size) {
 
115
  bufferSize=size;
 
116
}
 
117
 
 
118
 
 
119
void AVSyncer::config(const char* key,const char* value,void*) {
 
120
  if (strcmp(key,"-s")==0) {
 
121
    if (strcmp(value,"on")==0) {
 
122
      lavSync=true;
 
123
      cout << "******** lavSync on"<<endl;
 
124
    } else {
 
125
      lavSync=false;
 
126
      cout << "******** lavSync off"<<endl;
 
127
    }
 
128
  }
 
129
  if (strcmp(key,"-p")==0) {
 
130
    cout << "setting perfomance test true"<<endl;
 
131
    lPerformance=true;
 
132
  }  
 
133
 
 
134
}
 
135
 
 
136
 
 
137
 
 
138
void AVSyncer::setAudioSync(AudioData* audioData) {
 
139
 
 
140
  lockSyncData();
 
141
 
 
142
  if (onePicFrameInAudioBytes <= 0) {
 
143
    // no video present, we cannot calculate audio
 
144
    // pcm length
 
145
    //cout << "no video present, we cannot calculate audio pcm length"<<endl;
 
146
    unlockSyncData();    
 
147
    return;
 
148
  }
 
149
  // buffersize is the simulated size of /dev/dsp
 
150
 
 
151
 
 
152
 
 
153
  // we implement a fifo hopefully
 
154
  // we check the right audio pts time out
 
155
  // when /dev/dsp acutally plays it.
 
156
  audioDataArray->insertAudioData(audioData);
 
157
  int pcmSum=audioDataArray->getPCMSum();
 
158
  if (pcmSum >= bufferSize) {
 
159
    audioDataCurrent=audioDataArray->readAudioData();
 
160
    setAudioRunning(true);
 
161
    audioDataArray->forward();
 
162
  }
 
163
  TimeStamp* startAudio=audioDataCurrent->getStart();
 
164
  int lpts=startAudio->getPTSFlag();
 
165
 
 
166
  if (lpts==true) {
 
167
    SyncClock* syncClock=startAudio->getSyncClock();
 
168
    if (syncClock != NULL) {
 
169
      double pts=startAudio->getPTSTimeStamp();
 
170
      double scr=startAudio->getSCRTimeStamp();
 
171
 
 
172
      syncClock->syncAudio(pts,scr);
 
173
 
 
174
    } else {
 
175
      cout <<"syncClock == NULL (audio)"<<endl;
 
176
    }
 
177
  } else {
 
178
    //cout << "lpts is false"<<endl;
 
179
  }
 
180
  unlockSyncData();    
 
181
  
 
182
}
 
183
 
 
184
 
 
185
 
 
186
int AVSyncer::syncPicture(YUVPicture* syncPic) {
 
187
  if (syncPic == NULL) {
 
188
    cout << "syncPic == NULL"<<endl;
 
189
    return false;
 
190
  }
 
191
 
 
192
  float picPerSec=syncPic->getPicturePerSecond();
 
193
  int oneFrameTime=0;
 
194
 
 
195
  if (picPerSec > 0.0) {
 
196
    oneFrameTime=(int) (1000000.0/picPerSec);
 
197
  } else {
 
198
    syncPic->print("picPersec is 0");
 
199
    return true;
 
200
  }
 
201
 
 
202
  if (lPerformance==true) {
 
203
    waitTime->set(0,0);
 
204
    syncPic->setWaitTime(waitTime);
 
205
    performance->incPictureCount();
 
206
    return true;
 
207
  }
 
208
 
 
209
  int lpacketSync=true;
 
210
 
 
211
  videoTimeStamp->gettimeofday();
 
212
  diffTime->minus(videoTimeStamp,videoTimeStamp);
 
213
 
 
214
 
 
215
  if (lavSync==false) {
 
216
    if (videoTimeStamp->isNegative()) {
 
217
      diffTime->gettimeofday();
 
218
      diffTime->addOffset(0,oneFrameTime);
 
219
      cout << "skip time based"<<endl;
 
220
      return false;
 
221
    }
 
222
  }
 
223
 
 
224
 
 
225
 
 
226
  videoTimeStamp->copyTo(waitTime);
 
227
 
 
228
  TimeStamp* earlyTime=syncPic->getEarlyTime();
 
229
  earlyTime->set(0,0);
 
230
 
 
231
 
 
232
  if (lavSync) {
 
233
    
 
234
    lpacketSync=avSync(syncPic->getStartTimeStamp(),
 
235
                       waitTime,
 
236
                       earlyTime,
 
237
                       syncPic->getPicturePerSecond());
 
238
 
 
239
  } 
 
240
 
 
241
 
 
242
 
 
243
 
 
244
  if (lpacketSync == false) {
 
245
    //cout << "skip"<<endl;
 
246
    diffTime->gettimeofday();
 
247
    diffTime->addOffset(0,oneFrameTime);
 
248
    return false;
 
249
  }
 
250
 
 
251
  syncPic->setWaitTime(waitTime);
 
252
 
 
253
  if (lavSync) {
 
254
     waitTime->minus(videoTimeStamp,waitTime);
 
255
     if (waitTime->isPositive()) {
 
256
       diffTime->addOffset(waitTime);
 
257
     }
 
258
  }
 
259
  diffTime->addOffset(0,oneFrameTime);
 
260
  return true;
 
261
 
 
262
 
 
263
}
 
264
 
 
265
 
 
266
 
 
267
/**
 
268
   Heart of the sync routine is here!
 
269
 
 
270
   Currently its more in a state of "try/test"
 
271
 
 
272
   
 
273
*/
 
274
int AVSyncer::avSync(TimeStamp* startVideo,
 
275
                     TimeStamp* waitTime,
 
276
                     TimeStamp* earlyTime,
 
277
                     float picPerSec ) {
 
278
 
 
279
 
 
280
  double videoStartPTSTime=startVideo->getPTSTimeStamp();
 
281
  double videoStartSCRTime=startVideo->getSCRTimeStamp();
 
282
  int videoFrameCounter=startVideo->getVideoFrameCounter();
 
283
  double frameTime=0.0;
 
284
 
 
285
 
 
286
 
 
287
  lockSyncData();
 
288
  if (picPerSec > 0) {
 
289
    oneFrameTime=(long)(1000000.0/picPerSec);
 
290
    frameTime=1.0/picPerSec;
 
291
    onePicFrameInAudioBytes=audioTime->calculateBytes(1.0/picPerSec);
 
292
 
 
293
  }
 
294
  if (lAudioRunning==false) {
 
295
    waitTime->set(0,oneFrameTime);
 
296
 
 
297
    unlockSyncData();
 
298
    return true;
 
299
  }
 
300
   
 
301
 
 
302
  /*
 
303
    startAudio->print("audio");
 
304
    startVideo->print("video");
 
305
  */
 
306
 
 
307
 
 
308
 
 
309
 
 
310
                       
 
311
 
 
312
  /*
 
313
  cout << "audioStartAudioPacketNrMinor:"<<audioStartAudioPacketNrMinor<<endl;
 
314
  cout << "audioStartPTSTime:"<<audioStartPTSTime<<endl;
 
315
  cout << "audioStartEndPTSTime:"<<audioStartEndPTSTime<<endl;
 
316
  cout << "videoStartPTSTime:"<<videoStartPTSTime<<endl;
 
317
  */
 
318
  
 
319
    
 
320
  /**
 
321
     Here we make sure that we sync over an audio packet only one
 
322
     time.
 
323
  */
 
324
 
 
325
  waitTime->set(0,0);
 
326
  SyncClock* syncClock=startVideo->getSyncClock();
 
327
  int back=false;
 
328
  double addPts=videoFrameCounter*frameTime;
 
329
  double pts=videoStartPTSTime+addPts;
 
330
 
 
331
  if (syncClock != NULL) {
 
332
 
 
333
    back=syncClock->syncVideo(pts,
 
334
                              videoStartSCRTime,earlyTime,waitTime);
 
335
  } else {
 
336
    cout << "syncClock == NULL (video)"<<endl;
 
337
  }
 
338
  unlockSyncData();
 
339
 
 
340
  if (back==true) {
 
341
    //earlyTime->print("earlyTime");
 
342
    earlyTime->waitForIt();
 
343
    /*
 
344
    double tmp;
 
345
    double time=syncClock->getPTSTime(&tmp);
 
346
    cout << "time after wait:"<<time<<endl;
 
347
    */
 
348
  }
 
349
  /*
 
350
  if (back == false) {
 
351
    cout <<"real pts:"<<videoStartPTSTime
 
352
         <<" calc pts"<<pts
 
353
         <<" frameNo:"<<videoFrameCounter
 
354
         <<" frameTime:"<<frameTime<<endl;
 
355
  }
 
356
  */
 
357
          
 
358
 
 
359
 
 
360
  return back;
 
361
 
 
362
}
 
363
  
 
364
int AVSyncer::getAudioRunning() {
 
365
  return lAudioRunning;
 
366
}
 
367
 
 
368
 
 
369
void AVSyncer::setAudioRunning(int lAudioRunning) {
 
370
  this->lAudioRunning=lAudioRunning;
 
371
}
 
372
 
 
373
 
 
374
void AVSyncer::lockSyncData() {
 
375
  abs_thread_mutex_lock(&changeMut);
 
376
  abs_thread_mutex_lock(&writeInMut);
 
377
  abs_thread_mutex_unlock(&changeMut);
 
378
}
 
379
 
 
380
void AVSyncer::unlockSyncData() {
 
381
  abs_thread_mutex_unlock(&writeInMut); 
 
382
}