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

read a complete frame every time when use rtspovertcp #126

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

bailb
Copy link
Contributor

@bailb bailb commented May 1, 2024

under rtspovertcp mode. the length of frame is after the '$', and the content is after that. but the previous logic after decoding the length field just read from socket only once, so it's very frequency to occur that the length we decoded not match the real length we read.

@harlanc
Copy link
Owner

harlanc commented May 6, 2024

@bailb Thanks for your contributions, judging from the current logic, if the length is still not satisfied after an additional read of data, the entire RtspServerSession process will exit. Have you ever encountered this situation?

If that is the case, can this problem be solved by replacing if with while?

 pub async fn run(&mut self) -> Result<(), SessionError> {
     loop {
         while self.reader.len() < 4 {
             let data = self.io.lock().await.read().await?;
             self.reader.extend_from_slice(&data[..]);
         }

         if let Ok(data) = InterleavedBinaryData::new(&mut self.reader) {
             match data {
                 Some(a) => {
                     if self.reader.len() < a.length as usize { // replace if with while
                         let data = self.io.lock().await.read().await?;
                         self.reader.extend_from_slice(&data[..]);
                     }
                     self.on_rtp_over_rtsp_message(a.channel_identifier, a.length as usize)
                         .await?;
                 }
                 None => {
                     self.on_rtsp_message().await?;
                 }
             }
         }
     }
 }

@bailb
Copy link
Contributor Author

bailb commented May 6, 2024

@bailb Thanks for your contributions, judging from the current logic, if the length is still not satisfied after an additional read of data, the entire RtspServerSession process will exit. Have you ever encountered this situation?

If that is the case, can this problem be solved by replacing if with while?

 pub async fn run(&mut self) -> Result<(), SessionError> {
     loop {
         while self.reader.len() < 4 {
             let data = self.io.lock().await.read().await?;
             self.reader.extend_from_slice(&data[..]);
         }

         if let Ok(data) = InterleavedBinaryData::new(&mut self.reader) {
             match data {
                 Some(a) => {
                     if self.reader.len() < a.length as usize { // replace if with while
                         let data = self.io.lock().await.read().await?;
                         self.reader.extend_from_slice(&data[..]);
                     }
                     self.on_rtp_over_rtsp_message(a.channel_identifier, a.length as usize)
                         .await?;
                 }
                 None => {
                     self.on_rtsp_message().await?;
                 }
             }
         }
     }
 }

yes, I really encountered this error. and I solved the problem with a loop before. just think it's better use a function with timeout.

.io
.lock()
.await
.read_min_bytes_with_timeout(Duration::from_millis(1000), a.length.into())
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the length parameter passed into the function maybe a.length - self.reader.len() ??

@harlanc
Copy link
Owner

harlanc commented May 11, 2024

@bailb Thanks for your contributions, judging from the current logic, if the length is still not satisfied after an additional read of data, the entire RtspServerSession process will exit. Have you ever encountered this situation?
If that is the case, can this problem be solved by replacing if with while?

 pub async fn run(&mut self) -> Result<(), SessionError> {
     loop {
         while self.reader.len() < 4 {
             let data = self.io.lock().await.read().await?;
             self.reader.extend_from_slice(&data[..]);
         }

         if let Ok(data) = InterleavedBinaryData::new(&mut self.reader) {
             match data {
                 Some(a) => {
                     if self.reader.len() < a.length as usize { // replace if with while
                         let data = self.io.lock().await.read().await?;
                         self.reader.extend_from_slice(&data[..]);
                     }
                     self.on_rtp_over_rtsp_message(a.channel_identifier, a.length as usize)
                         .await?;
                 }
                 None => {
                     self.on_rtsp_message().await?;
                 }
             }
         }
     }
 }

yes, I really encountered this error. and I solved the problem with a loop before. just think it's better use a function with timeout.

From your perspective, why it is better to use timeout?

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

Successfully merging this pull request may close these issues.

None yet

2 participants