chromecast: replace the p_input hack by an other one
[vlc.git] / modules / stream_out / chromecast / chromecast.h
blobb32a0ded7b44bb3daa26dcc69d0642e158a18e32
1 /*****************************************************************************
2 * chromecast.cpp: Chromecast module for vlc
3 *****************************************************************************
4 * Copyright © 2014-2015 VideoLAN
6 * Authors: Adrien Maglo <magsoft@videolan.org>
7 * Jean-Baptiste Kempf <jb@videolan.org>
8 * Steve Lhomme <robux4@videolabs.io>
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU Lesser General Public License as published by
12 * the Free Software Foundation; either version 2.1 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License for more details.
20 * You should have received a copy of the GNU Lesser General Public License
21 * along with this program; if not, write to the Free Software Foundation,
22 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
23 *****************************************************************************/
25 /*****************************************************************************
26 * Preamble
27 *****************************************************************************/
29 #ifndef VLC_CHROMECAST_H
30 #define VLC_CHROMECAST_H
32 #include <vlc_common.h>
33 #include <vlc_plugin.h>
34 #include <vlc_tls.h>
35 #include <vlc_interrupt.h>
36 #include <vlc_httpd.h>
38 #include <atomic>
39 #include <sstream>
40 #include <queue>
42 #ifndef PROTOBUF_INLINE_NOT_IN_HEADERS
43 # define PROTOBUF_INLINE_NOT_IN_HEADERS 0
44 #endif
45 #include "cast_channel.pb.h"
46 #include "chromecast_common.h"
48 #define PACKET_HEADER_LEN 4
50 // Media player Chromecast app id
51 static const std::string DEFAULT_CHOMECAST_RECEIVER = "receiver-0";
52 /* see https://developers.google.com/cast/docs/reference/messages */
53 static const std::string NAMESPACE_MEDIA = "urn:x-cast:com.google.cast.media";
54 static const std::string NAMESPACE_DEVICEAUTH = "urn:x-cast:com.google.cast.tp.deviceauth";
55 static const std::string NAMESPACE_CONNECTION = "urn:x-cast:com.google.cast.tp.connection";
56 static const std::string NAMESPACE_HEARTBEAT = "urn:x-cast:com.google.cast.tp.heartbeat";
57 static const std::string NAMESPACE_RECEIVER = "urn:x-cast:com.google.cast.receiver";
60 #define CHROMECAST_CONTROL_PORT 8009
61 #define HTTP_PORT 8010
63 #define PACKET_MAX_LEN 10 * 1024
65 //#define CHROMECAST_VERBOSE
67 // Media player Chromecast app id
68 #define APP_ID "CC1AD845" // Default media player aka DEFAULT_MEDIA_RECEIVER_APPLICATION_ID
70 enum States
72 // An authentication request has been sent
73 Authenticating,
74 // We are sending a connection request
75 Connecting,
76 // We are connected to the chromecast but the receiver app is not running.
77 Connected,
78 // We are launching the media receiver app
79 Launching,
80 // The application is ready, but idle
81 Ready,
82 // The chromecast rejected the media
83 LoadFailed,
84 // A media session is being initiated
85 Loading,
86 Buffering,
87 Playing,
88 Paused,
89 Stopping,
90 Stopped,
91 // Something went wrong and the connection is dead.
92 Dead,
93 // Another playback started on the same cast device
94 TakenOver,
97 class ChromecastCommunication
99 public:
100 ChromecastCommunication( vlc_object_t* module, const char* targetIP, unsigned int devicePort );
101 ~ChromecastCommunication();
103 * @brief disconnect close the connection with the chromecast
105 void disconnect();
107 static const unsigned kInvalidId = 0;
109 /* All msg*() methods return kInvalidId on error, 1 or the receiver/player
110 * request ID on success */
112 unsigned msgPing();
113 unsigned msgPong();
114 unsigned msgConnect( const std::string& destinationId );
116 unsigned msgReceiverLaunchApp();
117 unsigned msgReceiverGetStatus();
118 unsigned msgReceiverClose(const std::string& destinationId);
119 unsigned msgAuth();
120 unsigned msgPlayerLoad( const std::string& destinationId, unsigned int i_port,
121 const std::string& mime, const vlc_meta_t *p_meta );
122 unsigned msgPlayerPlay( const std::string& destinationId, int64_t mediaSessionId );
123 unsigned msgPlayerStop( const std::string& destinationId, int64_t mediaSessionId );
124 unsigned msgPlayerPause( const std::string& destinationId, int64_t mediaSessionId );
125 unsigned msgPlayerGetStatus( const std::string& destinationId );
126 unsigned msgPlayerSeek( const std::string& destinationId, int64_t mediaSessionId,
127 const std::string & currentTime );
128 unsigned msgPlayerSetVolume( const std::string& destinationId, int64_t mediaSessionId,
129 float volume, bool mute);
130 ssize_t receive( uint8_t *p_data, size_t i_size, int i_timeout, bool *pb_timeout );
132 const std::string getServerIp()
134 return m_serverIp;
136 private:
137 int sendMessage(const castchannel::CastMessage &msg);
139 int buildMessage(const std::string & namespace_,
140 const std::string & payload,
141 const std::string & destinationId = DEFAULT_CHOMECAST_RECEIVER,
142 castchannel::CastMessage_PayloadType payloadType = castchannel::CastMessage_PayloadType_STRING);
143 int pushMediaPlayerMessage( const std::string& destinationId, const std::stringstream & payload );
144 std::string GetMedia( unsigned int i_port, const std::string& mime,
145 const vlc_meta_t *p_meta );
146 unsigned getNextReceiverRequestId();
147 unsigned getNextRequestId();
149 private:
150 vlc_object_t* m_module;
151 vlc_tls_creds_t *m_creds;
152 vlc_tls_t *m_tls;
153 unsigned m_receiver_requestId;
154 unsigned m_requestId;
155 std::string m_serverIp;
158 /*****************************************************************************
159 * intf_sys_t: description and status of interface
160 *****************************************************************************/
161 struct intf_sys_t
163 enum QueueableMessages
165 Stop,
167 intf_sys_t(vlc_object_t * const p_this, int local_port, std::string device_addr,
168 int device_port, httpd_host_t *);
169 ~intf_sys_t();
171 void setRetryOnFail(bool);
172 void setHasInput(const std::string mime_type = "");
174 void setOnInputEventCb(on_input_event_itf on_input_event, void *on_input_event_data);
175 void setDemuxEnabled(bool enabled, on_paused_changed_itf on_paused_changed,
176 void *on_paused_changed_data);
177 void requestPlayerStop();
178 States state() const;
180 void setPacing(bool do_pace);
181 int pace();
182 void sendInputEvent(enum cc_input_event event, union cc_input_arg arg);
183 vlc_tick_t getPauseDelay();
185 int httpd_file_fill( uint8_t *psz_request, uint8_t **pp_data, int *pi_data );
186 void interrupt_wake_up();
187 private:
188 void reinit();
189 bool handleMessages();
191 bool processMessage(const castchannel::CastMessage &msg);
192 void queueMessage( QueueableMessages msg );
194 void setPauseState(bool paused, vlc_tick_t delay);
195 bool isFinishedPlaying();
196 bool isStateError() const;
197 bool isStatePlaying() const;
198 bool isStateReady() const;
199 void tryLoad();
200 void doStop();
202 void setMeta( vlc_meta_t *p_meta );
204 vlc_tick_t getPlaybackTimestamp();
206 double getPlaybackPosition() const;
208 void setInitialTime( vlc_tick_t time );
209 // Sets the current state and signal the associated wait cond.
210 // This must be called with the lock held
211 void setState( States state );
213 void mainLoop();
214 void processAuthMessage( const castchannel::CastMessage& msg );
215 void processHeartBeatMessage( const castchannel::CastMessage& msg );
216 bool processReceiverMessage( const castchannel::CastMessage& msg );
217 void processMediaMessage( const castchannel::CastMessage& msg );
218 void processConnectionMessage( const castchannel::CastMessage& msg );
220 private:
221 static void* ChromecastThread(void* p_data);
223 static vlc_tick_t get_time(void*);
225 static int pace(void*);
226 static void send_input_event(void *, enum cc_input_event event, union cc_input_arg arg);
227 static void set_demux_enabled(void *, bool, on_paused_changed_itf, void *);
229 static void set_pause_state(void*, bool paused, vlc_tick_t delay);
231 static void set_meta(void*, vlc_meta_t *p_meta);
233 void prepareHttpArtwork();
235 static vlc_tick_t timeCCToVLC(double);
236 static std::string timeVLCToCC(vlc_tick_t);
238 private:
239 vlc_object_t * const m_module;
240 const int m_streaming_port;
241 const int m_device_port;
242 std::string m_mime;
243 std::string m_device_addr;
245 std::string m_appTransportId;
246 unsigned m_last_request_id;
247 int64_t m_mediaSessionId;
249 mutable vlc_mutex_t m_lock;
250 vlc_cond_t m_stateChangedCond;
251 vlc_cond_t m_pace_cond;
252 vlc_thread_t m_chromecastThread;
254 on_input_event_itf m_on_input_event;
255 void *m_on_input_event_data;
257 on_paused_changed_itf m_on_paused_changed;
258 void *m_on_paused_changed_data;
260 ChromecastCommunication *m_communication;
261 std::queue<QueueableMessages> m_msgQueue;
262 States m_state;
263 bool m_retry_on_fail;
264 bool m_played_once;
265 bool m_request_stop;
266 bool m_request_load;
267 bool m_paused;
268 bool m_input_eof;
269 bool m_cc_eof;
270 bool m_pace;
271 bool m_interrupted;
273 vlc_meta_t *m_meta;
275 vlc_interrupt_t *m_ctl_thread_interrupt;
277 httpd_host_t *m_httpd_host;
278 httpd_file_t *m_httpd_file;
279 std::string m_art_http_ip;
280 char *m_art_url;
281 unsigned m_art_idx;
283 vlc_tick_t m_cc_time_last_request_date;
284 vlc_tick_t m_cc_time_date;
285 vlc_tick_t m_cc_time;
286 vlc_tick_t m_pause_delay;
288 /* shared structure with the demux-filter */
289 chromecast_common m_common;
291 /* Heartbeat */
292 uint8_t m_pingRetriesLeft;
295 #endif /* VLC_CHROMECAST_H */