For H264 encoder always from my external implementation of WebRtcVideoEncoderFactory

890 views
Skip to first unread message

soft.deve...@gmail.com

unread,
Dec 11, 2017, 8:31:16 AM12/11/17
to discuss-webrtc
Hi, 
My c++ aplication is providing Webrtc CreatePeerConnectionFactory with my own video encoder factory, the thing is that sometimes WebRTC decides to uses it´s own internal H264 encoder and I dont know how to control that.

This are de codec my library si reporting to webrtc:

  cricket::VideoCodec codec(cricket::kH264CodecName);
  codec
.SetParam(cricket::kH264FmtpPacketizationMode, "1");
  codec
.SetParam(kH264FmtpProfileLevelId, kH264ProfileLevelConstrainedBaseline);
  codec
.SetParam(kH264FmtpLevelAsymmetryAllowed, "1");
  _codecs
.push_back(std::move(codec));

My offer does generate this lines:

a=rtpmap:100 H264/90000
a
=rtcp-fb:100 ccm fir
a
=rtcp-fb:100 nack
a
=rtcp-fb:100 nack pli
a
=rtcp-fb:100 goog-remb
a
=rtcp-fb:100 transport-cc
a
=fmtp:100 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=64001f;x-google-start-bitrate=3000;x-google-max-bitrate=8000;x-google-min-bitrate=2000
a
=rtpmap:101 rtx/90000
a
=fmtp:101 apt=100
a
=rtpmap:127 H264/90000
a
=rtcp-fb:127 ccm fir
a
=rtcp-fb:127 nack
a
=rtcp-fb:127 nack pli
a
=rtcp-fb:127 goog-remb
a
=rtcp-fb:127 transport-cc
a
=fmtp:127 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42e01f;x-google-start-bitrate=3000;x-google-max-bitrate=8000;x-google-min-bitrate=2000
a
=rtpmap:123 rtx/90000
a
=fmtp:123 apt=127
a
=rtpmap:125 H264/90000
a
=rtcp-fb:125 ccm fir
a
=rtcp-fb:125 nack
a
=rtcp-fb:125 nack pli
a
=rtcp-fb:125 goog-remb
a
=rtcp-fb:125 transport-cc
a
=fmtp:125 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42001f;x-google-start-bitrate=3000;x-google-max-bitrate=8000;x-google-min-bitrate=2000

The problem is that i don´t know when it does decide to use payload 100, 127 or 125 and i don´t know how to "tie" them to my video encoder factory just to avoid any usage of the internally compiled webrtc library. Sometimes it does call my H264 encoder and sometimes it does not.

Any suggestion on how should I do this?

Thank you very much in advance.

Alexandre GOUAILLARD

unread,
Dec 11, 2017, 9:07:51 AM12/11/17
to discuss...@googlegroups.com
well, first, the profile-level-id gives you indication:
64001f  => high profile 3.1
42001f  => base profile 3.1
42e01f  => Constrained base profile 3.1

given the way you initialise your codec, you can only be 42e01f (value of the kH264ProfileLevelConstrainedBaseline you are setting).

now depending on what you get on the other side, multiple things can happen. Chrome selection is unknown, but if you filter the sdp to only keep the codec whose name is "H264/90000" and whose corresponding profile-level-id is "42e01f", there is high chance that you end up using yours.

if not that means several codecs where registered with the same parameters, and you will have to dig into the C++ code to investigate further how the mapping and the selection, is done.


--

---
You received this message because you are subscribed to the Google Groups "discuss-webrtc" group.
To unsubscribe from this group and stop receiving emails from it, send an email to discuss-webrtc+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/discuss-webrtc/26e9ecba-9d8b-4200-9e5f-5b885853c355%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.



--
Alex. Gouaillard, PhD, PhD, MBA
------------------------------------------------------------------------------------
President - CoSMo Software Consulting, Singapore
------------------------------------------------------------------------------------

soft.deve...@gmail.com

unread,
Dec 11, 2017, 10:35:45 AM12/11/17
to discuss-webrtc
Thank you so much for the quick reply.

Oh, I see, so the way is filtering in the  SDP the codecs that are not published becouse of my factory. Is there any function or interface in WebRTC I can use to interprete the binary bytes for this profile-level-id into Baseline Main or High profiles and the level os should i make my own? The encoder I am using does support almost any profile and level, is this 3.1 level a constraint inside WebRTC library? 

Best reagrds,
To unsubscribe from this group and stop receiving emails from it, send an email to discuss-webrt...@googlegroups.com.

Alexandre GOUAILLARD

unread,
Dec 11, 2017, 10:43:56 AM12/11/17
to discuss...@googlegroups.com
Oh, I see, so the way is filtering in the  SDP the codecs that are not published becouse of my factory.

[alex] i don t know if it is the way, but it s one way, and it s easy t o implement in JS, by filtering out the H264 codecs which do not have the right profile-level-id. 

Is there any function or interface in WebRTC I can use to interprete the binary bytes for this profile-level-id into Baseline Main or High profiles and the level os should i make my own?

[alex] there is no such api, but i just gave you the mapping in the previous email. you should not get any different than the 3 values i listed (as of today's chrome). Just process the sdp.

 The encoder I am using does support almost any profile and level, is this 3.1 level a constraint inside WebRTC library?

[alex] I don t know what you are setting your encoder/ decoder implementation to, but you are registering the codec to the webrtc media engine with the value 3.1 in your code (hardcoded value of the kH264ProfileLevelConstrainedBaseline you are setting). That works for both encoder and decoder, and that is what you are negotiating during the offer/answer with the remote peers, so you'd better be sure you are setting the same thing inside your implementation. I would not be surprised if anything different from what chrome supports today would NOT be recognised/used by chrome. 

To unsubscribe from this group and stop receiving emails from it, send an email to discuss-webrtc+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/discuss-webrtc/38bf954a-7e8e-44ff-952f-dfd562477808%40googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

soft.deve...@gmail.com

unread,
Dec 11, 2017, 11:00:17 AM12/11/17
to discuss-webrtc
Thank you very much, your advises are so helpfull.
I am just working almost evrything in C++ so I want to control all that from the Offer that my "server" sends to any webbrowser, I think I can cap my offer properly now :)

soft.deve...@gmail.com

unread,
Dec 12, 2017, 1:38:49 PM12/12/17
to discuss-webrtc
Adding some code that might be usefull to anyone wanting to parse profile-level-id, it has been usefull to me :D


#pragma pack(push, NALU, 1)

     
enum H264Profile
     
{
       
Baseline = (uint8_t)66, //BP
       
Extended = (uint8_t)88, //XP
       
Main = (uint8_t)77,//MP
       
High = (uint8_t)100,//HiP
     
};

     
// The bit fields follow Little Endian layout
     
struct ProfileHeader
     
{
        uint8_t  profile_idc
: 8; //H264Profile
        uint8_t  flags_and_reserved
: 8;
        uint8_t  level_idc
: 8;
     
};
#pragma pack(pop, NALU)

bool parse_profile(const uint8_t * buffer, ProfileHeader& out)
{
  memcpy
(&out, buffer, sizeof(out));
 
return true;
}

//Insert here the profile-level-id from SDP
bool parse_profile(const char* str, ProfileHeader& out)
{
 
bool ret = false;
  std
::string hex = str;
 
if (hex.size() > 1)
 
{
    uint8_t
* hexBuff = new uint8_t[hex.size()/2];
    size_t hi
= 0;
   
for (size_t i = 0; i < hex.length(); i += 2)
   
{
      std
::string byteStr = hex.substr(i, 2);
      hexBuff
[hi] = strtol(byteStr.c_str(), NULL, 16);
      hi
++;
   
}
    ret
= parse_profile(hexBuff,out);
 
}
 
return ret;
}

soft.deve...@gmail.com

unread,
Dec 12, 2017, 1:44:56 PM12/12/17
to discuss-webrtc
Forgot to call delete[] hexBuff; !!!!

Ivan Mayo

unread,
Feb 23, 2018, 5:34:53 AM2/23/18
to discuss...@googlegroups.com
Hi,
I am facing this problem again:
My web client sends this SDP lines in the Offer:

.....
a=rtpmap:100 H264/90000
a=rtcp-fb:100 goog-remb
a=rtcp-fb:100 transport-cc
a=rtcp-fb:100 ccm fir
a=rtcp-fb:100 nack
a=rtcp-fb:100 nack pli
a=fmtp:100 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42001f
a=rtpmap:101 rtx/90000
a=fmtp:101 apt=100
a=rtpmap:102 H264/90000
a=rtcp-fb:102 goog-remb
a=rtcp-fb:102 transport-cc
a=rtcp-fb:102 ccm fir
a=rtcp-fb:102 nack
a=rtcp-fb:102 nack pli
a=fmtp:102 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42e01f
.....

My C++ Server send this lines in the SDP answer ():

.....
a=rtpmap:102 H264/90000
a=rtcp-fb:102 goog-remb
a=rtcp-fb:102 transport-cc
a=rtcp-fb:102 ccm fir
a=rtcp-fb:102 nack
a=rtcp-fb:102 nack pli
a=fmtp:102 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42e01f;x-google-start-bitrate=4000;x-google-max-bitrate=8000;x-google-min-bitrate=3000
.....

My Video Encoder Factory is reporting this codecs:

#define CONSTRAINED_BASELINE_3_1 "42e01f"
#define BASELINE_3_1 "42001f"

  //Add CONSTRAINED_BASELINE_3_1
  cricket::VideoCodec codec(cricket::kH264CodecName);
  codec.SetParam(kH264FmtpPacketizationMode, "1");//IM: Does not work, default is previously set at WebRTC library and it will pasarselo por el forro
  codec.SetParam(kH264FmtpProfileLevelId, CONSTRAINED_BASELINE_3_1);
  codec.SetParam(kH264FmtpLevelAsymmetryAllowed, "1");
  _codecs.push_back(std::move(codec));

  //Add BASELINE_3_1
  codec.SetParam(kH264FmtpPacketizationMode, "1");//IM: Does not work, default is previously set at WebRTC library and it will pasarselo por el forro
  codec.SetParam(kH264FmtpProfileLevelId, BASELINE_3_1);
  codec.SetParam(kH264FmtpLevelAsymmetryAllowed, "1");
  _codecs.push_back(std::move(codec));


The result is my codec never being created, webrtc decides just to use its internal h.264 codec implementation.
If the profile level id is matching, what is making webrtc to not use my encoder?? Still not able to force it using my own encoder :(

Best regards,

--

---
You received this message because you are subscribed to a topic in the Google Groups "discuss-webrtc" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/discuss-webrtc/c65RKaqr6yk/unsubscribe.
To unsubscribe from this group and all its topics, send an email to discuss-webrtc+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/discuss-webrtc/36d94820-3242-42c4-809a-60defd6c101a%40googlegroups.com.

Andrei Kozlov

unread,
Aug 29, 2018, 9:45:00 AM8/29/18
to discuss-webrtc

Hi Ivan.

Did you finally make it work? I have the same issue, webrtc obstinately uses its own encoder instead of mine.
To unsubscribe from this group and all its topics, send an email to discuss-webrt...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages