[Live-devel] Writing Speex encoder Filter

ternyk ternyk at gmail.com
Fri Sep 10 03:18:10 PDT 2010


Hello,

I'm trying to implement streaming Speex encoded audio data (RTP Speex
payload) from a microphone. I've read FAQ and checked mailing list so I had
point of start but now I can not go further.
I've decided to start first with streaming WAV file transcoded to Speex.
I created SpeexAudioFileServerMediaSubsession which was based on
WAVAudioFileServerMediaSubsession but when playing the stream VLC I get only
messages (with no audio):
....
live555 debug: tk->rtpSource->hasBeenSynchronizedUsingRTCP()
main error: ES_OUT_RESET_PCR called
main debug: Buffering 0%
main debug: Buffering 17%
main debug: Buffering 34%
main debug: Buffering 51%
main debug: Buffering 68%
main debug: Buffering 85%
main debug: Stream buffering done (1238 ms in 1238 ms)
main debug: Decoder buffering done in 0 ms
main debug: End of audio preroll
main warning: PTS is out of range (15713989), dropping buffer
main warning: PTS is out of range (15900246), dropping buffer
main warning: PTS is out of range (16089345), dropping buffer
main warning: PTS is out of range (16271773), dropping buffer
main warning: PTS is out of range (16458644), dropping buffer
main warning: PTS is out of range (16646190), dropping buffer
main warning: PTS is out of range (16832643), dropping buffer
main warning: PTS is out of range (17018080), dropping buffer


I wonder if I have to change fPresentationTime? Original time comes from
WAVAudioFileSource but after encoding frames with Speex should I do any
changes to it?

BTW Is there any reliable player for RTP/Speex? Maybe my problem is a player
that doesn't support the protocol and codec (I tested with VLC and mplayer)


Thanks in advance for help.

regards,
ternyk



Some snippets from my code:

*********************************************************
WAVAudioFileServerMediaSubsession:

--------------
createNewStreamSource:
WAVAudioFileSource* wavSource
= WAVAudioFileSource::createNew(envir(), fFileName);
...
//add if needed
resultSource = uLawFromPCMAudioSource::createNew(envir(), wavSource);
resultSource = EndianSwap16::createNew(envir(), wavSource);
...
fSamplingFrequency = 8000;
fNumChannels = 1;
unsigned bitsPerSecond
= fSamplingFrequency*fBitsPerSample*fNumChannels;
SpeexTranscoder* speexFilter = SpeexTranscoder::createNew(envir(),
SPEEX_MODE_NARROWBAND, bitsPerSecond, resultSource);
resultSource = speexFilter;

return resultSource;

----------------
createNewRTPSink:

return SimpleRTPSink::createNew(envir(), rtpGroupsock,
96, fSamplingFrequency,
"audio", "speex", fNumChannels);

*****************************************************************
in SpeexTranscoder:
-----------

SpeexInit:

encoder_state = speex_encoder_init( speex_mode );

int tmp;

tmp=0;
speex_encoder_ctl(encoder_state, SPEEX_SET_VBR, &tmp);
int quality = 8;
speex_encoder_ctl(encoder_state, SPEEX_SET_QUALITY, &quality); // 8:
27,800[bps]
tmp=3;
speex_encoder_ctl(encoder_state, SPEEX_SET_COMPLEXITY, &tmp);
speex_encoder_ctl( encoder_state, SPEEX_GET_FRAME_SIZE, &speex_frame_size );
speex_bits_init( &encoder_bits );

resampler = speex_resampler_init(1, 44100, 8000, quality, &tmp);


---------------
afterGettingFrame1:

fFrameSize = TranscodeSpeex(fOrigADU, numBytesRead, fOutBitrate,
fTo, fMaxSize, fAvailableBytesForBackpointer);

if (fFrameSize == 0) { // internal error - bad ADU data?
handleClosure(this);
return;
}

// Complete delivery to the client:
fNumTruncatedBytes = numTruncatedBytes;
fPresentationTime = presentationTime;
fDurationInMicroseconds = durationInMicroseconds;
afterGetting(this);

-----------
TranscodeSpeex:

unsigned SpeexTranscoder::TranscodeSpeex(unsigned char const* fromPtr,
unsigned fromSize, unsigned toBitrate, unsigned char* toPtr, unsigned
toMaxSize, unsigned& availableBytesForBackpointer) {

int err;
char tmp[MAX_MP3_FRAME_SIZE];
const spx_int16_t *in = (spx_int16_t*)fromPtr;
unsigned in_len = fromSize;
spx_int16_t* out = (spx_int16_t*)tmp;
unsigned out_len;
err = speex_resampler_process_int(resampler, 0, in, &in_len, out, &out_len);

speex_bits_reset( &encoder_bits );
speex_encode_int( encoder_state, out, &encoder_bits );
speex_packet_size = speex_bits_write( &encoder_bits, (char*)fTo, toMaxSize);
return speex_packet_size;
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.live555.com/pipermail/live-devel/attachments/20100910/53da87e1/attachment.html>


More information about the live-devel mailing list