# Recording proposal...still having corruption issues in recorded content

**URL:** <https://discourse.lynckia.com/t/recording-proposal-still-having-corruption-issues-in-recorded-content/281>\
**Category:** Uncategorized\
**Created:** [September 17, 2014, 2:14pm UTC](https://discourse.lynckia.com/t/recording-proposal-still-having-corruption-issues-in-recorded-content/281 "2014-09-17T14:14:12Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![Pedro\_Rodriguez](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.lynckia.com/pedro_rodriguez/32/23_2.png) [@Pedro\_Rodriguez](https://discourse.lynckia.com/u/Pedro_Rodriguez)\
**Post date:** [September 17, 2014, 2:14pm UTC](https://discourse.lynckia.com/t/recording-proposal-still-having-corruption-issues-in-recorded-content/281/1 "2014-09-17T14:14:12Z")

</div>

Hi Jeremy,

First of all I want to thank you for your effort and contributions to Licode. We really appreciate your work and your input. Get ready for a long answer 🙂

I understand your concerns regarding the actual state of recording, as it is, Licode does not implements the mechanisms you mention to manage packet loss. This is due to lack of development effort but also there are some design decisions involved.  
It doesn’t handle packet loss correctly; it should be sending a NACK on a lost packet on the RTCP back-channel.  
It doesn’t handle FEC correctly (there’s an entire packet type of 117 that it licode is droppoing on the floor).  
Licode allows recording, yes. But it is primarily designed to be used in a videoconferencing scenario. We give a low priority to implementing FEC handling and RTCP reporting because Chrome clients (subscribers), DO implement this, and Licode makes sure this RTCP messages (NACK, REMB, etc.) ARE forwarded (in a quite brute way at this point, we plan on improving this).

Publisher ————(A)———\> Licode ———(B) ———\> subscriber.

For the communication, it is important to control packet loss both in A and B. With our limited resources, we decided it was better to pass RTCP packets from the subscriber instead of generating a new RTCP stream from Licode.

This, of course, means that if there are no subscribers in the session, no packet loss will be reported. That is the case of a record-only session. Also, as you point out, we discard red data and fec packets WHEN recording, we know that is quite far from optimal. Do you have other subscribers in your recording session?

Another difference with recording is that you need periodic keyframes to be able to seek within a recorded video, we manually ask for them via FIR (Frame-intra-request) messages.

This approach has provided very good communication experiences in our projects and decent-to-good recording quality.

On how to proceed: As I mentioned, we want to add more intelligence to Licode regarding RTCP. I would definitely improve ExternalOutput and the (now almost totally yours) RtpQueue so they can report packets loss, use redundancy packets and so on.

We don’t want to use Google’s library in Licode’s core for a variety of engineering, scientific, socio-political and philosophical reasons. We prefer to increasingly improve what we have according to the standards while being compatible with Google.

However, there is another option. You can use Google’s webRTC library for recording without altering Licode, you can create a stand-alone webRTC client, implement the negotiation as in erizoClient and implement recording there (possibly by reusing our ExternalOutput code if you manage to get the encoded frames). That would require, IMO less work that replacing Erizo’s WebRTC stack and you could still use Licode as the MCU for room management, etc. In fact, I believe that there are similar projects out there.

Finally, I would like to ask you to send me an example of a corrupted video so I can see exactly the kind of corruption you are referring to.

Cheers! –  
Pedro Rodriguez

On 15 Sep 2014 at 22:11:46, Jeremy Noring ([jnoring@hirevue.com](mailto:jnoring@hirevue.com)) wrote:

I’ve been working on recording a lot in licode, and I’ve come to two conclusions:  
It doesn’t handle packet loss correctly; it should be sending a NACK on a lost packet on the RTCP back-channel.  
It doesn’t handle FEC correctly (there’s an entire packet type of 117 that it licode is droppoing on the floor).  
WebRTC itself seems to use a hybrid approach to deal with packet loss where they’ll use retransmits if the latency is low enough and FEC to provide stream-level redundancy. I know this approach must work well because I rarely (never?) see visible corruption in a WebRTC video stream, even with significant packet loss and latency in the local network connection. Unfortunately in my recorded content, corruption is fairly common and often pretty bad.

To solve this…I’m thinking the best approach may be to actually use libjingle-peerconnection in licode to handle RTP packet reordering on the video stream. This would involve sucking down the entire WebRTC project, building it, linking it against licode, stripping out the RTP packet queue I recently re-wrote, etc. It’s a ton of work. But I think it’d still be dramatically less work than re-writing the RTP/RTCP/NACK/FEC code in WebRTC, which is part of a half-dozen RFCs that definitely not trivial to implement. So I wanted to get the opinion of others here on this approach and see if there’s any alternate proposals?

I really, really need video recording that is largely free of corruption. So I have to do something. Any advice is hugely appreciated.

## -Jeremy

You received this message because you are subscribed to the Google Groups “lynckia” group.  
To unsubscribe from this group and stop receiving emails from it, send an email to [lynckia+unsubscribe@googlegroups.com](mailto:lynckia+unsubscribe@googlegroups.com).  
For more options, visit [https://groups.google.com/d/optout](https://groups.google.com/d/optout).

---

<div class="post-metadata">

**Author:** ![Jeremy\_Noring](https://avatars.discourse-cdn.com/v4/letter/j/977dab/32.png) [@Jeremy\_Noring](https://discourse.lynckia.com/u/Jeremy_Noring)\
**Post date:** [October 4, 2014, 2:08pm UTC](https://discourse.lynckia.com/t/recording-proposal-still-having-corruption-issues-in-recorded-content/281/2 "2014-10-04T14:08:29Z")

</div>

I’ve started pulling code in to see if I can make this work. My first guy  
impression is it’s going to be very hard to granularly remove  
fec\_receiver\_impl.cc/fec\_receiver\_impl.h, because the sheer number of  
#includes they pull in is sort of mind-boggling. Still trying to see if  
there’s a granular approach I can adopt here. Advice welcome.On Tuesday, September 23, 2014 1:43:32 AM UTC-6, Pedro Rodriguez wrote:

> I’d swear I sent the response to the list but I cannot find it here now…
> 
> Short answer:  
> Yes, we need to implement FEC/redundancy support to improve recording  
> quality.  
> Generating RTCP from the MCU is a lower priority at this point, I find  
> more interesting improving the way we forward the RTCP RR/Feedback packets  
> from clients by adding more intelligence to OneToManyProcessor. That said,  
> generating RTCP RR from the MCU is quite simple at this point.
> 
> We are also working on an statistics monitor that will hopefully help  
> diagnose network problems.
> 
> We really don’t want to use full libjingle in Licode’s core for a variety  
> of reasons. Using isolated parts of the code, like we are doing with VP8  
> fragmenting and parsing is ok, though. Another route is to create a  
> stand-alone erizo client for recording using libjingle.

---

<div class="post-metadata">

**Author:** ![Yannick\_Modah\_Gouez](https://avatars.discourse-cdn.com/v4/letter/y/c6cbf5/32.png) [@Yannick\_Modah\_Gouez](https://discourse.lynckia.com/u/Yannick_Modah_Gouez)\
**Post date:** [September 22, 2014, 12:49pm UTC](https://discourse.lynckia.com/t/recording-proposal-still-having-corruption-issues-in-recorded-content/281/3 "2014-09-22T12:49:43Z")

</div>

To have libjingle included in Licode would definitly make sense. I also  
need to handle packet loss correctly for similar reasons ( I am forwarding  
the webRTC stream to an http streaming server ).

I don’t realize how much work this represents but I’d also love to hear the  
vision from Licode’s team and their plans on the recording functionnality.

---

<div class="post-metadata">

**Author:** ![Pedro\_Rodriguez](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.lynckia.com/pedro_rodriguez/32/23_2.png) [@Pedro\_Rodriguez](https://discourse.lynckia.com/u/Pedro_Rodriguez)\
**Post date:** [September 23, 2014, 7:43am UTC](https://discourse.lynckia.com/t/recording-proposal-still-having-corruption-issues-in-recorded-content/281/4 "2014-09-23T07:43:31Z")

</div>

I’d swear I sent the response to the list but I cannot find it here now…

Short answer:  
Yes, we need to implement FEC/redundancy support to improve recording  
quality.  
Generating RTCP from the MCU is a lower priority at this point, I find more  
interesting improving the way we forward the RTCP RR/Feedback packets from  
clients by adding more intelligence to OneToManyProcessor. That said,  
generating RTCP RR from the MCU is quite simple at this point.

We are also working on an statistics monitor that will hopefully help  
diagnose network problems.

We really don’t want to use full libjingle in Licode’s core for a variety  
of reasons. Using isolated parts of the code, like we are doing with VP8  
fragmenting and parsing is ok, though. Another route is to create a  
stand-alone erizo client for recording using libjingle.

Cheers!El lunes, 22 de septiembre de 2014 14:49:43 UTC+2, Yannick Modah Gouez escribió:

> To have libjingle included in Licode would definitly make sense. I also  
> need to handle packet loss correctly for similar reasons ( I am forwarding  
> the webRTC stream to an http streaming server ).
> 
> I don’t realize how much work this represents but I’d also love to hear  
> the vision from Licode’s team and their plans on the recording  
> functionnality.

---

<div class="post-metadata">

**Author:** ![Jeremy\_Noring](https://avatars.discourse-cdn.com/v4/letter/j/977dab/32.png) [@Jeremy\_Noring](https://discourse.lynckia.com/u/Jeremy_Noring)\
**Post date:** [September 15, 2014, 8:11pm UTC](https://discourse.lynckia.com/t/recording-proposal-still-having-corruption-issues-in-recorded-content/281/5 "2014-09-15T20:11:43Z")

</div>

I’ve been working on recording a lot in licode, and I’ve come to two  
conclusions:

1. It doesn’t handle packet loss correctly; it should be sending a NACK  
on a lost packet on the RTCP back-channel.
2. It doesn’t handle FEC correctly (there’s an entire packet type of 117  
that it licode is droppoing on the floor).

WebRTC itself seems to use a hybrid approach to deal with packet loss where  
they’ll use retransmits if the latency is low enough and FEC to provide  
stream-level redundancy. I know this approach must work well because I  
rarely (never?) see visible corruption in a WebRTC video stream, even with  
significant packet loss and latency in the local network connection.  
Unfortunately in my recorded content, corruption is fairly common and  
often pretty bad.

To solve this…I’m thinking the best approach may be to actually use  
libjingle-peerconnection in licode to handle RTP packet reordering on the  
video stream. This would involve sucking down the entire WebRTC project,  
building it, linking it against licode, stripping out the RTP packet queue  
I recently re-wrote, etc. It’s a ton of work. But I think it’d still be  
dramatically less work than re-writing the RTP/RTCP/NACK/FEC code in  
WebRTC, which is part of a half-dozen RFCs that definitely not trivial to  
implement. So I wanted to get the opinion of others here on this approach  
and see if there’s any alternate proposals?

I really, really need video recording that is largely free of corruption.  
So I have to do something. Any advice is hugely appreciated.

-Jeremy

---

<div class="post-metadata">

**Author:** ![Jeremy\_Noring](https://avatars.discourse-cdn.com/v4/letter/j/977dab/32.png) [@Jeremy\_Noring](https://discourse.lynckia.com/u/Jeremy_Noring)\
**Post date:** [September 18, 2014, 7:53pm UTC](https://discourse.lynckia.com/t/recording-proposal-still-having-corruption-issues-in-recorded-content/281/6 "2014-09-18T19:53:27Z")

</div>

Hi Pedro,

Thanks so much for the response!

> I understand your concerns regarding the actual state of recording, as it  
> is, Licode does not implements the mechanisms you mention to manage packet  
> loss. This is due to lack of development effort but also there are some  
> design decisions involved.
> 
> 1. It doesn’t handle packet loss correctly; it should be sending a  
> NACK on a lost packet on the RTCP back-channel.
> 2. It doesn’t handle FEC correctly (there’s an entire packet type of  
> 117 that it licode is droppoing on the floor).
> 
> Licode allows recording, yes. But it is primarily designed to be used in a  
> videoconferencing scenario. We give a low priority to implementing FEC  
> handling and RTCP reporting because Chrome clients (subscribers), DO  
> implement this, and Licode makes sure this RTCP messages (NACK, REMB, etc.)  
> ARE forwarded (in a quite brute way at this point, we plan on improving  
> this).
> 
> Publisher ————(A)———\> Licode ———(B) ———\> subscriber.
> 
> For the communication, it is important to control packet loss both in A  
> and B. With our limited resources, we decided it was better to pass RTCP  
> packets from the subscriber instead of generating a new RTCP stream from  
> Licode.
> 
> This, of course, means that if there are no subscribers in the session, no  
> packet loss will be reported. That is the case of a record-only session.  
> Also, as you point out, we discard red data and fec packets WHEN recording,  
> we know that is quite far from optimal. Do you have other subscribers in  
> your recording session?

Yes, our typical scenario involves two to four parties in a room. All of  
the incoming streams are being recorded. Are you saying I should be seeing  
packets get retransmitted? In general, I’d describe the video recording  
quality as “adequate?” Definitely during any sort of packet loss and/or  
latency situation, I see pretty frequent breakup in recorded streams. It’s  
particularly bad if a keyframe is corrupted (which makes sense, since  
subsequent packets rely on it–also more likely to lose a packet for a  
keyframe)

On how to proceed: As I mentioned, we want to add more intelligence to

> Licode regarding RTCP. I would definitely improve ExternalOutput and the  
> (now almost totally yours) RtpQueue so they can report packets loss, use  
> redundancy packets and so on.

I think that’d be a good approach. Also, technically to do recording  
right, I need the RTCP channel there so I can do proper timestamping.  
Right now, I’m sort of winging it. The RTCP channel is needed to relate  
timestamps in audio/video streams.

I know it’s an open source project, but do you have any idea when someone  
would work on this? I’d be happy to help in any way, since this is an  
issue I have to find some way to fix.

> However, there is another option. You can use Google’s webRTC library for  
> recording without altering Licode, you can create a stand-alone webRTC  
> client, implement the negotiation as in erizoClient and implement recording  
> there (possibly by reusing our ExternalOutput code if you manage to get the  
> encoded frames). That would require, IMO less work that replacing Erizo’s  
> WebRTC stack and you could still use Licode as the MCU for room management,  
> etc. In fact, I believe that there are similar projects out there.

I thought about this, but there’s a number of problems with the approach;  
the biggest is it’s no longer tightly integrated with the MCU, and that  
creates a headache when parties connect/disconnect/on room events/etc.

Finally, I would like to ask you to send me an example of a corrupted video

> so I can see exactly the kind of corruption you are referring to.

I’ll send you an email with the details of this.On Wednesday, September 17, 2014 8:14:16 AM UTC-6, Pedro Rodriguez wrote:

---

<div class="post-metadata">

**Author:** ![Rohit\_Aggarwal](https://avatars.discourse-cdn.com/v4/letter/r/b2d939/32.png) [@Rohit\_Aggarwal](https://discourse.lynckia.com/u/Rohit_Aggarwal)\
**Post date:** [April 5, 2018, 8:20pm UTC](https://discourse.lynckia.com/t/recording-proposal-still-having-corruption-issues-in-recorded-content/281/7 "2018-04-05T20:20:31Z")

</div>

@Pedro_Rodriguez it seems this issue still persists.

> [@Pedro\_Rodriguez](#):
>
> You can use Google’s webRTC library for recording without altering Licode, you can create a stand-alone webRTC client, implement the negotiation as in erizoClient and implement recording there (possibly by reusing our ExternalOutput code if you manage to get the encoded frames). That would require, IMO less work that replacing Erizo’s WebRTC stack and you could still use Licode as the MCU for room management, etc. In fact, I believe that there are similar projects out there.

Can you please recommend a project that readily does it? I will greatly appreciate any suggestion that you can offer.

Thank you,  
Rohit

---

<div class="post-metadata">

**Author:** ![Rohit\_Aggarwal](https://avatars.discourse-cdn.com/v4/letter/r/b2d939/32.png) [@Rohit\_Aggarwal](https://discourse.lynckia.com/u/Rohit_Aggarwal)\
**Post date:** [April 6, 2018, 8:17pm UTC](https://discourse.lynckia.com/t/recording-proposal-still-having-corruption-issues-in-recorded-content/281/8 "2018-04-06T20:17:20Z")

</div>

@Pedro_Rodriguez if Chrome takes care of packet loss, perhaps I can create a `subscriberOnServer`, who subscribes to the speaker on Licode server. We can then record client-side using subscriberOnServer, but since this client is on the server, we will have the recording on the server.

How does it sound to you? I can try something like this to run client/subscriber on server: [https://github.com/relekang/docker-webrtc-test](https://github.com/relekang/docker-webrtc-test)

If it sounds ok to you, then I need to figure out how to record video from the client/subscriber in Licode room. I will greatly appreciate your suggestions on this.

---

<div class="post-metadata">

**Author:** ![pedro](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.lynckia.com/pedro/32/24_2.png) [@pedro](https://discourse.lynckia.com/u/pedro)\
**Post date:** [April 18, 2018, 1:22pm UTC](https://discourse.lynckia.com/t/recording-proposal-still-having-corruption-issues-in-recorded-content/281/9 "2018-04-18T13:22:07Z")

</div>

This is a very outdated thread. Licode now has is able to report packet loss and `ExternalOutput` should reorder packets accordingly. We’ve come a long way since we discussed this here.  
You can certainly use a browser somewhere else to record the whole screen. I haven’t personally tried to record individual streams in Licode that way but, since you have access to the underlying peerConnection and streams, you should be able to do it.

---

<div class="post-metadata">

**Author:** ![Rohit\_Aggarwal](https://avatars.discourse-cdn.com/v4/letter/r/b2d939/32.png) [@Rohit\_Aggarwal](https://discourse.lynckia.com/u/Rohit_Aggarwal)\
**Post date:** [April 18, 2018, 7:05pm UTC](https://discourse.lynckia.com/t/recording-proposal-still-having-corruption-issues-in-recorded-content/281/10 "2018-04-18T19:05:59Z")

</div>

@pedro So would you have any idea why recording still gets corrupted? And typically this corruption happens only in the starting 30 to 110 secs and then the rest of the recording is fine. I must note that subscriber sees speaker’s video good all the time, even when recording gets corrupted at the start.

1. Could this be that subscriber’s bandwidth is affecting publisher’s recording? We use this setting to publish speaker’s room.  
`room.publish(localStream, { minVideoBW: 1000, scheme: "notify-break-recover" });`

2. Would providing only audio to a subscriber and no video to subscriber prevent any recording degradation of speaker’s video?

Any suggestion on how to prevent recording corruption will be highly appreciated.
