Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

access raw RTP packets (headers and all) #58

Closed
RustPanda opened this issue Apr 25, 2022 · 10 comments
Closed

access raw RTP packets (headers and all) #58

RustPanda opened this issue Apr 25, 2022 · 10 comments
Labels
enhancement New feature or request

Comments

@RustPanda
Copy link

Hello. How to Get raw Rtp Package? I want to redirect rtp packages to gstreamer rtph264depay.

@RustPanda
Copy link
Author

webrtc-rs example:

let mut buf = [0u8; 1500];
while let Ok((size, _)) = track.read(&mut buf).await {
    let mut buffer = gst::Buffer::with_size(size)
        .map_err(|err| tracing::error!("{err}"))
        .unwrap();
    {
        let buffer = buffer.get_mut().unwrap();
        buffer
            .copy_from_slice(0, &buf[..size])
            .map_err(|err| tracing::error!("{err}"))
            .unwrap();
    }

    appsrc
        .push_buffer(buffer)
        .map_err(|err| tracing::error!("{err}"))
        .unwrap();
}

@scottlamb
Copy link
Owner

"Package" = "packet", right?

retina::client::Session implements futures::Stream<Item = Result<retina::client::PacketItem, retina::Error>>, so roughly:

use futures::StreamExt; // for StreamExt::next

while let Some(pkt) = session.next().await {
    let pkt = pkt.unwrap();
    match pkt {
        PacketItem::RtpPacket(p) => {
            // see p.timestamp, p.payload, etc.
        },
        _ => {} // RTCP sender report; additional payload types in the future
    }
}

@RustPanda
Copy link
Author

@scottlamb yes, packet. I want to get slice, raw bytes:

let mut buf = [0u8; 1500]; <--- my buffer for rtp packet.
while let Ok((size, _)) = track.read(&mut buf).await { <--- I receive a packet
...

PacketItem::RtpPacket(p) != &buf[..size] :)

I can not send PacketItem::RtpPacket(p) to rtph264depay
I need a non-deserialized package to integrate gstreamre

@scottlamb
Copy link
Owner

Oh, the full unparsed RTP packet including the headers? That's not currently available; the non-payload parts are trimmed away here:

retina/src/client/rtp.rs

Lines 203 to 204 in 375754a

data.truncate(payload_range.end);
data.advance(payload_range.start);

There's no reason we couldn't keep it around, except that we currently expose the Bytes of the payload, and I'd prefer not to have two Bytes (which would both bloat the struct and require an extra refcount). In the next breaking API change I'm likely to get rid of the exposed payload Bytes anyway in favor of borrowing a &[u8] or similar. (See #47.) Then making the full RTP packet available would be no problem.

Out of curiosity, is there a particular reason you want to use gstreamer's rtph264depay rather than Retina's H.264 depacketization code? I'm not too familiar with gstreamer but I have to imagine they also provide a way to pass in the already-assembled access units as in retina::codec::VideoFrame.

@RustPanda
Copy link
Author

RustPanda commented Apr 25, 2022

@scottlamb i tried to use gstreamer-rtp to send rtp payload to gst-pipeline but it doesn't work.

More convenient to send raw rtp to Gstreamer and webrtc-rs.

@scottlamb
Copy link
Owner

I mean skipping the rtph264depay step, instead feeding output from Retina's Demuxer (which does roughly the same thing) directly into whatever you'd otherwise feed rtph264depay's output into. I imagine it's possible, but I'm not sure how due to my inexperience with gstreamer.

But anyway, I'm working on #47 and think with those API changes, it'll be pretty easy to support getting the full raw RTP packets.

@scottlamb scottlamb changed the title How to Get raw Rtp Package access raw RTP packets (headers and all) Apr 27, 2022
@scottlamb scottlamb added the enhancement New feature or request label Apr 27, 2022
scottlamb added a commit that referenced this issue Apr 28, 2022
As described in #47 and #58: revamp this type to keep the full raw
packet, and provide accessors rather than raw fields. It's also
smaller now, which is nice.
@scottlamb
Copy link
Owner

I just pushed the next branch with a bunch of API changes, including one that lets you get the full raw packet as requested here. I'm not done with all the breaking changes, but if you enjoy the bleeding edge, please check it out.

@RustPanda
Copy link
Author

@scottlamb thank you very much

@RustPanda
Copy link
Author

@scottlamb, i managed to get a stable connection. Here is the code I have been playing with: RTSPlay

@scottlamb
Copy link
Owner

Cool! Glad it worked, and thanks for sharing that code. Learning more about GStreamer has been on my todo list. If I get a chance, I might play around with your code and see if I can remove the rtph264depay as I suggested above.

From what little I've seen, I really like GStreamer's pipeline model. Seems like overkill for Retina by itself, but maybe someday someone will write a larger media framework in pure Rust...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants