02-08-2012 02:02 AM
Hi Sir,
can you give me the code sample according to my above given RecvStream.java class because i implemented
its many way but i unable to solve this issue. so please sir help me.
thanks
Saurabh
02-08-2012 11:37 AM
02-09-2012 02:17 AM
To play PCM data you can do the follwoing,
1. use x-wav while creating the player.
2. add wav header to the pcm data.
3. Extend ByeArrayInputStream to implement your own input stream that will be provided to player
4. In the extended class read(), reset(), skip() and available() method should be carefully implemented
5. If you want play continuous stream, available should always return a high value like 0x7fffffff
6. Any read() after a call to reset should always return the header first and then data in subsequent read call
Hope this helps.
02-09-2012 07:48 AM
Hi sir,
I want to some help only for finding the length of "buf"
byte[] buf = buffer.dequeue();
In this line of code my rtp packet decoded and store in "buf" given in above code.
so please sir only help how to find the length of "buf"
and how to copy the array in my read() method.
Please sir help.
Thanks
Saurabh
02-09-2012 09:38 AM
It is difficult to follow the code as formatting is lost. The buffer seems to be a custom class (mypackage.ByteBuffer).
But the strategy i think you should follow is have a byte[] of say 100000 and use it as ring buffer. Whenever player calls read return the data available from last read position to current write position.
So recv rtp packet and write the data in the byte[] (after the header data) and increment write position. In read just return the data between last read position and new write position. Obviously you need to take care of boundary conditions.
While doing createplayer() player calls reset()->read()->reset() and read(), read() and so on. So in the first read you supply the header. Any read after reset should also provide the header.
Hope you are aware of the player buffering in BB also. As if you do not supply enough data to player it will stop playing
Also using audio/x-wav may help instead of audio/pcm.
02-09-2012 11:51 AM
02-10-2012 08:24 AM
Hi sir,
can you help me how to add webHeader receving "packet" from given line.
RtpPacket packet ;
packet = mSession.recvPacket((int) mPlayerTs);
because this line return the "int packet and player time stamp."
Thanks
saurabh
02-14-2012 08:25 AM
Hi Sir,
Please Sir Help me give me some tipse to add wevHeader in my receve voice packet.
Thanks
02-15-2012 05:45 AM
What you can do is as follows,
1. define a byte array for the header. WAV header is as follows,
private byte[] Header8K =
{
(byte)0x52, (byte)0x49, (byte)0x46, (byte)0x46,
(byte)0xff, (byte)0xff, (byte)0xff, (byte)0x07,
(byte)0x57, (byte)0x41, (byte)0x56, (byte)0x45,
(byte)0x66, (byte)0x6d, (byte)0x74, (byte)0x20,
(byte)0x10, (byte)0x00, (byte)0x00, (byte)0x00,
(byte)0x01, (byte)0x00, (byte)0x01, (byte)0x00,
(byte)0x40, (byte)0x1f, (byte)0x00, (byte)0x00, // 8000
(byte)0x80, (byte)0x3e, (byte)0x00, (byte)0x00, // 16000
(byte)0x02, (byte)0x00, (byte)0x10, (byte)0x00,
(byte)0x64, (byte)0x61, (byte)0x74, (byte)0x61,
(byte)0xdb, (byte)0xff, (byte)0xff, (byte)0x07
} ;
2. Store the rtp data in a separate buffer
3. Whenever inputstraem read is called after a reset() call, return the header data only (44 bytes)
4. In the subsequent read() call provide actual data. But do keep track how much is written in the buffer and how much is read. Also special care should be taken for boundary conditions.
02-27-2012 08:03 AM
Hi sir
I am using your given Header But it Throough the exception please see below:--
................
Thread [jlinphone(237)id=69422080] (Suspended (exception ArrayIndexOutOfBoundsException))
RecvStream$1.read(byte[], int, int) line: 128
StreamModifyingDataSource$HeaderAddingSourceStream
DataSourceInputStream.read(byte[], int, int) line: 38
RingBuffer.write(InputStream) line: 310
MediaPlayer.read() line: 458
MediaPlayer.moreData() line: 429
MediaStreamingManagerImpl$StreamingSessionImpl$Rea
////////////////////////////////////////////------
so sir please help me what can i do for resolve this isssue.
.....................................
public class RecvStream implements /*Runnable,*/ PlayerListener {
private Player mPlayer;
private SendStream mSendStream;
private WavHeaderAppender header;
private RtpSession mSession;
private long mStartTime=0;
private boolean mFirstRead=true;
private boolean mRunning;
private boolean mBuffering=true;
private static Logger sLogger=JOrtpFactory.instance().createLogger("Recv
private long mPlayerTs=-1;
private byte[] tempBuffer = new byte[160];
private long mReturnedMs=0;
private void reset() {
mPlayer=null;
mStartTime=0;
mFirstRead=true;
mBuffering=true;
mPlayerTs=-1;
mReturnedMs=0;
}
private SourceStream mInput= new SourceStream(){
private byte[] Header8K =
{
(byte)0x52, (byte)0x49, (byte)0x46, (byte)0x46,
(byte)0xff, (byte)0xff, (byte)0xff, (byte)0x07,
(byte)0x57, (byte)0x41, (byte)0x56, (byte)0x45,
(byte)0x66, (byte)0x6d, (byte)0x74, (byte)0x20,
(byte)0x10, (byte)0x00, (byte)0x00, (byte)0x00,
(byte)0x01, (byte)0x00, (byte)0x01, (byte)0x00,
(byte)0x40, (byte)0x1f, (byte)0x00, (byte)0x00, // 8000
(byte)0x80, (byte)0x3e, (byte)0x00, (byte)0x00, // 16000
(byte)0x02, (byte)0x00, (byte)0x10, (byte)0x00,
(byte)0x64, (byte)0x61, (byte)0x74, (byte)0x61,
(byte)0xdb, (byte)0xff, (byte)0xff, (byte)0x07
} ;
private RtpPacket mTroncatedPacket;
private int mTroncatedPacketSize;
private boolean priority_set=false;
ContentDescriptor mContentDescriptor=new ContentDescriptor("audio/pcm");
public int read(byte[] b, int offset, int length) throws IOException {
int bytesToReturn=Header8K.length;
if (mBuffering){
bytesToReturn=Header8K.length*8;
}
try {
if (!priority_set && Thread.currentThread().getPriority() != Thread.MAX_PRIORITY) {
Thread.currentThread().setPriority(Thread.MAX_PRIO
priority_set=true;
}
int lWrittenLenth=0;
while(lWrittenLenth<=bytesToReturn && mRunning){
long ts=getCurTs();
if (mPlayerTs==-1) {
mPlayerTs=ts;
sLogger.info("Initializing timestamp to ["+mPlayerTs+"]");
}
RtpPacket packet=null;
try {
long diff;
while((diff=(ts-mPlayerTs))>=0){
if (diff> 400){
mPlayerTs=ts-400;
sLogger.warn("Too late, skipping "+ ((diff-400)/4) +" ms...");
}
packet=mSession.recvPacket((int)mPlayerTs);
if (packet!=null){
mReturnedMs+=20;
if (mFirstRead) {
lWrittenLenth=tempBuffer.length;
System.arraycopy(packet.getBytes(), 12,
tempBuffer, 0, 160);
byte[] dencoded = new byte[tempBuffer.length * 2];
for (int i = 0, j = 0; i < tempBuffer.length; i++) {
int s = tempBuffer[i];
int res = G711.ulaw2linear(s);
dencoded[j++] = (byte) (res);
dencoded[j++] = (byte) (res >> 8);
//header.appendWavHeader(dencoded);
}
System.arraycopy(dencoded,0, b, offset, lWrittenLenth );
length = length - lWrittenLenth;
offset+=lWrittenLenth;
mFirstRead=false;
}
if ((length < Header8K.length)) {
// special case for end of buffer
System.arraycopy(packet.getBytes(),packet.getDataO
lWrittenLenth+= length;
mTroncatedPacketSize=length;
mTroncatedPacket = packet;
if (sLogger.isLevelEnabled(Logger.Warn)) sLogger.warn("End of buffer, ["+lWrittenLenth+"] bytes returned");
return lWrittenLenth;
}else{
if (mTroncatedPacket != null) {
// special case for troncated packet
int remain=mTroncatedPacket.getRealLength()-mTroncated
System.arraycopy(mTroncatedPacket.getBytes(),mTron
lWrittenLenth+= remain;
mTroncatedPacketSize=0;
mTroncatedPacket = null;
offset+= remain;
length-=remain;
}
//+1 because we need to skip the CMR bytes
int datalen=packet.getRealLength()-packet.getDataOffse
System.arraycopy(packet.getBytes(),packet.getDataO
lWrittenLenth+= datalen;
length-=datalen;
offset+=datalen;
}
}
mPlayerTs+=160;
}
} catch (RtpException e) {
sLogger.error("Bad RTP packet", e);
}
if (packet==null) Thread.sleep(20);
}
if (!mRunning){
//to notify end of stream.
return -1;
}
if (sLogger.isLevelEnabled(Logger.Debug)) sLogger.debug("["+lWrittenLenth+"] bytes returned");
return lWrittenLenth;
} catch (Throwable e) {
sLogger.error("Exiting player input stream",e);
return -1;
}
finally {
if (bytesToReturn > Header8K.length) {
// we were buffering, so now it's ok resetting value
mBuffering=false;
}
}
}
Thanks