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.
tderadio/plugins/recording/encoder.cpp

173 lines
5.6 KiB

/***************************************************************************
encoder.cpp - description
-------------------
begin : Thu May 05 2005
copyright : (C) 2005 by Martin Witte
email : witte@kawo1.rwth-aachen.de
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include "../../src/include/radiostation.h"
#include "../../src/include/errorlog-interfaces.h"
#include "../../src/include/aboutwidget.h"
#include "recording.h"
#include "recording-configuration.h"
#include "soundstreamevent.h"
#include <tqsocketnotifier.h>
#include <tqevent.h>
#include <tqapplication.h>
#include <tqregexp.h>
#include <tdeconfig.h>
#include <tdeversion.h>
#include <tdelocale.h>
RecordingEncoding::RecordingEncoding(TQObject *parent, SoundStreamID ssid,
const RecordingConfig &cfg, const RadioStation *rs,
const TQString &filename)
:
m_parent(parent),
m_config(cfg),
m_RadioStation(rs ? rs->copy() : NULL),
m_SoundStreamID(ssid),
m_error(false),
m_errorString(TQString()),
m_done(false),
m_InputBuffers(m_config.m_EncodeBufferCount < 3 ? 3 : m_config.m_EncodeBufferCount,
m_config.m_EncodeBufferSize < 4096 ? 4096 : m_config.m_EncodeBufferSize),
m_buffersMetaData(NULL),
m_encodedSize(0),
m_InputStartTime(0),
m_InputStartPosition(0),
m_outputURL(filename)
{
if (m_config.m_EncodeBufferCount < 3)
m_config.m_EncodeBufferCount = 3;
if (m_config.m_EncodeBufferSize < 4096)
m_config.m_EncodeBufferSize = 4096;
m_buffersMetaData = new TQPtrList<BufferSoundMetaData> *[m_config.m_EncodeBufferCount];
for (size_t i = 0; i < m_config.m_EncodeBufferCount; ++i) {
m_buffersMetaData [i] = new TQPtrList<BufferSoundMetaData>;
m_buffersMetaData [i]->setAutoDelete(true);
}
}
RecordingEncoding::~RecordingEncoding()
{
for (size_t i = 0; i < m_config.m_EncodeBufferCount; ++i) {
delete m_buffersMetaData[i];
}
delete m_buffersMetaData;
delete m_RadioStation;
}
char *RecordingEncoding::lockInputBuffer(size_t &bufferSize)
{
if (m_done || m_error)
return NULL;
char * retval = m_InputBuffers.lockWriteBuffer(bufferSize);
m_error |= m_InputBuffers.hasError();
m_errorString += m_InputBuffers.getErrorString();
m_InputBuffers.resetError();
return retval;
}
void RecordingEncoding::unlockInputBuffer(size_t bufferSize, const SoundMetaData &md)
{
if (m_done)
return;
size_t bufidx = m_InputBuffers.getCurrentWriteBufferIdx();
size_t buffill = m_InputBuffers.getWriteBufferFill();
m_InputBuffers.unlockWriteBuffer(bufferSize);
if (!m_InputBuffers.hasError()) {
if (!m_InputStartTime) {
m_InputStartTime = md.absoluteTimestamp();
m_InputStartPosition = md.position();
}
BufferSoundMetaData *bmd = new BufferSoundMetaData(
md.position() - m_InputStartPosition,
md.absoluteTimestamp() - m_InputStartTime,
md.absoluteTimestamp(),
md.url(),
buffill);
m_buffersMetaData[bufidx]->append(bmd);
} else {
m_error = true;
m_errorString += m_InputBuffers.getErrorString();
m_InputBuffers.resetError();
}
}
void RecordingEncoding::setDone()
{
m_done = true;
m_InputBuffers.unlockAllWriteBuffers();
}
void RecordingEncoding::run()
{
BufferSoundMetaData last_md;
while (!m_error) {
char *buffer = NULL;
size_t buffer_fill = 0;
if (!m_done) {
buffer = m_InputBuffers.wait4ReadBuffer(buffer_fill);
}
if (!buffer_fill) {
if (m_done)
break;
else
continue;
}
char *export_buffer = NULL;
size_t export_buffer_size = 0;
TQ_UINT64 old_pos = m_encodedSize;
encode(buffer, buffer_fill, export_buffer, export_buffer_size);
SoundStreamEncodingStepEvent *step_event = NULL;
if (!m_error) {
last_md = *m_buffersMetaData[m_InputBuffers.getCurrentReadBufferIdx()]->first();
SoundMetaData md(old_pos, last_md.relativeTimestamp(), last_md.absoluteTimestamp(), m_outputURL);
step_event = new SoundStreamEncodingStepEvent(m_SoundStreamID, export_buffer, export_buffer_size, md);
}
if (step_event)
TQApplication::postEvent(m_parent, step_event);
}
m_done = true;
closeOutput();
SoundMetaData md(m_encodedSize, last_md.relativeTimestamp(), last_md.absoluteTimestamp(), m_outputURL);
TQApplication::postEvent(m_parent, new SoundStreamEncodingStepEvent(m_SoundStreamID, NULL, 0, md));
TQApplication::postEvent(m_parent, new SoundStreamEncodingTerminatedEvent(m_SoundStreamID));
}