2
encapsulates the syncing methods, to use it in other classes
3
Copyright (C) 1999 Martin Vogt
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.
9
For more information look at the file COPYRIGHT in this package
16
#include "audioDataArray.h"
17
#include "performance.h"
19
AVSyncer::AVSyncer(int bufferSize) {
21
onePicFrameInAudioBytes=8192;
22
this->bufferSize=bufferSize;
24
abs_thread_mutex_init(&writeInMut);
25
abs_thread_mutex_init(&changeMut);
28
audioDataInsert=new AudioData();
29
audioDataArray=new AudioDataArray(400);
30
audioDataCurrent=audioDataArray->readAudioData();
32
startAudio=new TimeStamp();
33
endAudio=new TimeStamp();
34
audioTime=new AudioTime();
36
performance=new Performance();
38
waitTime=new TimeStamp();
39
diffTime=new TimeStamp();
40
videoTimeStamp=new TimeStamp();
49
AVSyncer::~AVSyncer() {
50
delete audioDataArray;
51
delete audioDataInsert;
55
abs_thread_mutex_destroy(&writeInMut);
56
abs_thread_mutex_destroy(&changeMut);
60
delete videoTimeStamp;
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);
73
int AVSyncer::audioPlay(TimeStamp* startStamp,
74
TimeStamp* endStamp,char* , int size) {
79
audioDataInsert->setStart(startStamp);
80
audioDataInsert->setEnd(endStamp);
81
audioDataInsert->setAudioTime(audioTime);
82
audioDataInsert->setPCMLen(size);
84
setAudioSync(audioDataInsert);
90
void AVSyncer::audioClose(void) {
92
setAudioRunning(false);
93
audioDataArray->clear();
101
int AVSyncer::getPreferredDeliverSize() {
102
return onePicFrameInAudioBytes;
107
int AVSyncer::getFrameusec() {
109
int back=oneFrameTime;
114
void AVSyncer::setAudioBufferSize(int size) {
119
void AVSyncer::config(const char* key,const char* value,void*) {
120
if (strcmp(key,"-s")==0) {
121
if (strcmp(value,"on")==0) {
123
cout << "******** lavSync on"<<endl;
126
cout << "******** lavSync off"<<endl;
129
if (strcmp(key,"-p")==0) {
130
cout << "setting perfomance test true"<<endl;
138
void AVSyncer::setAudioSync(AudioData* audioData) {
142
if (onePicFrameInAudioBytes <= 0) {
143
// no video present, we cannot calculate audio
145
//cout << "no video present, we cannot calculate audio pcm length"<<endl;
149
// buffersize is the simulated size of /dev/dsp
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();
163
TimeStamp* startAudio=audioDataCurrent->getStart();
164
int lpts=startAudio->getPTSFlag();
167
SyncClock* syncClock=startAudio->getSyncClock();
168
if (syncClock != NULL) {
169
double pts=startAudio->getPTSTimeStamp();
170
double scr=startAudio->getSCRTimeStamp();
172
syncClock->syncAudio(pts,scr);
175
cout <<"syncClock == NULL (audio)"<<endl;
178
//cout << "lpts is false"<<endl;
186
int AVSyncer::syncPicture(YUVPicture* syncPic) {
187
if (syncPic == NULL) {
188
cout << "syncPic == NULL"<<endl;
192
float picPerSec=syncPic->getPicturePerSecond();
195
if (picPerSec > 0.0) {
196
oneFrameTime=(int) (1000000.0/picPerSec);
198
syncPic->print("picPersec is 0");
202
if (lPerformance==true) {
204
syncPic->setWaitTime(waitTime);
205
performance->incPictureCount();
209
int lpacketSync=true;
211
videoTimeStamp->gettimeofday();
212
diffTime->minus(videoTimeStamp,videoTimeStamp);
215
if (lavSync==false) {
216
if (videoTimeStamp->isNegative()) {
217
diffTime->gettimeofday();
218
diffTime->addOffset(0,oneFrameTime);
219
cout << "skip time based"<<endl;
226
videoTimeStamp->copyTo(waitTime);
228
TimeStamp* earlyTime=syncPic->getEarlyTime();
234
lpacketSync=avSync(syncPic->getStartTimeStamp(),
237
syncPic->getPicturePerSecond());
244
if (lpacketSync == false) {
245
//cout << "skip"<<endl;
246
diffTime->gettimeofday();
247
diffTime->addOffset(0,oneFrameTime);
251
syncPic->setWaitTime(waitTime);
254
waitTime->minus(videoTimeStamp,waitTime);
255
if (waitTime->isPositive()) {
256
diffTime->addOffset(waitTime);
259
diffTime->addOffset(0,oneFrameTime);
268
Heart of the sync routine is here!
270
Currently its more in a state of "try/test"
274
int AVSyncer::avSync(TimeStamp* startVideo,
276
TimeStamp* earlyTime,
280
double videoStartPTSTime=startVideo->getPTSTimeStamp();
281
double videoStartSCRTime=startVideo->getSCRTimeStamp();
282
int videoFrameCounter=startVideo->getVideoFrameCounter();
283
double frameTime=0.0;
289
oneFrameTime=(long)(1000000.0/picPerSec);
290
frameTime=1.0/picPerSec;
291
onePicFrameInAudioBytes=audioTime->calculateBytes(1.0/picPerSec);
294
if (lAudioRunning==false) {
295
waitTime->set(0,oneFrameTime);
303
startAudio->print("audio");
304
startVideo->print("video");
313
cout << "audioStartAudioPacketNrMinor:"<<audioStartAudioPacketNrMinor<<endl;
314
cout << "audioStartPTSTime:"<<audioStartPTSTime<<endl;
315
cout << "audioStartEndPTSTime:"<<audioStartEndPTSTime<<endl;
316
cout << "videoStartPTSTime:"<<videoStartPTSTime<<endl;
321
Here we make sure that we sync over an audio packet only one
326
SyncClock* syncClock=startVideo->getSyncClock();
328
double addPts=videoFrameCounter*frameTime;
329
double pts=videoStartPTSTime+addPts;
331
if (syncClock != NULL) {
333
back=syncClock->syncVideo(pts,
334
videoStartSCRTime,earlyTime,waitTime);
336
cout << "syncClock == NULL (video)"<<endl;
341
//earlyTime->print("earlyTime");
342
earlyTime->waitForIt();
345
double time=syncClock->getPTSTime(&tmp);
346
cout << "time after wait:"<<time<<endl;
351
cout <<"real pts:"<<videoStartPTSTime
353
<<" frameNo:"<<videoFrameCounter
354
<<" frameTime:"<<frameTime<<endl;
364
int AVSyncer::getAudioRunning() {
365
return lAudioRunning;
369
void AVSyncer::setAudioRunning(int lAudioRunning) {
370
this->lAudioRunning=lAudioRunning;
374
void AVSyncer::lockSyncData() {
375
abs_thread_mutex_lock(&changeMut);
376
abs_thread_mutex_lock(&writeInMut);
377
abs_thread_mutex_unlock(&changeMut);
380
void AVSyncer::unlockSyncData() {
381
abs_thread_mutex_unlock(&writeInMut);