Skip to content

Commit e419e52

Browse files
Merge pull request #1214 from smartdevicelink/hotfix/issue_1110
Fix issue with video streaming stability
2 parents ffe2f08 + 98d80bb commit e419e52

5 files changed

Lines changed: 101 additions & 34 deletions

File tree

android/sdl_android/src/main/java/com/smartdevicelink/managers/SdlManager.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -737,13 +737,18 @@ public void removeServiceListener(SessionType serviceType, ISdlServiceListener s
737737
@Override
738738
public void startVideoService(VideoStreamingParameters parameters, boolean encrypted) {
739739
if(proxy.getIsConnected()){
740-
proxy.startVideoStream(encrypted,parameters);
740+
proxy.startVideoService(encrypted,parameters);
741741
}
742742
}
743743

744744
@Override
745745
public IVideoStreamListener startVideoStream(boolean isEncrypted, VideoStreamingParameters parameters){
746-
return proxy.startVideoStream(isEncrypted, parameters);
746+
if(proxy.getIsConnected()){
747+
return proxy.startVideoStream(isEncrypted, parameters);
748+
}else{
749+
DebugTool.logError("Unable to start video stream, proxy not connected");
750+
return null;
751+
}
747752
}
748753

749754
@Override

android/sdl_android/src/main/java/com/smartdevicelink/managers/video/VideoStreamManager.java

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@
6969
import com.smartdevicelink.streaming.video.SdlRemoteDisplay;
7070
import com.smartdevicelink.streaming.video.VideoStreamingParameters;
7171
import com.smartdevicelink.transport.utl.TransportRecord;
72+
import com.smartdevicelink.util.DebugTool;
7273
import com.smartdevicelink.util.Version;
7374

7475
import java.lang.ref.WeakReference;
@@ -101,12 +102,13 @@ public class VideoStreamManager extends BaseVideoStreamManager {
101102
@Override
102103
public void onServiceStarted(SdlSession session, SessionType type, boolean isEncrypted) {
103104
if(SessionType.NAV.equals(type)){
104-
if(session != null && session.getAcceptedVideoParams() != null){
105+
if (session != null && session.getAcceptedVideoParams() != null) {
105106
parameters = session.getAcceptedVideoParams();
107+
VideoStreamManager.this.streamListener = session.startVideoStream();
106108
}
107-
VideoStreamManager.this.streamListener = internalInterface.startVideoStream(isEncrypted, parameters);
108-
if(streamListener == null){
109-
Log.e(TAG, "Error starting video service");
109+
110+
if (VideoStreamManager.this.streamListener == null) {
111+
Log.e(TAG, "Error starting video stream");
110112
stateMachine.transitionToState(StreamingStateMachine.ERROR);
111113
return;
112114
}
@@ -132,6 +134,7 @@ public void onServiceEnded(SdlSession session, SessionType type) {
132134

133135
@Override
134136
public void onServiceError(SdlSession session, SessionType type, String reason) {
137+
DebugTool.logError("Unable to start video service: " + reason);
135138
stateMachine.transitionToState(StreamingStateMachine.ERROR);
136139
transitionToState(BaseSubManager.ERROR);
137140
}
@@ -302,7 +305,6 @@ protected void startStreaming(VideoStreamingParameters parameters, boolean encry
302305
//Start the video service
303306
this.internalInterface.startVideoService(parameters, encrypted);
304307

305-
306308
}
307309

308310
/**
@@ -477,10 +479,14 @@ public void run() {
477479
}
478480
} ));
479481
Thread showPresentation = new Thread(fTask);
482+
showPresentation.setName("RmtDispThread");
480483

481484
showPresentation.start();
482485
} catch (Exception ex) {
483486
Log.e(TAG, "Unable to create Virtual Display.");
487+
if(DebugTool.isDebugEnabled()){
488+
ex.printStackTrace();
489+
}
484490
}
485491
}
486492

android/sdl_android/src/main/java/com/smartdevicelink/proxy/SdlProxyBase.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5339,6 +5339,27 @@ public IVideoStreamListener startVideoStream(boolean isEncrypted, VideoStreaming
53395339
}
53405340
}
53415341

5342+
/**
5343+
* This method will try to start the video service with the requested parameters.
5344+
* When it returns it will attempt to store the accepted parameters if available.
5345+
* @param isEncrypted if the service should be encrypted
5346+
* @param parameters the desiered video streaming parameters
5347+
*/
5348+
public void startVideoService(boolean isEncrypted, VideoStreamingParameters parameters) {
5349+
if (sdlSession == null) {
5350+
DebugTool.logWarning("SdlSession is not created yet.");
5351+
return;
5352+
}
5353+
if (!sdlSession.getIsConnected()) {
5354+
DebugTool.logWarning("Connection is not available.");
5355+
return;
5356+
}
5357+
5358+
sdlSession.setDesiredVideoParams(parameters);
5359+
5360+
tryStartVideoStream(isEncrypted, parameters);
5361+
}
5362+
53425363
/**
53435364
*Closes the opened video service (serviceType 11)
53445365
*@return true if the video service is closed successfully, return false otherwise

android/sdl_android/src/main/java/com/smartdevicelink/streaming/StreamPacketizer.java

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
import com.smartdevicelink.protocol.enums.SessionType;
3939
import com.smartdevicelink.proxy.interfaces.IAudioStreamListener;
4040
import com.smartdevicelink.proxy.interfaces.IVideoStreamListener;
41+
import com.smartdevicelink.util.DebugTool;
4142

4243
import java.io.IOException;
4344
import java.io.InputStream;
@@ -79,6 +80,7 @@ public StreamPacketizer(IStreamListener streamListener, InputStream is, SessionT
7980
if (bufferSize == 0) {
8081
// fail safe
8182
bufferSize = BUFF_READ_SIZE;
83+
buffer = new byte[bufferSize];
8284
}
8385
if(isServiceProtected){ //If our service is encrypted we can only use 1024 as the max buffer size.
8486
bufferSize = BUFF_READ_SIZE;
@@ -147,6 +149,9 @@ public void run() {
147149
frame = byteBufferWithListener.byteBuffer;
148150
completionListener = byteBufferWithListener.completionListener;
149151
} catch (InterruptedException e) {
152+
if(DebugTool.isDebugEnabled()){
153+
e.printStackTrace();
154+
}
150155
Thread.currentThread().interrupt();
151156
break;
152157
}
@@ -169,7 +174,7 @@ public void run() {
169174
frame.position(frame.position() + len);
170175
}
171176

172-
if (!frame.hasRemaining() && completionListener != null){
177+
if (completionListener != null){
173178
completionListener.onComplete(true);
174179
}
175180
}
@@ -187,8 +192,6 @@ public void run() {
187192
}else{
188193
_session.endService(_serviceType,_rpcSessionID);
189194
}
190-
191-
192195
}
193196
}
194197

@@ -297,8 +300,8 @@ private void sendByteBufferData(ByteBuffer data, CompletionListener completionLi
297300
}
298301

299302
private class ByteBufferWithListener{
300-
ByteBuffer byteBuffer;
301-
CompletionListener completionListener;
303+
final ByteBuffer byteBuffer;
304+
final CompletionListener completionListener;
302305
ByteBufferWithListener (ByteBuffer byteBuffer, CompletionListener completionListener){
303306
this.byteBuffer = byteBuffer;
304307
this.completionListener = completionListener;

base/src/main/java/com/smartdevicelink/protocol/SdlProtocolBase.java

Lines changed: 54 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1046,27 +1046,31 @@ protected void handleProtocolSessionStarted(SdlPacket packet, SessionType servic
10461046
}
10471047
}
10481048
} else {
1049-
TransportRecord transportRecord = packet.getTransportRecord();
1050-
if(transportRecord == null || (requiresHighBandwidth
1051-
&& TransportType.BLUETOOTH.equals(transportRecord.getType()))){
1052-
//transport can't support high bandwidth
1053-
onTransportNotAccepted((transportRecord != null ? transportRecord.getType().toString() : "Transport") + "can't support high bandwidth requirement, and secondary transport not supported in this protocol version");
1054-
return;
1055-
}
1056-
//If version < 5 and transport is acceptable we need to just add these
1057-
activeTransports.put(SessionType.RPC, transportRecord);
1058-
activeTransports.put(SessionType.BULK_DATA, transportRecord);
1059-
activeTransports.put(SessionType.CONTROL, transportRecord);
1060-
activeTransports.put(SessionType.NAV, transportRecord);
1061-
activeTransports.put(SessionType.PCM, transportRecord);
1062-
1063-
if (protocolVersion.getMajor() > 1){
1064-
if (packet.payload!= null && packet.dataSize == 4){ //hashid will be 4 bytes in length
1065-
hashID = BitConverter.intFromByteArray(packet.payload, 0);
1049+
if(serviceType.equals(SessionType.RPC)) {
1050+
TransportRecord transportRecord = packet.getTransportRecord();
1051+
if (transportRecord == null || (requiresHighBandwidth
1052+
&& TransportType.BLUETOOTH.equals(transportRecord.getType()))) {
1053+
//transport can't support high bandwidth
1054+
onTransportNotAccepted((transportRecord != null ? transportRecord.getType().toString() : "Transport ") + "can't support high bandwidth requirement, and secondary transport not supported in this protocol version");
1055+
return;
1056+
}
1057+
//If version < 5 and transport is acceptable we need to just add these
1058+
activeTransports.put(SessionType.RPC, transportRecord);
1059+
activeTransports.put(SessionType.BULK_DATA, transportRecord);
1060+
activeTransports.put(SessionType.CONTROL, transportRecord);
1061+
activeTransports.put(SessionType.NAV, transportRecord);
1062+
activeTransports.put(SessionType.PCM, transportRecord);
1063+
1064+
if (protocolVersion.getMajor() > 1) {
1065+
if (packet.payload != null && packet.dataSize == 4) { //hashid will be 4 bytes in length
1066+
hashID = BitConverter.intFromByteArray(packet.payload, 0);
1067+
}
10661068
}
1069+
}else if(serviceType.equals(SessionType.NAV)) {
1070+
//Protocol versions <5 don't support param negotiation
1071+
iSdlProtocol.setAcceptedVideoParams(iSdlProtocol.getDesiredVideoParams());
10671072
}
10681073
}
1069-
10701074
iSdlProtocol.onProtocolSessionStarted(serviceType, (byte) packet.getSessionId(), (byte)protocolVersion.getMajor(), "", hashID, packet.isEncrypted());
10711075
}
10721076

@@ -1184,16 +1188,44 @@ public void onTransportDisconnected(String info, TransportRecord disconnectedTra
11841188
}
11851189

11861190
if((getTransportForSession(SessionType.RPC) != null && disconnectedTransport.equals(getTransportForSession(SessionType.RPC))) || disconnectedTransport.equals(connectedPrimaryTransport)){
1191+
//Primary transport has been disconnected. Let's check if we can recover.
11871192
//transportTypes.remove(type);
11881193
boolean primaryTransportAvailable = false;
11891194
if(requestedPrimaryTransports != null && requestedPrimaryTransports.size() > 1){
1190-
for (TransportType transportType: requestedPrimaryTransports){ Log.d(TAG, "Checking " + transportType.name());
1195+
for (TransportType transportType: requestedPrimaryTransports){
1196+
DebugTool.logInfo( "Checking " + transportType.name());
1197+
11911198
if(!disconnectedTransport.getType().equals(transportType)
11921199
&& transportManager != null
11931200
&& transportManager.isConnected(transportType,null)){
1194-
primaryTransportAvailable = true;
1195-
transportManager.updateTransportConfig(transportConfig);
1196-
break;
1201+
1202+
//There is currently a supported primary transport
1203+
1204+
//See if any high bandwidth transport is available currently
1205+
boolean highBandwidthAvailable = transportManager.isHighBandwidthAvailable();
1206+
1207+
if (requiresHighBandwidth) {
1208+
if (!highBandwidthAvailable) {
1209+
if (TransportType.BLUETOOTH.equals(transportType)
1210+
&& requestedSecondaryTransports != null
1211+
&& supportedSecondaryTransports != null) {
1212+
for (TransportType secondaryTransport : requestedSecondaryTransports) {
1213+
DebugTool.logInfo("Checking secondary " + secondaryTransport.name());
1214+
if (supportedSecondaryTransports.contains(secondaryTransport)) {
1215+
//Should only be USB or TCP
1216+
highBandwidthAvailable = true;
1217+
break;
1218+
}
1219+
}
1220+
}
1221+
} // High bandwidth already available
1222+
}
1223+
1224+
if(!requiresHighBandwidth || (requiresHighBandwidth && highBandwidthAvailable )) {
1225+
primaryTransportAvailable = true;
1226+
transportManager.updateTransportConfig(transportConfig);
1227+
break;
1228+
}
11971229
}
11981230
}
11991231
}

0 commit comments

Comments
 (0)