ngraziano / SharpRTSP

A RTSP handling library
Other
557 stars 182 forks source link

AAC RTP packets with multiple AU units per packet #81

Open belveder79 opened 1 year ago

belveder79 commented 1 year ago

Thx for your continued effort to improve this asset...

I was wondering how you tested the AACPayload, but at least for me it does not work with e.g. ffmpeg.

https://github.com/ngraziano/SharpRTSP/blob/3ce0caf142206488869523369ac8fa8c7c1cbb24/RTSP/AACPayload.cs#L112

Overall the code only works if there is just one AU unit present, as the AU units are usually lined up sequentially at the beginning of the payload and the header length (in byte / 2) gives the number of AUs present. The code assumes there is one AU unit, but as there are usually more, it might loose 2-3 other AU units and the outcome is choppy...

instead of using the while loop, I use this one, which seems to work fine:

int ptr = 0;
if (ptr + 2 > rtp_payload.Length) return audio_data; // 2 bytes for AU Header Length

// Get Size of the AU Header
int au_headers_length_bits = (((rtp_payload[ptr] << 8) + (rtp_payload[ptr + 1] << 0))); // 16 bits
int au_headers_length = (int)Math.Ceiling((double)au_headers_length_bits / 8.0);
ptr += 2;

int cnt = 0;
for(int p = 0; p < au_headers_length>>1; p++)
{
  int aac_frame_size = (((rtp_payload[ptr + 2 * p] << 8) + (rtp_payload[ptr + 2 * p + 1] << 0)) >> 3); // 13 bits
  int aac_index_delta = rtp_payload[ptr + 2 * p + 1] & 0x03; // 3 bits

  // extract the AAC block
  if ((ptr + au_headers_length + cnt ) + aac_frame_size > rtp_payload.Length) break; // not enough data to copy
  byte[] aac_data = new byte[aac_frame_size];
  Array.Copy(rtp_payload, (ptr + au_headers_length + cnt), aac_data, 0, aac_frame_size);
  audio_data.Add(aac_data);

  cnt += aac_frame_size;
}
return audio_data;

Any feedback would be great... cheers...

RogerHardiman commented 1 year ago

Many thanks for this.

When I wrote the code to extract AAC, all I had to use was an online Big Buck Bunny test RTSP stream. I don't think I tested it on any RTSP source.

Many thanks for the code contribution. If you want to do it as a Pull Request then you will be listed in the Contributors section by github.

belveder79 commented 1 year ago

thx - will create a pull request....

RogerHardiman commented 1 year ago

Pull Request has been added. Many thanks for that. It is nice to keep your name in the history.

I had a quick question. What device was sending AAC that showed up the problem? For example, was it a particular make of IP camera?

belveder79 commented 1 year ago

thx... I was just testing with ffmpeg and streaming directly from an RTSP client like PHZ76/RtspServer I also passed it through a server like aler9/rtsp-simple-server, so the implementation just did not consider the case of more than one aac packet per payload...