-
Notifications
You must be signed in to change notification settings - Fork 105
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
Implement SDL 0048 RTP Video Encoder #703
Implement SDL 0048 RTP Video Encoder #703
Conversation
This packetizer sends H.264 video stream using RTP frames defined by RFC 6184 and RFC 4571.
Also, latest PTS value is kept in SDLStreamingMediaLifecycleManager so that video image with outdated PTS will be rejected.
@joeljfischer Please kindly review. |
@shoamano83 Because this adds a method to |
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.
Hi @shoamano83, mostly asking for small changes. One big current question is that this appears to be adding code for RTP, but it's not currently enabled. I'm assuming that it won't be until the control payload / video capabilities PR for 5.0?
I've tested against Ford's Sync 3 TDK and everything is still working there, so I just still need to test against your recommended GStreamer settings.
// SmartDeviceLink-iOS | ||
// | ||
// Created by Sho Amano on 4/11/17. | ||
// Copyright © 2017 Xevo Inc. All rights reserved. |
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.
Please change this to how other files do, you can either remove the copyright entirely or alter it to say "Copyright © 2017 SmartDeviceLink Consortium, Inc."
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.
Hi @joeljfischer, I’m aware of the copyright headers in other files, but it is a request from our legal department to add our company name in the copyright header for newly created and updated files. I hope this is OK for you.
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.
👍
SmartDeviceLink/SDLH264Packetizer.h
Outdated
|
||
#import <Foundation/Foundation.h> | ||
|
||
@protocol SDLH264Packetizer |
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.
All protocols, extensions, and classes need to be wrapped in NS_ASSUME_NONNULL_BEGIN
and NS_ASSUME_NONNULL_END
and nullable
tags when the developer is allowed to pass nil
.
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.
Thanks, fixed by afecd28.
SmartDeviceLink/SDLH264Packetizer.h
Outdated
* All NAL units that belongs to a frame should be included in | ||
* nalUnits array. | ||
*/ | ||
- (NSArray *)createPackets:(NSArray *)nalUnits pts:(double)pts; |
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.
All container classes need generics to specify what is to be passed in or out.
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 would prefer to see the pts:pts
part expanded out of the acronym to presentationTimestamp:(double)presentationTimestamp
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.
Fixed by 107382f.
SmartDeviceLink/SDLH264Packetizer.h
Outdated
* | ||
* @return List of NSData. Each NSData holds a packet. | ||
* | ||
* @note This method cannot be called more than once with same pts value. |
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.
This should probably be @warning
instead of @note
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.
Updated by 107382f.
* | ||
* @note This must be between 0 and 127. Default value is 96. | ||
*/ | ||
@property (assign, nonatomic) UInt8 payloadType; |
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 there a link or reference to explain what this means?
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 put some documentation with commit d585057. Hope this will make clearer.
const UInt8 DEFAULT_PAYLOAD_TYPE = 96; | ||
const NSUInteger FU_INDICATOR_LEN = 1; | ||
const NSUInteger FU_HEADER_LEN = 1; | ||
const UInt8 TYPE_FU_A = 0x1C; |
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.
Unsure what "FU" or "A" are.
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.
"A" seems to be just a name of a version (there are "FU-A" and "FU-B" in the RFC). I've updated the constant's name in d585057, hope this is OK.
* | ||
* @return Whether or not the data was successfully encoded and sent. | ||
*/ | ||
- (BOOL)sendVideoData:(CVImageBufferRef)imageBuffer pts:(CMTime)pts; |
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 would prefer to see the pts:pts part expanded out of the acronym to presentationTimestamp:(CMTime)presentationTimestamp
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.
Sure, updated with 33b5d07.
@@ -517,8 +538,14 @@ - (void)sdl_sendBackgroundFrames { | |||
return; | |||
} | |||
|
|||
const CMTime interval = CMTimeMake(1, 30); |
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 still okay even if they're not doing 30fps?
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 think it should work, since the delta of timestamp doesn’t need to be constant all the time.
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 just want to make doubly sure, because devs could try to send fps anywhere from half to double this number that this is going to work for them.
* | ||
* @return Whether or not the data was successfully encoded and sent. | ||
*/ | ||
- (BOOL)sendVideoData:(CVImageBufferRef)imageBuffer pts:(CMTime)pts; |
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 would prefer to see the pts:pts part expanded out of the acronym to presentationTimestamp:(CMTime)presentationTimestamp
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.
Updated with 33b5d07.
SmartDeviceLink/SDLVideoEncoder.m
Outdated
|
||
- (BOOL)encodeFrame:(CVImageBufferRef)imageBuffer pts:(CMTime)pts { | ||
if (!CMTIME_IS_VALID(pts)) { | ||
pts = CMTimeMake(self.currentFrameNumber, 30); |
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.
Will this still work even if they're not using 30fps? Shouldn't we be pulling this from the videoEncoderSettings
?
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.
Actually this is from current implementation, I kept it as it is. (Please refer to: https://github.com/smartdevicelink/sdl_ios/blob/release/5.0.0/SmartDeviceLink/SDLVideoEncoder.m#L122)
My thought is that app should provide timestamp along with video frames, especially when RTP format is used.
If it cannot provide, then SDL Proxy may create timestamps by capturing current time when -sendVideoData:
is called. I was hesitated to add this implementation because it may change behavior even when we use byte-stream format.
I’m aware of kVTCompressionPropertyKey_ExpectedFrameRate
key in the configuration. But I thought we cannot guarantee that all navi apps add it in the configuration dictionary.
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.
Can you add this as an issue? I agree with keeping it as is for 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.
OK, I created issue #717.
Reflecting code review comments.
- Update "note" comment to "warning" - Add generics to NSArray containers - rename "pts" arg to "presentationTimestamp" - remove redundant method declarations - remove redundant protocol conformations
Reflecting review comments.
Hi @joeljfischer, thank you for your detailed review.
That’s right, it is not enabled yet, and it should be enabled when the format is chosen through Constructed Payload + Video Capabilities mechanism. |
- Add documentations in private functions - Rename private functions and args - Rename “pts” acronym - Remove “FU” acronym in comments
- Update initializer style - Add brackets between a boolean expression - Use dot syntax - Remove an extra line
Reflecting code review comment.
Reflecting code review comment.
Reflecting review comments.
Reflecting review comments.
Hi @shoamano83, I've tried to test the RTP streaming by changing SDLVideoEncoder.m L113 to instantiate an We tested against a develop version of Core running on Ubuntu 16.04 with gStreamer v1.8.2. |
Hi @joeljfischer, I've never tried pipe transport in my environment. Let me check and get back to you. |
I verified that socket as well as pipe works on my environment. Actually it's quite tricky to test with sdl_hmi and GStreamer. Here is details of what I do. Environment:Ubuntu 16.04 (amd64) on VirtualBox Mobile: iPhone 5s (iOS 8.4.1) Modifcation to sdl_hmi:
Modification to iOS proxy:Change:
to:
Modification to SDL Core:Open log4cxx.properties and change this line:
to:
This prevents SDL Core from generating a huge amount of logs during streaming. In my environment they often exhaust RAM and Linux will stop working. Steps:
I noticed that on my Ubuntu 16.04 For pipe streamer, update smartDeviceLink.ini and also update the gstreamer pipeline as you tried:
Note, the whole sequence sometimes fails (possibly because of timing issue between HMI and GStreamer?) so I try it several times. |
JFYI, attaching a video of the whole sequence. |
autovideosink doesn't work in some environments, replacing it with ximagesink.
Fixes #619
This PR is ready for review.
Risk
This PR makes minor API changes.
This PR adds new public methods in
SDLStreamingMediaManager
,SDLStreamingMediaLifecycleManager
andSDLVideoEncoder
. Also, it updates the default flow of video streaming insdl_videoEncoderOutputCallback()
.I carefully implemented the changes not to break compatibility and I believe the risk is low, but I hope them to be double checked.
Testing Plan
Unit test cases are added for newly added classes.
Summary
Implements SDL 0048
This PR adds RTP packetizer implementation which is necessary for SDL-0048.
It also adds following changes which are necessary for the RTP format to work:
SDLVideoEncoder
is split into two parts. One is to extract NAL units from sample buffer, and the other is to add start codes in front of every NAL unit (which is inSDLH264ByteStreamPacketizer
class)-sendVideoData:pts:
is added so that SDL app can provide PTS (presentation timestamp) along with the video frameChangelog
Breaking Changes
Enhancements
SDLVideoEncoder
to extract list of NAL units from encoded dataSDLH264ByteStreamPacketizer
to append start codes in front of the NAL unitsSDLRTPH264Packetizer
to create RTP packets from the NAL units-sendVideoData:pts:
Bug Fixes
Tasks Remaining:
CLA