[vlc-commits] [Git][videolan/vlc][master] 2 commits: sout: chromecast: fix `CLOSE` json message parsing

Felix Paul Kühne (@fkuehne) gitlab at videolan.org
Fri Mar 27 14:27:22 UTC 2026



Felix Paul Kühne pushed to branch master at VideoLAN / VLC


Commits:
8fbd8560 by Alaric Senat at 2026-03-27T14:48:56+01:00
sout: chromecast: fix `CLOSE` json message parsing

The `type` value is defined in the parent message by the protocol, not
in a sub-object. This was mistakenly introduced by d85ecc2dd1f8365200b87e5164b5c76355d2ce0e.

This fixes a subsequent assert on chromecast app closure:

```
stream out debug: processMessage: urn:x-cast:com.google.cast.tp.connection->sender-vlc {"type":"CLOSE"}
stream out error: connection message: bad payload
stream out warning: Unexpected RECEIVER_STATUS with state Stopped. Checking media status
chromecast_communication.cpp:483: int ChromecastCommunication::pushMediaPlayerMessage(const std::string&, const std::stringstream&): Assertion `!destinationId.empty()' failed.
Aborted
```

- - - - -
37afe71a by Alaric Senat at 2026-03-27T14:48:56+01:00
sout: chromecast: avoid unecessary string copies

Use std::string_view to compare strings from the json parser, it avoids
extra std::string allocation just for that purpose.

- - - - -


1 changed file:

- modules/stream_out/chromecast/chromecast_ctrl.cpp


Changes:

=====================================
modules/stream_out/chromecast/chromecast_ctrl.cpp
=====================================
@@ -36,6 +36,7 @@
 #include <cassert>
 #include <cerrno>
 #include <iomanip>
+#include <string_view>
 
 #include <vlc_fixups.h>
 #include <vlc_stream.h>
@@ -83,6 +84,12 @@ size_t json_read(void *data, void *buf, size_t size)
 
 }
 
+static inline std::string_view json_get_str_view(const struct json_object *obj, const char *key)
+{
+    const char *val = json_get_str(obj, key);
+    return val ? val : "";
+}
+
 static int httpd_file_fill_cb( httpd_file_sys_t *data, httpd_file_t *http_file,
                           uint8_t *psz_request, uint8_t **pp_data, size_t *pi_data );
 
@@ -736,8 +743,7 @@ void intf_sys_t::processAuthMessage( const castchannel::CastMessage& msg )
 void intf_sys_t::processHeartBeatMessage( const castchannel::CastMessage& msg , const struct json_object *entry )
 {
     VLC_UNUSED(msg);
-    const char *tmp = json_get_str(entry, "type");
-    std::string type = tmp ? tmp : ""; 
+    const std::string_view type = json_get_str_view(entry, "type");
     if (type == "PING")
     {
         msg_Dbg( m_module, "PING received from the Chromecast");
@@ -745,19 +751,18 @@ void intf_sys_t::processHeartBeatMessage( const castchannel::CastMessage& msg ,
     }
     else if (type == "PONG")
     {
-        msg_Dbg( m_module, "PONG received from the Chromecast");
+        msg_Dbg(m_module, "PONG received from the Chromecast");
         m_pingRetriesLeft = PING_WAIT_RETRIES;
     }
     else
     {
-        msg_Warn( m_module, "Heartbeat command not supported: %s", type.c_str());
+        msg_Warn(m_module, "Heartbeat command not supported: %s", type.data());
     }
 }
 
 bool intf_sys_t::processReceiverMessage( const castchannel::CastMessage& msg , const struct json_object *entry )
 {
-    const char *tmp = json_get_str(entry, "type");
-    std::string type = tmp ? tmp : "";
+    const std::string_view type = json_get_str_view(entry, "type");
 
     bool ret = true;
     if (type == "RECEIVER_STATUS")
@@ -794,8 +799,7 @@ bool intf_sys_t::processReceiverMessage( const castchannel::CastMessage& msg , c
             if ( p_app != NULL )
             {
                 msg_Dbg( m_module, "Media receiver application was already running" );
-                tmp = json_get_str(p_app, "transportId");
-                m_appTransportId = tmp ? tmp: "";
+                m_appTransportId = json_get_str_view(p_app, "transportId");
                 m_communication->msgConnect( m_appTransportId );
                 setState( Ready );
             }
@@ -809,8 +813,7 @@ bool intf_sys_t::processReceiverMessage( const castchannel::CastMessage& msg , c
             if ( p_app != NULL )
             {
                 msg_Dbg( m_module, "Media receiver application has been started." );
-                tmp = json_get_str(p_app, "transportId");
-                m_appTransportId = tmp ? tmp: "";
+                m_appTransportId = json_get_str_view(p_app, "transportId");
                 m_communication->msgConnect( m_appTransportId );
                 setState( Ready );
             }
@@ -868,8 +871,7 @@ bool intf_sys_t::processReceiverMessage( const castchannel::CastMessage& msg , c
 
 void intf_sys_t::processMediaMessage( const castchannel::CastMessage& msg , const struct json_object *entry )
 {
-    const char *tmp = json_get_str(entry, "type");
-    std::string type = tmp ? tmp: "";
+    const std::string_view type = json_get_str_view(entry, "type");
     int64_t requestId = (int64_t) json_get_num(entry,"requestId");
 
     vlc::threads::mutex_locker lock( m_lock );
@@ -889,14 +891,11 @@ void intf_sys_t::processMediaMessage( const castchannel::CastMessage& msg , cons
             return;
         }
         int64_t sessionId = (int64_t) json_get_num(&status->array.entries[0].object,"mediaSessionId");
-        tmp = json_get_str(&status->array.entries[0].object,"playerState");
-        std::string newPlayerState = tmp ? tmp: "";
-        tmp = json_get_str(&status->array.entries[0].object,"idleReason");
-        std::string idleReason = tmp ? tmp: "";
+        const std::string_view newPlayerState = json_get_str_view(&status->array.entries[0].object,"playerState");
+        const std::string_view idleReason = json_get_str_view(&status->array.entries[0].object,"idleReason");
 
-        msg_Dbg( m_module, "Player state: %s sessionId: %" PRId64,
-                 json_get_str(&status->array.entries[0].object,"playerState"),
-                 sessionId );
+        msg_Dbg(m_module, "Player state: %s sessionId: %" PRId64,
+                newPlayerState.data(), sessionId);
 
         if (sessionId != 0 && m_mediaSessionId != 0 && m_mediaSessionId != sessionId)
         {
@@ -995,7 +994,7 @@ void intf_sys_t::processMediaMessage( const castchannel::CastMessage& msg , cons
                 }
             }
             else
-                msg_Warn( m_module, "Unknown Chromecast MEDIA_STATUS state %s", newPlayerState.c_str());
+                msg_Warn(m_module, "Unknown Chromecast MEDIA_STATUS state %s", newPlayerState.data());
         }
     }
     else if (type == "LOAD_FAILED")
@@ -1019,14 +1018,9 @@ void intf_sys_t::processMediaMessage( const castchannel::CastMessage& msg , cons
 
 }
 
-void intf_sys_t::processConnectionMessage( const castchannel::CastMessage& msg , const struct json_object *entry )
+void intf_sys_t::processConnectionMessage( const castchannel::CastMessage& , const struct json_object *entry )
 {
-    const struct json_value *value = json_get(entry, msg.payload_utf8().c_str());
-    if (!value) {
-        msg_Err(m_module, "connection message: bad payload");
-        return;
-    }
-    std::string type = json_get_str(&value->object, "type");
+    const std::string_view type = json_get_str_view(entry, "type");
 
     if ( type == "CLOSE" )
     {
@@ -1040,7 +1034,7 @@ void intf_sys_t::processConnectionMessage( const castchannel::CastMessage& msg ,
     else
     {
         msg_Warn( m_module, "Connection command not supported: %s",
-                type.c_str());
+                  type.data() );
     }
 }
 



View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/f68aa4821ca749e30db2d64e53faf9fa4de7428e...37afe71a69684c7fe594934ad0dca4542a48cf19

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/f68aa4821ca749e30db2d64e53faf9fa4de7428e...37afe71a69684c7fe594934ad0dca4542a48cf19
You're receiving this email because of your account on code.videolan.org.




More information about the vlc-commits mailing list