sample format in codec

git-svn-id: svn://elaine/murooma/trunk@226 d8a302eb-03bc-478d-80e4-98257eca68ef
This commit is contained in:
(no author) 2014-08-31 18:44:06 +00:00
parent 192aa6fd9e
commit b7e63a91c8
7 changed files with 48 additions and 31 deletions

View file

@ -2,7 +2,6 @@
#define DECODER_H #define DECODER_H
#include "common/chunk.h" #include "common/chunk.h"
class Decoder class Decoder
{ {
public: public:

View file

@ -1,13 +1,24 @@
#ifndef ENCODER_H #ifndef ENCODER_H
#define ENCODER_H #define ENCODER_H
#include "common/chunk.h" #include "common/chunk.h"
#include "common/sampleFormat.h"
class Encoder class Encoder
{ {
public: public:
Encoder(); Encoder(const SampleFormat& format) : sampleFormat(format)
{
}
virtual double encode(Chunk* chunk) = 0; virtual double encode(Chunk* chunk) = 0;
virtual WireChunk* getHeader()
{
return NULL;
}
protected:
SampleFormat sampleFormat;
}; };

View file

@ -5,21 +5,16 @@
using namespace std; using namespace std;
OggEncoder::OggEncoder() OggEncoder::OggEncoder(const SampleFormat& format) : Encoder(format), headerChunk(NULL)
{ {
init(); init();
lastGranulepos = -1; lastGranulepos = -1;
} }
bool OggEncoder::getHeader(Chunk* chunk) WireChunk* OggEncoder::getHeader()
{ {
WireChunk* wireChunk = chunk->wireChunk; return headerChunk;
wireChunk->type = chunk_type::header;
wireChunk->payload = (char*)realloc(wireChunk->payload, oggHeaderLen);
memcpy(wireChunk->payload, oggHeader, oggHeaderLen);
wireChunk->length = oggHeaderLen;
return true;
} }
@ -137,7 +132,7 @@ void OggEncoder::init()
*********************************************************************/ *********************************************************************/
ret=vorbis_encode_init_vbr(&vi,2,48000,0.7); ret=vorbis_encode_init_vbr(&vi, sampleFormat.channels, sampleFormat.rate, 0.9);
/* do not continue if setup failed; this can happen if we ask for a /* do not continue if setup failed; this can happen if we ask for a
mode that libVorbis does not support (eg, too low a bitrate, etc, mode that libVorbis does not support (eg, too low a bitrate, etc,
@ -176,21 +171,22 @@ void OggEncoder::init()
*/ */
// while(!eos){ // while(!eos){
size_t pos(0); size_t pos(0);
oggHeader = (char*)malloc(0); headerChunk = Chunk::makeChunk(chunk_type::header, 0);
oggHeaderLen = 0;
while (true) while (true)
{ {
int result=ogg_stream_flush(&os,&og); int result=ogg_stream_flush(&os,&og);
if (result == 0) if (result == 0)
break; break;
oggHeaderLen += og.header_len + og.body_len; headerChunk->length += og.header_len + og.body_len;
oggHeader = (char*)realloc(oggHeader, oggHeaderLen); headerChunk->payload = (char*)realloc(headerChunk->payload, headerChunk->length);
cout << "HeadLen: " << og.header_len << ", bodyLen: " << og.body_len << ", result: " << result << "\n"; cout << "HeadLen: " << og.header_len << ", bodyLen: " << og.body_len << ", result: " << result << "\n";
memcpy(oggHeader + pos, og.header, og.header_len); memcpy(headerChunk->payload + pos, og.header, og.header_len);
pos += og.header_len; pos += og.header_len;
memcpy(oggHeader + pos, og.body, og.body_len); memcpy(headerChunk->payload + pos, og.body, og.body_len);
pos += og.body_len; pos += og.body_len;
} }
// fwrite(og.header,1,og.header_len,stdout); // fwrite(og.header,1,og.header_len,stdout);
// fwrite(og.body,1,og.body_len,stdout); // fwrite(og.body,1,og.body_len,stdout);
// } // }

View file

@ -4,12 +4,12 @@
#include <vorbis/vorbisenc.h> #include <vorbis/vorbisenc.h>
class OggEncoder class OggEncoder : public Encoder
{ {
public: public:
OggEncoder(); OggEncoder(const SampleFormat& format);
virtual double encode(Chunk* chunk); virtual double encode(Chunk* chunk);
virtual bool getHeader(Chunk* chunk); virtual WireChunk* getHeader();
private: private:
void init(); void init();
@ -31,11 +31,10 @@ private:
ogg_packet header_code; ogg_packet header_code;
ogg_int64_t lastGranulepos; ogg_int64_t lastGranulepos;
WireChunk* headerChunk;
int eos=0,ret; int eos=0,ret;
int i, founddata; int i, founddata;
char* oggHeader;
int oggHeaderLen;
int32_t tv_sec; int32_t tv_sec;
int32_t tv_usec; int32_t tv_usec;

View file

@ -1,6 +1,6 @@
#include "pcmEncoder.h" #include "pcmEncoder.h"
PcmEncoder::PcmEncoder() PcmEncoder::PcmEncoder(const SampleFormat& format) : Encoder(format)
{ {
} }

View file

@ -3,10 +3,10 @@
#include "encoder.h" #include "encoder.h"
class PcmEncoder class PcmEncoder : public Encoder
{ {
public: public:
PcmEncoder(); PcmEncoder(const SampleFormat& format);
virtual double encode(Chunk* chunk); virtual double encode(Chunk* chunk);
}; };

View file

@ -150,7 +150,8 @@ cout << "Sending header: " << headerChunk->wireChunk->length << "\n";
void setHeader(shared_ptr<Chunk> chunk) void setHeader(shared_ptr<Chunk> chunk)
{ {
headerChunk = chunk; if (chunk && (chunk->wireChunk != NULL))
headerChunk = shared_ptr<Chunk>(chunk);
} }
void send(shared_ptr<Chunk> chunk) void send(shared_ptr<Chunk> chunk)
@ -220,13 +221,15 @@ int main(int argc, char* argv[])
size_t port; size_t port;
string fifoName; string fifoName;
string codec;
bool runAsDaemon; bool runAsDaemon;
po::options_description desc("Allowed options"); po::options_description desc("Allowed options");
desc.add_options() desc.add_options()
("help,h", "produce help message") ("help,h", "produce help message")
("port,p", po::value<size_t>(&port)->default_value(98765), "port to listen on") ("port,p", po::value<size_t>(&port)->default_value(98765), "port to listen on")
("sampleformat,f", po::value<string>(&sampleFormat)->default_value("48000:16:2"), "sample format") ("sampleformat,s", po::value<string>(&sampleFormat)->default_value("48000:16:2"), "sample format")
("codec,c", po::value<string>(&codec)->default_value("ogg"), "transport codec [ogg|pcm]")
("fifo,f", po::value<string>(&fifoName)->default_value("/tmp/snapfifo"), "name of fifo file") ("fifo,f", po::value<string>(&fifoName)->default_value("/tmp/snapfifo"), "name of fifo file")
("daemon,d", po::bool_switch(&runAsDaemon)->default_value(false), "daemonize") ("daemon,d", po::bool_switch(&runAsDaemon)->default_value(false), "daemonize")
; ;
@ -276,9 +279,18 @@ int main(int argc, char* argv[])
size_t duration = 50; size_t duration = 50;
SampleFormat format(sampleFormat); SampleFormat format(sampleFormat);
OggEncoder encoder; std::auto_ptr<Encoder> encoder;
shared_ptr<Chunk> header(new Chunk(format, Chunk::makeChunk(chunk_type::header, 0))); if (codec == "ogg")
encoder.getHeader(header.get()); encoder.reset(new OggEncoder(sampleFormat));
else if (codec == "pcm")
encoder.reset(new PcmEncoder(sampleFormat));
else
{
cout << "unknown codec: " << codec << "\n";
return 1;
}
shared_ptr<Chunk> header(new Chunk(format, encoder->getHeader()));
server->setHeader(header); server->setHeader(header);
while (!g_terminated) while (!g_terminated)
@ -307,7 +319,7 @@ size_t duration = 50;
wireChunk->tv_sec = tvChunk.tv_sec; wireChunk->tv_sec = tvChunk.tv_sec;
wireChunk->tv_usec = tvChunk.tv_usec; wireChunk->tv_usec = tvChunk.tv_usec;
double chunkDuration = encoder.encode(chunk.get()); double chunkDuration = encoder->encode(chunk.get());
if (chunkDuration > 0) if (chunkDuration > 0)
server->send(chunk); server->send(chunk);
//cout << wireChunk->tv_sec << ", " << wireChunk->tv_usec / 1000 << "\n"; //cout << wireChunk->tv_sec << ", " << wireChunk->tv_usec / 1000 << "\n";