You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
206 lines
4.7 KiB
206 lines
4.7 KiB
/*
|
|
output to arts
|
|
Copyright (C) 2000 Martin Vogt
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU Library General Public License as published by
|
|
the Free Software Foundation.
|
|
|
|
For more information look at the file COPYRIGHT in this package
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "artsOutputStream.h"
|
|
#include "windowOut.h"
|
|
#include "avSyncer.h"
|
|
#include "../util/abstract/threadQueue.h"
|
|
|
|
|
|
ArtsOutputStream::ArtsOutputStream(void (*streamStateChangeCallback)(void*)) {
|
|
|
|
audioTime=new AudioTime();
|
|
x11Window=new WindowOut();
|
|
privateBufferSize=1024*32;
|
|
|
|
// we can dynamically change the buffer size,
|
|
// over a config switch in avSyncer
|
|
// but for now this should be ok
|
|
// Arts must pass the total size of the audiobuffer
|
|
// from /dev/dsp + connected nodes
|
|
// or arts need a video interface
|
|
stream=new BufferInputStream(privateBufferSize,1024*64,"artsLoopback");
|
|
avSyncer=new AVSyncer(privateBufferSize);
|
|
|
|
// with the ThreadQueue we protect all calls to the
|
|
// x11 output. This is necessary, because arts may call
|
|
// in the future "config" entries to switch the video
|
|
// mode (full,double,desktop)
|
|
threadQueue=new ThreadQueue();
|
|
// we set it, but its never used !
|
|
this->streamStateChangeCallback=streamStateChangeCallback;
|
|
}
|
|
|
|
|
|
ArtsOutputStream::~ArtsOutputStream() {
|
|
delete stream;
|
|
delete audioTime;
|
|
delete x11Window;
|
|
delete avSyncer;
|
|
delete threadQueue;
|
|
}
|
|
|
|
|
|
|
|
|
|
int ArtsOutputStream::audioSetup(int freq,int stereo,
|
|
int sign,int big,int sampleSize) {
|
|
audioTime->setFormat(stereo,sampleSize,freq,sign,big);
|
|
avSyncer->audioSetup(freq,stereo,sign,big,sampleSize);
|
|
|
|
OutputStream::audioSetup(freq,stereo,sign,big,sampleSize);
|
|
|
|
return true;
|
|
}
|
|
|
|
AudioTime* ArtsOutputStream::getAudioTime() {
|
|
return audioTime;
|
|
}
|
|
|
|
|
|
void ArtsOutputStream::audioClose() {
|
|
audioTime->setTime(0.0);
|
|
// if we close this stream the thread is kicked out.
|
|
stream->close();
|
|
stream->clear();
|
|
avSyncer->audioClose();
|
|
}
|
|
|
|
void ArtsOutputStream::audioFlush() {
|
|
OutputStream::audioFlush();
|
|
audioClose();
|
|
}
|
|
|
|
|
|
void ArtsOutputStream::audioOpen() {
|
|
audioTime->setTime(0.0);
|
|
// if we close this stream the thread is kicked out.
|
|
stream->open("artsLoopback");
|
|
}
|
|
|
|
|
|
int ArtsOutputStream::audioPlay(TimeStamp* startStamp,
|
|
TimeStamp* endStamp,char *buffer, int size) {
|
|
int write=size;
|
|
|
|
|
|
// we call this for stream state handling
|
|
OutputStream::audioPlay(startStamp,endStamp,buffer,size);
|
|
|
|
// store sync information
|
|
avSyncer->audioPlay(startStamp,endStamp,buffer,size);
|
|
|
|
|
|
// here we simulate our own blocking audio device
|
|
if (stream->isOpen()==false) {
|
|
audioTime->sleepWrite(size);
|
|
} else {
|
|
write=stream->write(buffer,size,startStamp);
|
|
}
|
|
return write;
|
|
|
|
}
|
|
|
|
|
|
int ArtsOutputStream::read(char** buffer,int bytes) {
|
|
int back=stream->readRemote(buffer,bytes);
|
|
return back;
|
|
}
|
|
|
|
|
|
void ArtsOutputStream::forwardReadPtr(int bytes) {
|
|
audioTime->forwardTime(bytes);
|
|
stream->forwardReadPtr(bytes);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int ArtsOutputStream::getPreferredDeliverSize() {
|
|
return avSyncer->getPreferredDeliverSize();
|
|
}
|
|
|
|
|
|
int ArtsOutputStream::openWindow(int width, int height,const char *title) {
|
|
threadQueue->waitForExclusiveAccess();
|
|
int back=x11Window->openWindow(width,height,title);
|
|
threadQueue->releaseExclusiveAccess();
|
|
|
|
return back;
|
|
}
|
|
|
|
int ArtsOutputStream::x11WindowId() {
|
|
return x11Window->x11WindowId();
|
|
}
|
|
|
|
void ArtsOutputStream::closeWindow() {
|
|
threadQueue->waitForExclusiveAccess();
|
|
x11Window->closeWindow();
|
|
threadQueue->releaseExclusiveAccess();
|
|
}
|
|
|
|
void ArtsOutputStream::flushWindow() {
|
|
threadQueue->waitForExclusiveAccess();
|
|
x11Window->flushWindow();
|
|
threadQueue->releaseExclusiveAccess();
|
|
}
|
|
|
|
|
|
PictureArray* ArtsOutputStream::lockPictureArray() {
|
|
PictureArray* back;
|
|
threadQueue->waitForExclusiveAccess();
|
|
back=x11Window->lockPictureArray();
|
|
threadQueue->releaseExclusiveAccess();
|
|
return back;
|
|
}
|
|
|
|
|
|
void ArtsOutputStream::unlockPictureArray(PictureArray* pictureArray) {
|
|
|
|
|
|
YUVPicture* pic=pictureArray->getYUVPictureCallback();
|
|
if (avSyncer->syncPicture(pic)==false) {
|
|
return;
|
|
}
|
|
threadQueue->waitForExclusiveAccess();
|
|
x11Window->unlockPictureArray(pictureArray);
|
|
threadQueue->releaseExclusiveAccess();
|
|
|
|
}
|
|
|
|
int ArtsOutputStream::getBufferFillgrade() {
|
|
return stream->getFillgrade();
|
|
}
|
|
|
|
int ArtsOutputStream::getFrameusec() {
|
|
return avSyncer->getFrameusec();
|
|
}
|
|
|
|
|
|
|
|
void ArtsOutputStream::setAudioBufferSize(int size) {
|
|
avSyncer->setAudioBufferSize(privateBufferSize+size);
|
|
}
|
|
|
|
|
|
void ArtsOutputStream::config(const char* key,const char* value,
|
|
void* user_data) {
|
|
|
|
threadQueue->waitForExclusiveAccess();
|
|
avSyncer->config(key,value,user_data);
|
|
x11Window->config(key,value,user_data);
|
|
threadQueue->releaseExclusiveAccess();
|
|
}
|