-
Notifications
You must be signed in to change notification settings - Fork 2
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
OCP-6005 rtph266pay: Add config-interval and AP #42
base: rtph266depay
Are you sure you want to change the base?
Conversation
4be0a88
to
27d4f51
Compare
22320a2
to
fc9cf86
Compare
27d4f51
to
3919204
Compare
fc9cf86
to
4e2fde9
Compare
a5bb6e8
to
1bcc68c
Compare
When using |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will review tomorrow AP implementation.
@@ -205,12 +266,36 @@ static void | |||
_set_property (GObject * object, guint prop_id, | |||
const GValue * value, GParamSpec * pspec) | |||
{ | |||
GstRtpH266Pay *rtph266pay = GST_RTP_H266_PAY (object); | |||
|
|||
GST_OBJECT_LOCK (rtph266pay); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wouldn't protect with GST_OBJECT_LOCK/UNLOCK the default case: G_OBJECT_WARN_INVALID_PROPERTY_ID.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you think it could lead to some kind of error or wrong behavior? I agree it isn't necessary, but if it's just because of that, I'd rather keep it as is. The code is simpler this way.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, just no need to warn inside a protected section.
for (GList * l = head; l != NULL; l = l->next) { | ||
Nalu *current_nalu = l->data; | ||
|
||
if (!_can_insert_xps (rtph266pay, current_nalu)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about renaming to something like _nalus_insert_xps_nalu
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🤔 I'd like to keep the can
verb, as this method is not inserting, but checking if the insertion is possible. I don't mind adding the nalu
particle. What do you think about _can_insert_xps_nalu()
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I had a typo: _nalus_can_insert_ps
. Just a preference. Nitpick.
@@ -323,6 +413,9 @@ _sink_event (GstRTPBasePayload * rtpbasepay, GstEvent * event) | |||
GST_DEBUG_OBJECT (rtph266pay, "EOS: Draining"); | |||
ret = _push_pending_data (rtph266pay, TRUE); | |||
break; | |||
case GST_EVENT_STREAM_START: | |||
_clear_xps_cache (rtph266pay); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do you decide to clera the xps cache here and not in GST_EVENT_FLUSH_STOP?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure 😕 I was imitating what rtph265pay
does:
case GST_EVENT_STREAM_START:
GST_DEBUG_OBJECT (rtph265pay,
"New stream detected => Clear VPS, SPS and PPS");
gst_rtp_h265_pay_clear_vps_sps_pps (rtph265pay);
break;
const AggregatedNalus *aggregated_nalus = &rtph266pay->aggregated_nalus; | ||
guint mtu = GST_RTP_BASE_PAYLOAD_MTU (rtph266pay); | ||
guint num_nalus = g_queue_get_length ((GQueue *) & aggregated_nalus->nalus); | ||
gsize nalu_size_sum = aggregated_nalus->nalu_size_sum; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove nalu_size_sum
definition. We can directly use aggregated_nalus->nalu_size_sum
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like the way it is. It makes this statement fit in onetwo line and makes it easier to read:
guint payload_size =
NALU_HDR_LEN + nalu_size_field_sum + nalu_size_sum + nalu->size;
} | ||
} | ||
|
||
if (_aggregated_nalus_have_au (aggregated_nalus)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this part even reachable? There was a condition above if (!_aggregated_nalus_is_empty (aggregated_nalus)) {
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, it is. Let's say a complete AU comes in and fits into an AP. What will happen is:
- The for-each-nalu loop will aggregate all nalus into the AP:
_aggregated_nalus_add(); -> continue;
. TheCan't aggregate anymore
part of the loop won't be executed. - Finally, if we have aggregated a complete AU, we push it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems this loop is not easy to understand 😞 Do you think it'd be good to add a commentary summarizing what it does?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, add a comment. I don't understand yet, though.
So, if an AU is ensured to be completed after this while loop terminates, what is pushed here?
// vvv Can't aggregate anymore vvv
if (!_aggregated_nalus_is_empty (aggregated_nalus)) {
g_queue_push_head (nalus, nalu); // Keep this one for later
ret = _push_aggregated (rtph266pay); // Push what we have right now
if (ret != GST_FLOW_OK)
return ret;
An AP containing an incomplete AU? Can you explain in what case this piece of code called?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've added even more commentaries and reworded some of them. Let me know what you think, please.
So, if an AU is ensured to be completed after this while loop terminates, what is pushed here?
No, an AU is not ensured to be complete at this point. At this point, we just know we've tried to aggregate this NALU, be we couldn't. In this situation we might have to do one of these two things:
- If we already have something aggregated, send it. We'll deal later with the current NALU that couldn't fit inside this AP.
- If we have nothing aggregated, then it means the current NALU can't be aggregated and it has be processed by other means (ie: FU or UP)
// vvv Can't aggregate anymore vvv | ||
if (!_aggregated_nalus_is_empty (aggregated_nalus)) { | ||
g_queue_push_head (nalus, nalu); // Keep this one for later | ||
ret = _push_aggregated (rtph266pay); // Push what we have right now |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not check here with _aggregated_nalus_have_au?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It doesn't matter whether we have a complete AU or not; as we can no longer aggregate, we need to push the AP we have right now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's say an AU has Nalu1, Nalu2... Nalu100. Can an AP have Nalu1..50 and the next AP have Nalu51... Nalu100?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes! Exactly! An AP can have less than one AU, but it can not have more than one AU.
An AP aggregates NAL units of one access unit, and it MUST NOT contain NAL units from more than one AU.
OCP-5966 rtph266pay
Keep a cache of all Parameter Sets received, then, send them when it's appropriated according with the `config-interval` parameter. Issue: OCP_6005
Add support for two types of aggregation: * zero-latency: Only aggregate Parameter Set NALUs * max: Try to aggregate entires NALUs Issue: OCP_6005
UNKOWN -> UNKNOWN Issue: OCP_6005
Remove X from XPS. Now it's only Package Set. Issue: OCP_6005
Explain the more complex part of the algorithm, as it was proveen to be hard to understand. Issue: OCP_6005
Add missing Nalu fields to these parameters. Issue: OCP_6005
1bcc68c
to
85c171a
Compare
continuation of #37