|
| 1 | +#ifndef _XQC_MOQ_H_INCLUDED_ |
| 2 | +#define _XQC_MOQ_H_INCLUDED_ |
| 3 | + |
| 4 | +#include <xquic/xquic.h> |
| 5 | + |
| 6 | +#ifdef __cplusplus |
| 7 | +extern "C" { |
| 8 | +#endif |
| 9 | + |
| 10 | +#define XQC_ALPN_MOQ_QUIC "moq-quic" |
| 11 | +#define XQC_ALPN_MOQ_WEBTRANSPORT "moq-wt" |
| 12 | + |
| 13 | +typedef enum { |
| 14 | + XQC_MOQ_VIDEO_KEY, |
| 15 | + XQC_MOQ_VIDEO_DELTA, |
| 16 | +} xqc_moq_video_frame_type_t; |
| 17 | + |
| 18 | +typedef struct { |
| 19 | + xqc_moq_video_frame_type_t type; |
| 20 | + uint64_t seq_num; |
| 21 | + uint64_t timestamp_us; |
| 22 | + uint8_t *video_data; |
| 23 | + uint64_t video_len; |
| 24 | +} xqc_moq_video_frame_t; |
| 25 | + |
| 26 | +typedef struct { |
| 27 | + uint64_t seq_num; |
| 28 | + uint64_t timestamp_us; |
| 29 | + uint8_t *audio_data; |
| 30 | + uint64_t audio_len; |
| 31 | +} xqc_moq_audio_frame_t; |
| 32 | + |
| 33 | +typedef enum { |
| 34 | + XQC_MOQ_CONTAINER_LOC, |
| 35 | + XQC_MOQ_CONTAINER_CMAF, |
| 36 | + XQC_MOQ_CONTAINER_NONE, |
| 37 | +} xqc_moq_container_t; |
| 38 | + |
| 39 | +typedef enum { |
| 40 | + XQC_MOQ_TRACK_VIDEO, |
| 41 | + XQC_MOQ_TRACK_AUDIO, |
| 42 | + XQC_MOQ_TRACK_CATALOG, |
| 43 | + XQC_MOQ_TRACK_DATACHANNEL, |
| 44 | +} xqc_moq_track_type_t; |
| 45 | + |
| 46 | +typedef enum { |
| 47 | + XQC_MOQ_TRACK_FOR_PUB, |
| 48 | + XQC_MOQ_TRACK_FOR_SUB, |
| 49 | +} xqc_moq_track_role_t; |
| 50 | + |
| 51 | +typedef struct { |
| 52 | + /* Common */ |
| 53 | + char *codec; /* Required */ |
| 54 | + char *mime_type; /* Required */ |
| 55 | + xqc_int_t bitrate; /* Required */ |
| 56 | + char *lang; /* Optional */ |
| 57 | + /* Video */ |
| 58 | + xqc_int_t framerate; /* Required */ |
| 59 | + xqc_int_t width; /* Required */ |
| 60 | + xqc_int_t height; /* Required */ |
| 61 | + xqc_int_t display_width; /* Optional */ |
| 62 | + xqc_int_t display_height; /* Optional */ |
| 63 | + /* Audio */ |
| 64 | + xqc_int_t samplerate; /* Required */ |
| 65 | + char *channel_config; /* Optional */ |
| 66 | +} xqc_moq_selection_params_t; |
| 67 | + |
| 68 | +typedef struct { |
| 69 | + char *track_namespace; |
| 70 | + char *track_name; |
| 71 | + xqc_moq_track_type_t track_type; |
| 72 | + xqc_moq_selection_params_t selection_params; |
| 73 | +} xqc_moq_track_info_t; |
| 74 | + |
| 75 | +typedef enum { |
| 76 | + XQC_MOQ_TRANSPORT_WEBTRANSPORT, |
| 77 | + XQC_MOQ_TRANSPORT_QUIC, |
| 78 | +} xqc_moq_transport_type_t; |
| 79 | + |
| 80 | +typedef enum { |
| 81 | + XQC_MOQ_PUBLISHER = 0x01, |
| 82 | + XQC_MOQ_SUBSCRIBER = 0x02, |
| 83 | + XQC_MOQ_PUBSUB = 0x03, |
| 84 | +} xqc_moq_role_t; |
| 85 | + |
| 86 | +typedef enum { |
| 87 | + XQC_MOQ_FILTER_LAST_GROUP = 0x1, |
| 88 | + XQC_MOQ_FILTER_LAST_OBJECT = 0x2, |
| 89 | + XQC_MOQ_FILTER_ABSOLUTE_START = 0x3, |
| 90 | + XQC_MOQ_FILTER_ABSOLUTE_RANGE = 0x4, |
| 91 | +} xqc_moq_filter_type_t; |
| 92 | + |
| 93 | +typedef struct xqc_moq_session_s xqc_moq_session_t; |
| 94 | +typedef struct xqc_moq_stream_s xqc_moq_stream_t; |
| 95 | +typedef struct xqc_moq_track_s xqc_moq_track_t; |
| 96 | +typedef struct xqc_moq_object_s xqc_moq_object_t; |
| 97 | +typedef struct xqc_moq_catalog_s xqc_moq_catalog_t; |
| 98 | +typedef struct xqc_moq_subscribe_s xqc_moq_subscribe_t; |
| 99 | +typedef struct xqc_moq_subscribe_msg_s xqc_moq_subscribe_msg_t; |
| 100 | +typedef struct xqc_moq_subscribe_ok_msg_s xqc_moq_subscribe_ok_msg_t; |
| 101 | +typedef struct xqc_moq_subscribe_error_msg_s xqc_moq_subscribe_error_msg_t; |
| 102 | +typedef struct xqc_moq_subscribe_update_msg_s xqc_moq_subscribe_update_msg_t; |
| 103 | +typedef struct xqc_moq_announce_msg_s xqc_moq_announce_msg_t; |
| 104 | +typedef struct xqc_moq_announce_ok_msg_s xqc_moq_announce_ok_msg_t; |
| 105 | +typedef struct xqc_moq_announce_error_msg_s xqc_moq_announce_error_msg_t; |
| 106 | +typedef struct xqc_moq_unannounce_msg_s xqc_moq_unannounce_msg_t; |
| 107 | +typedef struct xqc_moq_unsubscribe_msg_s xqc_moq_unsubscribe_msg_t; |
| 108 | +typedef struct xqc_moq_subscribe_done_msg_s xqc_moq_subscribe_done_msg_t; |
| 109 | +typedef struct xqc_moq_goaway_msg_s xqc_moq_goaway_msg_t; |
| 110 | +typedef struct xqc_moq_client_setup_msg_s xqc_moq_client_setup_msg_t; |
| 111 | +typedef struct xqc_moq_server_setup_msg_s xqc_moq_server_setup_msg_t; |
| 112 | +typedef struct xqc_moq_stream_header_track_msg_s xqc_moq_stream_header_track_msg_t; |
| 113 | +typedef struct xqc_moq_stream_header_group_msg_s xqc_moq_stream_header_group_msg_t; |
| 114 | +typedef struct xqc_moq_decode_msg_ctx_s xqc_moq_decode_msg_ctx_t; |
| 115 | +typedef struct xqc_moq_user_session_s { |
| 116 | + xqc_moq_session_t *session; |
| 117 | + uint8_t data[0]; |
| 118 | +} xqc_moq_user_session_t; |
| 119 | + |
| 120 | +typedef enum { |
| 121 | + XQC_MOQ_MSG_OBJECT_STREAM = 0x0, |
| 122 | + XQC_MOQ_MSG_OBJECT_DATAGRAM = 0x1, |
| 123 | + XQC_MOQ_MSG_SUBSCRIBE_UPDATE = 0x2, |
| 124 | + XQC_MOQ_MSG_SUBSCRIBE = 0x3, |
| 125 | + XQC_MOQ_MSG_SUBSCRIBE_OK = 0x4, |
| 126 | + XQC_MOQ_MSG_SUBSCRIBE_ERROR = 0x5, |
| 127 | + XQC_MOQ_MSG_ANNOUNCE = 0x6, |
| 128 | + XQC_MOQ_MSG_ANNOUNCE_OK = 0x7, |
| 129 | + XQC_MOQ_MSG_ANNOUNCE_ERROR = 0x8, |
| 130 | + XQC_MOQ_MSG_UNANNOUNCE = 0x9, |
| 131 | + XQC_MOQ_MSG_UNSUBSCRIBE = 0xA, |
| 132 | + XQC_MOQ_MSG_SUBSCRIBE_DONE = 0xB, |
| 133 | + XQC_MOQ_MSG_ANNOUNCE_CANCEL = 0xC, |
| 134 | + XQC_MOQ_MSG_TRACK_STATUS_REQUEST = 0xD, |
| 135 | + XQC_MOQ_MSG_TRACK_STATUS = 0xE, |
| 136 | + XQC_MOQ_MSG_GOAWAY = 0x10, |
| 137 | + XQC_MOQ_MSG_CLIENT_SETUP = 0x40, |
| 138 | + XQC_MOQ_MSG_SERVER_SETUP = 0x41, |
| 139 | + XQC_MOQ_MSG_STREAM_HEADER_TRACK = 0x50, |
| 140 | + XQC_MOQ_MSG_STREAM_HEADER_GROUP = 0x51, |
| 141 | + /* Phony message types */ |
| 142 | + XQC_MOQ_MSG_TRACK_STREAM_OBJECT = 0xA0, |
| 143 | + XQC_MOQ_MSG_GROUP_STREAM_OBJECT = 0xA1, |
| 144 | +} xqc_moq_msg_type_t; |
| 145 | + |
| 146 | +typedef struct { |
| 147 | + uint64_t type; |
| 148 | + uint64_t length; |
| 149 | + uint8_t *value; |
| 150 | +} xqc_moq_message_parameter_t; |
| 151 | + |
| 152 | +typedef struct xqc_moq_msg_base_s { |
| 153 | + xqc_moq_msg_type_t (*type)(); |
| 154 | + xqc_int_t (*encode_len)(struct xqc_moq_msg_base_s *msg_base); |
| 155 | + xqc_int_t (*encode)(struct xqc_moq_msg_base_s *msg_base, uint8_t *buf, size_t buf_cap); |
| 156 | + xqc_int_t (*decode)(uint8_t *buf, size_t buf_len, uint8_t stream_fin, struct xqc_moq_decode_msg_ctx_s *msg_ctx, |
| 157 | + struct xqc_moq_msg_base_s *msg_base, xqc_int_t *finish, xqc_int_t *wait_more_data); |
| 158 | + void (*on_msg)(struct xqc_moq_session_s *session, struct xqc_moq_stream_s *moq_stream, struct xqc_moq_msg_base_s *msg_base); |
| 159 | +} xqc_moq_msg_base_t; |
| 160 | + |
| 161 | +typedef struct xqc_moq_subscribe_msg_s { |
| 162 | + xqc_moq_msg_base_t msg_base; |
| 163 | + uint64_t subscribe_id; |
| 164 | + uint64_t track_alias; |
| 165 | + char *track_namespace; |
| 166 | + size_t track_namespace_len; |
| 167 | + char *track_name; |
| 168 | + size_t track_name_len; |
| 169 | + uint64_t filter_type; |
| 170 | + uint64_t start_group_id; |
| 171 | + uint64_t start_object_id; |
| 172 | + uint64_t end_group_id; |
| 173 | + uint64_t end_object_id; |
| 174 | + uint64_t params_num; |
| 175 | + xqc_moq_message_parameter_t *params; |
| 176 | +} xqc_moq_subscribe_msg_t; |
| 177 | + |
| 178 | +typedef struct xqc_moq_subscribe_ok_msg_s { |
| 179 | + xqc_moq_msg_base_t msg_base; |
| 180 | + uint64_t subscribe_id; |
| 181 | + uint64_t expire_ms; |
| 182 | + uint64_t content_exist; |
| 183 | + uint64_t largest_group_id; |
| 184 | + uint64_t largest_object_id; |
| 185 | +} xqc_moq_subscribe_ok_msg_t; |
| 186 | + |
| 187 | +typedef struct xqc_moq_subscribe_error_msg_s { |
| 188 | + xqc_moq_msg_base_t msg_base; |
| 189 | + uint64_t subscribe_id; |
| 190 | + uint64_t error_code; |
| 191 | + char *reason_phrase; |
| 192 | + size_t reason_phrase_len; |
| 193 | + uint64_t track_alias; |
| 194 | +} xqc_moq_subscribe_error_msg_t; |
| 195 | + |
| 196 | +typedef void (*xqc_moq_on_session_setup_pt)(xqc_moq_user_session_t *user_session, char *extdata); |
| 197 | + |
| 198 | +typedef void (*xqc_moq_on_datachannel_pt)(xqc_moq_user_session_t *user_session); |
| 199 | + |
| 200 | +typedef void (*xqc_moq_on_datachannel_msg_pt)(xqc_moq_user_session_t *user_session, uint8_t *msg, size_t msg_len); |
| 201 | + |
| 202 | +typedef void (*xqc_moq_on_subscribe_pt)(xqc_moq_user_session_t *user_session, uint64_t subscribe_id, |
| 203 | + xqc_moq_track_t *track, xqc_moq_subscribe_msg_t *msg); |
| 204 | + |
| 205 | +typedef void (*xqc_moq_on_request_keyframe_pt)(xqc_moq_user_session_t *user_session, uint64_t subscribe_id, |
| 206 | + xqc_moq_track_t *track); |
| 207 | + |
| 208 | +typedef void (*xqc_moq_on_subscribe_ok_pt)(xqc_moq_user_session_t *user_session, |
| 209 | + xqc_moq_subscribe_ok_msg_t *subscribe_ok); |
| 210 | + |
| 211 | +typedef void (*xqc_moq_on_subscribe_error_pt)(xqc_moq_user_session_t *user_session, |
| 212 | + xqc_moq_subscribe_error_msg_t *subscribe_error); |
| 213 | + |
| 214 | +typedef void (*xqc_moq_on_catalog_pt)(xqc_moq_user_session_t *user_session, xqc_moq_track_info_t **track_info_array, |
| 215 | + xqc_int_t array_size); |
| 216 | + |
| 217 | +typedef void (*xqc_moq_on_video_frame_pt)(xqc_moq_user_session_t *user_session, uint64_t subscribe_id, |
| 218 | + xqc_moq_video_frame_t *video_frame); |
| 219 | + |
| 220 | +typedef void (*xqc_moq_on_audio_frame_pt)(xqc_moq_user_session_t *user_session, uint64_t subscribe_id, |
| 221 | + xqc_moq_audio_frame_t *audio_frame); |
| 222 | + |
| 223 | +/** |
| 224 | + * @brief There are two ways to get the target bitrate. |
| 225 | + * 1. Call xqc_moq_target_bitrate before encoding. |
| 226 | + * 2. Register the xqc_moq_on_bitrate_change_pt callback. A callback notification occurs when the target bitrate changes |
| 227 | + */ |
| 228 | +typedef void (*xqc_moq_on_bitrate_change_pt)(xqc_moq_user_session_t *user_session, uint64_t bitrate); |
| 229 | + |
| 230 | +typedef struct { |
| 231 | + xqc_moq_on_session_setup_pt on_session_setup; /* Required */ |
| 232 | + xqc_moq_on_datachannel_pt on_datachannel; /* Required */ |
| 233 | + xqc_moq_on_datachannel_msg_pt on_datachannel_msg; /* Required */ |
| 234 | + /* For Publisher */ |
| 235 | + xqc_moq_on_subscribe_pt on_subscribe; /* Required */ |
| 236 | + xqc_moq_on_request_keyframe_pt on_request_keyframe; /* Required */ |
| 237 | + xqc_moq_on_bitrate_change_pt on_bitrate_change; /* Optional */ |
| 238 | + /* For Subscriber */ |
| 239 | + xqc_moq_on_subscribe_ok_pt on_subscribe_ok; /* Required */ |
| 240 | + xqc_moq_on_subscribe_error_pt on_subscribe_error; /* Required */ |
| 241 | + xqc_moq_on_catalog_pt on_catalog; /* Required */ |
| 242 | + xqc_moq_on_video_frame_pt on_video; /* Required */ |
| 243 | + xqc_moq_on_audio_frame_pt on_audio; /* Required */ |
| 244 | +} xqc_moq_session_callbacks_t; |
| 245 | + |
| 246 | +XQC_EXPORT_PUBLIC_API |
| 247 | +void xqc_moq_init_alpn(xqc_engine_t *engine, xqc_conn_callbacks_t *conn_cbs, xqc_moq_transport_type_t transport_type); |
| 248 | + |
| 249 | +/** |
| 250 | + * @param extdata The client can send extdata when creating a session. |
| 251 | + * This extdata will be received by the server in the on_session_setup callback. |
| 252 | + */ |
| 253 | +XQC_EXPORT_PUBLIC_API |
| 254 | +xqc_moq_session_t *xqc_moq_session_create(void *conn, xqc_moq_user_session_t *user_session, |
| 255 | + xqc_moq_transport_type_t type, xqc_moq_role_t role, xqc_moq_session_callbacks_t, char *extdata); |
| 256 | + |
| 257 | +XQC_EXPORT_PUBLIC_API |
| 258 | +void xqc_moq_session_destroy(xqc_moq_session_t *session); |
| 259 | + |
| 260 | +/** |
| 261 | + * @brief Set application error code and close the connection |
| 262 | + * @param code in range 0x700 ~ 0x7FF |
| 263 | + */ |
| 264 | +XQC_EXPORT_PUBLIC_API |
| 265 | +void xqc_moq_session_app_error(xqc_moq_session_t *session, uint64_t code); |
| 266 | + |
| 267 | +/** |
| 268 | + * @brief Get session error code in conn_closing or conn_close_notify |
| 269 | + */ |
| 270 | +XQC_EXPORT_PUBLIC_API |
| 271 | +uint64_t xqc_moq_session_get_error(xqc_moq_session_t *session); |
| 272 | + |
| 273 | +/** |
| 274 | + * @brief Call it after xqc_moq_session_create |
| 275 | + * Configure bitrate in bps |
| 276 | + */ |
| 277 | +XQC_EXPORT_PUBLIC_API |
| 278 | +void xqc_moq_configure_bitrate(xqc_moq_session_t *session, uint64_t init_bitrate, uint64_t max_bitrate, uint64_t min_bitrate); |
| 279 | + |
| 280 | +/** |
| 281 | + * @brief There are two ways to get the target bitrate. |
| 282 | + * 1. Call xqc_moq_target_bitrate before encoding. |
| 283 | + * 2. Register the xqc_moq_on_bitrate_change_pt callback. A callback notification occurs when the target bitrate changes |
| 284 | + * @return Encode bitrate in bits per second (bps) |
| 285 | + */ |
| 286 | +XQC_EXPORT_PUBLIC_API |
| 287 | +uint64_t xqc_moq_target_bitrate(xqc_moq_session_t *session); |
| 288 | + |
| 289 | +XQC_EXPORT_PUBLIC_API |
| 290 | +xqc_moq_track_t *xqc_moq_track_create(xqc_moq_session_t *session, char *track_namespace, char *track_name, |
| 291 | + xqc_moq_track_type_t track_type, xqc_moq_selection_params_t *params, xqc_moq_container_t container, xqc_moq_track_role_t role); |
| 292 | + |
| 293 | +XQC_EXPORT_PUBLIC_API |
| 294 | +xqc_int_t xqc_moq_subscribe(xqc_moq_session_t *session, const char *track_namespace, const char *track_name, |
| 295 | + xqc_moq_filter_type_t filter_type, uint64_t start_group_id, uint64_t start_object_id, |
| 296 | + uint64_t end_group_id, uint64_t end_object_id, char *authinfo); |
| 297 | + |
| 298 | +XQC_EXPORT_PUBLIC_API |
| 299 | +xqc_int_t xqc_moq_subscribe_latest(xqc_moq_session_t *session, const char *track_namespace, const char *track_name); |
| 300 | + |
| 301 | +XQC_EXPORT_PUBLIC_API |
| 302 | +xqc_int_t xqc_moq_request_keyframe(xqc_moq_session_t *session, uint64_t subscribe_id); |
| 303 | + |
| 304 | +XQC_EXPORT_PUBLIC_API |
| 305 | +xqc_int_t xqc_moq_write_subscribe_ok(xqc_moq_session_t *session, xqc_moq_subscribe_ok_msg_t *subscribe_ok); |
| 306 | + |
| 307 | +XQC_EXPORT_PUBLIC_API |
| 308 | +xqc_int_t xqc_moq_write_subscribe_error(xqc_moq_session_t *session, xqc_moq_subscribe_error_msg_t *subscribe_error); |
| 309 | + |
| 310 | +XQC_EXPORT_PUBLIC_API |
| 311 | +xqc_int_t xqc_moq_write_datachannel(xqc_moq_session_t *session, uint8_t *msg, size_t msg_len); |
| 312 | + |
| 313 | +XQC_EXPORT_PUBLIC_API |
| 314 | +xqc_int_t xqc_moq_write_video_frame(xqc_moq_session_t *session, uint64_t subscribe_id, |
| 315 | + xqc_moq_track_t *track, xqc_moq_video_frame_t *video_frame); |
| 316 | + |
| 317 | +XQC_EXPORT_PUBLIC_API |
| 318 | +xqc_int_t xqc_moq_write_audio_frame(xqc_moq_session_t *session, uint64_t subscribe_id, |
| 319 | + xqc_moq_track_t *track, xqc_moq_audio_frame_t *audio_frame); |
| 320 | + |
| 321 | +#ifdef __cplusplus |
| 322 | +} |
| 323 | +#endif |
| 324 | + |
| 325 | +#endif /* _XQC_MOQ_H_INCLUDED_ */ |
0 commit comments