Author Topic: pushing rtp to a stream  (Read 156 times)

drugoimir

  • Posts: 39
pushing rtp to a stream
« on: 20 Oct '21 - 13:18 »
Hello Ian,
i need to push mp3, ogg, or linear data to a stream (decoded from an RTP source).

I could use BASS_StreamCreateFileUser which accommodates most formats but i see that BASS_FILEPROCS
must be defined in order to initialize the right coder at the beginning of the file, but i've no file... i have my data right in memory.
What i need is a way to create a channel, defining its encoding (pcm, mp3, whatever) and then push data to it.

Regards.

 

Ian @ un4seen

  • Administrator
  • Posts: 23991
Re: pushing rtp to a stream
« Reply #1 on: 20 Oct '21 - 15:00 »
You can use BASS_StreamCreate with PCM data, but BASS_StreamCreateFileUser will be needed for encoded (MP3/etc) data. Note the data can come from anywhere. If you have the data in memory then your FILEREADPROC callback function would read/copy it from there.

drugoimir

  • Posts: 39
Re: pushing rtp to a stream
« Reply #2 on: 20 Oct '21 - 16:50 »
That's fine,
will then Bass automatically detect the format of data i'm sending  (mp3 ogg or whatever else) ?

Ian @ un4seen

  • Administrator
  • Posts: 23991
Re: pushing rtp to a stream
« Reply #3 on: 20 Oct '21 - 17:24 »
Yes, BASS_StreamCreateFileUser will call your BASS_FILEPROCS functions to get some data so that it can detect the format and initialize a decoder, before returning a new stream handle (if successful). After that, your functions will be called again whenever more data is needed or you can use BASS_StreamPutFileData to provide it, depending on whether you used STREAMFILE_BUFFERPUSH in the BASS_StreamCreateFileUser call.

drugoimir

  • Posts: 39
Re: pushing rtp to a stream
« Reply #4 on: 21 Oct '21 - 08:42 »
Hi Ian,

Does bass, reading the initial data, configure a proper decoder only or it also take other info, just like number of channels, bitrate, samplerate ... ?
I'm asking this because, if it prepares only the right decoder,  it would be possible to have some fake headers (one for each encoding) to  pass  to the  FILEREADPROC  in order to
have the bass channel  ready for decoding before the real streamed data arrives.
In this case i could create the channels once i know the rtp payload type without passing the data initially to initialize the right decoder.
Or .. it would be better if  bass could initialize its decoder through the streamputdata function only, rather having to use the FILEREADPROC initially.
Linear pcm playing is working flawlessly in this way.

I also have to prevent buffer overflow/underflow fine-tuning the channel samplerate. I've already done this with icecast/shoutcast streaming, throttling the samplerate to keep the buffer at a fixed level,
but i see that, in this case, i've no access to check any buffer length because i'm using a decoding channel and it is stated that channelgetdata will not work on those channels. 
What can i do then ?

Thanks for any suggestion.

Ian @ un4seen

  • Administrator
  • Posts: 23991
Re: pushing rtp to a stream
« Reply #5 on: 21 Oct '21 - 13:54 »
Does bass, reading the initial data, configure a proper decoder only or it also take other info, just like number of channels, bitrate, samplerate ... ?

Configuring a decoder generally requires knowing what the decoded format is (eg. sample rate and number of channels), so the initial data will be used for all of the above.

I'm asking this because, if it prepares only the right decoder,  it would be possible to have some fake headers (one for each encoding) to  pass  to the  FILEREADPROC  in order to
have the bass channel  ready for decoding before the real streamed data arrives.

Yes, that may be possible with some file formats, but note that the fake headers would need to accurately represent what the subsequent real data will be.

In this case i could create the channels once i know the rtp payload type without passing the data initially to initialize the right decoder.

Perhaps you could just delay the BASS_StreamCreateFileUser call until you have some data?

I also have to prevent buffer overflow/underflow fine-tuning the channel samplerate. I've already done this with icecast/shoutcast streaming, throttling the samplerate to keep the buffer at a fixed level,
but i see that, in this case, i've no access to check any buffer length because i'm using a decoding channel and it is stated that channelgetdata will not work on those channels. 
What can i do then ?

When using the buffered file system, you can check the "download" buffer space with BASS_StreamGetFilePosition:

Code: [Select]
QWORD space = BASS_StreamGetFilePosition(stream, BASS_FILEPOS_END) - BASS_StreamGetFilePosition(stream, BASS_FILEPOS_BUFFER);

When using BASS_StreamPutFileData, it will return how much data it was able to accept, so you can also detect when the buffer is full from that, ie. when the return value is lower than the "length" parameter.

drugoimir

  • Posts: 39
Re: pushing rtp to a stream
« Reply #6 on: 22 Oct '21 - 11:28 »
Many thanks,

i'll try what you suggested.
To have an order of magnitude, how many data have i to buffer to have the channel properly initialized ?
It should contain at least one header, but how much is enough (for most formats) ?


Regards
« Last Edit: 22 Oct '21 - 11:36 by drugoimir »

Ian @ un4seen

  • Administrator
  • Posts: 23991
Re: pushing rtp to a stream
« Reply #7 on: 22 Oct '21 - 17:08 »
The amount of initial data required to create a stream can vary greatly depending on the format. Do you have a format in mind? If it's MP3 then just 1 frame may suffice, the size of which you can calculate like this: 144000 * bitrate / samplerate + padding. Where "padding" is 0 or 1.