rtmp.h 40 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130
  1. // Licensed to the Apache Software Foundation (ASF) under one
  2. // or more contributor license agreements. See the NOTICE file
  3. // distributed with this work for additional information
  4. // regarding copyright ownership. The ASF licenses this file
  5. // to you under the Apache License, Version 2.0 (the
  6. // "License"); you may not use this file except in compliance
  7. // with the License. You may obtain a copy of the License at
  8. //
  9. // http://www.apache.org/licenses/LICENSE-2.0
  10. //
  11. // Unless required by applicable law or agreed to in writing,
  12. // software distributed under the License is distributed on an
  13. // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  14. // KIND, either express or implied. See the License for the
  15. // specific language governing permissions and limitations
  16. // under the License.
  17. #ifndef BRPC_RTMP_H
  18. #define BRPC_RTMP_H
  19. #include "butil/strings/string_piece.h" // butil::StringPiece
  20. #include "butil/endpoint.h" // butil::EndPoint
  21. #include "brpc/shared_object.h" // SharedObject, intrusive_ptr
  22. #include "brpc/socket_id.h" // SocketUniquePtr
  23. #include "brpc/controller.h" // Controller, IOBuf
  24. #include "brpc/rtmp.pb.h" // RtmpConnectRequest
  25. #include "brpc/amf.h" // AMFObject
  26. #include "brpc/destroyable.h" // DestroyingPtr
  27. namespace brpc {
  28. namespace policy {
  29. class RtmpContext;
  30. class RtmpChunkStream;
  31. class OnServerStreamCreated;
  32. }
  33. class RtmpClientImpl;
  34. class RtmpClientStream;
  35. class RtmpServerStream;
  36. class StatusService;
  37. // ======= Audio =======
  38. enum RtmpAudioCodec {
  39. RTMP_AUDIO_NONE = 0x0001, // Raw sound, no compression
  40. RTMP_AUDIO_ADPCM = 0x0002, // ADPCM compression
  41. RTMP_AUDIO_MP3 = 0x0004, // mp3 compression
  42. RTMP_AUDIO_INTEL = 0x0008, // Not used
  43. RTMP_AUDIO_UNUSED = 0x0010, // Not used
  44. RTMP_AUDIO_NELLY8 = 0x0020, // NellyMoser at 8-kHz compression
  45. RTMP_AUDIO_NELLY = 0x0040, // NellyMoser compression (5, 11, 22, and 44 kHz)
  46. RTMP_AUDIO_G711A = 0x0080, // G711A sound compression (Flash Media Server only)
  47. RTMP_AUDIO_G711U = 0x0100, // G711U sound compression (Flash Media Server only)
  48. RTMP_AUDIO_NELLY16 = 0x0200, // NellyMouser at 16-kHz compression
  49. RTMP_AUDIO_AAC = 0x0400, // Advanced audio coding (AAC) codec
  50. RTMP_AUDIO_SPEEX = 0x0800, // Speex Audio
  51. RTMP_AUDIO_ALL = 0x0FFF, // All RTMP-supported audio codecs
  52. };
  53. static const RtmpAudioCodec RTMP_AUDIO_UNKNOWN = (RtmpAudioCodec)0;
  54. enum FlvAudioCodec {
  55. FLV_AUDIO_LINEAR_PCM_PLATFORM_ENDIAN = 0,
  56. FLV_AUDIO_ADPCM = 1,
  57. FLV_AUDIO_MP3 = 2,
  58. FLV_AUDIO_LINEAR_PCM_LITTLE_ENDIAN = 3,
  59. FLV_AUDIO_NELLYMOSER_16KHZ_MONO = 4,
  60. FLV_AUDIO_NELLYMOSER_8KHZ_MONO = 5,
  61. FLV_AUDIO_NELLYMOSER = 6,
  62. FLV_AUDIO_G711_ALAW_LOGARITHMIC_PCM = 7,
  63. FLV_AUDIO_G711_MULAW_LOGARITHMIC_PCM = 8,
  64. FLV_AUDIO_RESERVED = 9,
  65. FLV_AUDIO_AAC = 10,
  66. FLV_AUDIO_SPEEX = 11,
  67. FLV_AUDIO_MP3_8KHZ = 14,
  68. FLV_AUDIO_DEVICE_SPECIFIC_SOUND = 15,
  69. };
  70. // note: 16 is always safe because SoundFormat in flv spec is only 4 bits.
  71. static const FlvAudioCodec FLV_AUDIO_UNKNOWN = (FlvAudioCodec)16/*note*/;
  72. const char* FlvAudioCodec2Str(FlvAudioCodec);
  73. enum FlvSoundRate {
  74. FLV_SOUND_RATE_5512HZ = 0,
  75. FLV_SOUND_RATE_11025HZ = 1,
  76. FLV_SOUND_RATE_22050HZ = 2,
  77. FLV_SOUND_RATE_44100HZ = 3,
  78. };
  79. const char* FlvSoundRate2Str(FlvSoundRate);
  80. // Only pertains to uncompressed formats. Compressed formats always decode
  81. // to 16 bits internally.
  82. enum FlvSoundBits {
  83. FLV_SOUND_8BIT = 0,
  84. FLV_SOUND_16BIT = 1,
  85. };
  86. const char* FlvSoundBits2Str(FlvSoundBits);
  87. // For Nellymoser: always 0. For AAC: always 1.
  88. enum FlvSoundType {
  89. FLV_SOUND_MONO = 0,
  90. FLV_SOUND_STEREO = 1,
  91. };
  92. const char* FlvSoundType2Str(FlvSoundType);
  93. // The Audio Message in RTMP.
  94. struct RtmpAudioMessage {
  95. uint32_t timestamp;
  96. FlvAudioCodec codec;
  97. FlvSoundRate rate;
  98. FlvSoundBits bits;
  99. FlvSoundType type;
  100. butil::IOBuf data;
  101. bool IsAACSequenceHeader() const;
  102. size_t size() const { return data.size() + 1; }
  103. };
  104. std::ostream& operator<<(std::ostream&, const RtmpAudioMessage&);
  105. enum FlvAACPacketType {
  106. FLV_AAC_PACKET_SEQUENCE_HEADER = 0,
  107. FLV_AAC_PACKET_RAW = 1,
  108. };
  109. // The Audio Message when format == FLV_AUDIO_AAC
  110. struct RtmpAACMessage {
  111. uint32_t timestamp;
  112. FlvSoundRate rate;
  113. FlvSoundBits bits;
  114. FlvSoundType type;
  115. FlvAACPacketType packet_type;
  116. // For sequence header: AudioSpecificConfig
  117. // For raw: Raw AAC frame data
  118. butil::IOBuf data;
  119. // Create AAC message from audio message.
  120. butil::Status Create(const RtmpAudioMessage& msg);
  121. // Size of serialized message.
  122. size_t size() const { return data.size() + 2; }
  123. };
  124. // the aac object type, for RTMP sequence header
  125. // aac-mp4a-format-ISO_IEC_14496-3+2001.pdf, page 23
  126. enum AACObjectType {
  127. AAC_OBJECT_MAIN = 1,
  128. AAC_OBJECT_LC = 2,
  129. AAC_OBJECT_SSR = 3,
  130. AAC_OBJECT_HE = 5, // AAC HE = LC+SBR
  131. AAC_OBJECT_HEV2 = 29, // AAC HEv2 = LC+SBR+PS
  132. };
  133. static const AACObjectType AAC_OBJECT_UNKNOWN = (AACObjectType)0;
  134. struct AudioSpecificConfig {
  135. AudioSpecificConfig();
  136. butil::Status Create(const butil::IOBuf& buf);
  137. butil::Status Create(const void* data, size_t len);
  138. AACObjectType aac_object;
  139. uint8_t aac_sample_rate;
  140. uint8_t aac_channels;
  141. };
  142. // ======= Video =======
  143. enum RtmpVideoCodec {
  144. RTMP_VIDEO_UNUSED = 0x0001, // Obsolete value
  145. RTMP_VIDEO_JPEG = 0x0002, // Obsolete value
  146. RTMP_VIDEO_SORENSON = 0x0004, // Sorenson Flash video
  147. RTMP_VIDEO_HOMEBREW = 0x0008, // V1 screen sharing
  148. RTMP_VIDEO_VP6 = 0x0010, // On2 video (Flash 8+)
  149. RTMP_VIDEO_VP6ALPHA = 0x0020, // On2 video with alpha
  150. RTMP_VIDEO_HOMEBREWV = 0x0040, // Screen sharing version 2 (Flash 8+)
  151. RTMP_VIDEO_H264 = 0x0080, // H264 video
  152. RTMP_VIDEO_ALL = 0x00FF, // All RTMP-supported video
  153. };
  154. static const RtmpVideoCodec RTMP_VIDEO_UNKNOWN = (RtmpVideoCodec)0;
  155. enum RtmpVideoFunction {
  156. // Indicates that the client can perform frame-accurate seeks.
  157. RTMP_VIDEO_FUNCTION_CLIENT_SEEK = 1,
  158. };
  159. enum FlvVideoFrameType {
  160. FLV_VIDEO_FRAME_KEYFRAME = 1, // for AVC, a seekable frame
  161. FLV_VIDEO_FRAME_INTERFRAME = 2, // for AVC, a non-seekable frame
  162. FLV_VIDEO_FRAME_DISPOSABLE_INTERFRAME = 3, // H.263 only
  163. FLV_VIDEO_FRAME_GENERATED_KEYFRAME = 4, // reserved for server use only
  164. FLV_VIDEO_FRAME_INFOFRAME = 5
  165. };
  166. const char* FlvVideoFrameType2Str(FlvVideoFrameType);
  167. enum FlvVideoCodec {
  168. FLV_VIDEO_JPEG = 1, // currently unused
  169. FLV_VIDEO_SORENSON_H263 = 2,
  170. FLV_VIDEO_SCREEN_VIDEO = 3,
  171. FLV_VIDEO_ON2_VP6 = 4,
  172. FLV_VIDEO_ON2_VP6_WITH_ALPHA_CHANNEL = 5,
  173. FLV_VIDEO_SCREEN_VIDEO_V2 = 6,
  174. FLV_VIDEO_AVC = 7,
  175. FLV_VIDEO_HEVC = 12
  176. };
  177. static const FlvVideoCodec FLV_VIDEO_UNKNOWN = (FlvVideoCodec)0;
  178. const char* FlvVideoCodec2Str(FlvVideoCodec);
  179. // The Video Message in RTMP.
  180. struct RtmpVideoMessage {
  181. uint32_t timestamp;
  182. FlvVideoFrameType frame_type;
  183. FlvVideoCodec codec;
  184. butil::IOBuf data;
  185. // True iff this message is a sequence header of AVC codec.
  186. bool IsAVCSequenceHeader() const;
  187. // True iff this message is a sequence header of HEVC(H.265) codec.
  188. bool IsHEVCSequenceHeader() const;
  189. // Size of serialized message
  190. size_t size() const { return data.size() + 1; }
  191. };
  192. std::ostream& operator<<(std::ostream&, const RtmpVideoMessage&);
  193. enum FlvAVCPacketType {
  194. FLV_AVC_PACKET_SEQUENCE_HEADER = 0,
  195. FLV_AVC_PACKET_NALU = 1,
  196. // lower level NALU sequence ender is not required or supported
  197. FLV_AVC_PACKET_END_OF_SEQUENCE = 2,
  198. };
  199. // The Video Message when codec == FLV_VIDEO_AVC
  200. struct RtmpAVCMessage {
  201. uint32_t timestamp;
  202. FlvVideoFrameType frame_type;
  203. FlvAVCPacketType packet_type;
  204. int32_t composition_time;
  205. // For sequence header: AVCDecoderConfigurationRecord
  206. // For NALU: One or more NALUs
  207. // For end of sequence: empty
  208. butil::IOBuf data;
  209. // Create a AVC message from a video message.
  210. butil::Status Create(const RtmpVideoMessage&);
  211. // Size of serialized message.
  212. size_t size() const { return data.size() + 5; }
  213. };
  214. // the profile for avc/h.264.
  215. // @see Annex A Profiles and levels, H.264-AVC-ISO_IEC_14496-10.pdf, page 205.
  216. enum AVCProfile {
  217. // @see ffmpeg, libavcodec/avcodec.h:2713
  218. AVC_PROFILE_BASELINE = 66,
  219. AVC_PROFILE_CONSTRAINED_BASELINE = 578,
  220. AVC_PROFILE_MAIN = 77,
  221. AVC_PROFILE_EXTENDED = 88,
  222. AVC_PROFILE_HIGH = 100,
  223. AVC_PROFILE_HIGH10 = 110,
  224. AVC_PROFILE_HIGH10_INTRA = 2158,
  225. AVC_PROFILE_HIGH422 = 122,
  226. AVC_PROFILE_HIGH422_INTRA = 2170,
  227. AVC_PROFILE_HIGH444 = 144,
  228. AVC_PROFILE_HIGH444_PREDICTIVE = 244,
  229. AVC_PROFILE_HIGH444_INTRA = 2192,
  230. };
  231. const char* AVCProfile2Str(AVCProfile);
  232. // the level for avc/h.264.
  233. // @see Annex A Profiles and levels, H.264-AVC-ISO_IEC_14496-10.pdf, page 207.
  234. enum AVCLevel {
  235. AVC_LEVEL_1 = 10,
  236. AVC_LEVEL_11 = 11,
  237. AVC_LEVEL_12 = 12,
  238. AVC_LEVEL_13 = 13,
  239. AVC_LEVEL_2 = 20,
  240. AVC_LEVEL_21 = 21,
  241. AVC_LEVEL_22 = 22,
  242. AVC_LEVEL_3 = 30,
  243. AVC_LEVEL_31 = 31,
  244. AVC_LEVEL_32 = 32,
  245. AVC_LEVEL_4 = 40,
  246. AVC_LEVEL_41 = 41,
  247. AVC_LEVEL_5 = 50,
  248. AVC_LEVEL_51 = 51,
  249. };
  250. // Table 7-1 - NAL unit type codes, syntax element categories, and NAL unit type classes
  251. // H.264-AVC-ISO_IEC_14496-10-2012.pdf, page 83.
  252. enum AVCNaluType {
  253. AVC_NALU_EMPTY = 0,
  254. AVC_NALU_NONIDR = 1,
  255. AVC_NALU_DATAPARTITIONA = 2,
  256. AVC_NALU_DATAPARTITIONB = 3,
  257. AVC_NALU_DATAPARTITIONC = 4,
  258. AVC_NALU_IDR = 5,
  259. AVC_NALU_SEI = 6,
  260. AVC_NALU_SPS = 7,
  261. AVC_NALU_PPS = 8,
  262. AVC_NALU_ACCESSUNITDELIMITER = 9,
  263. AVC_NALU_EOSEQUENCE = 10,
  264. AVC_NALU_EOSTREAM = 11,
  265. AVC_NALU_FILTERDATA = 12,
  266. AVC_NALU_SPSEXT = 13,
  267. AVC_NALU_PREFIXNALU = 14,
  268. AVC_NALU_SUBSETSPS = 15,
  269. AVC_NALU_LAYERWITHOUTPARTITION = 19,
  270. AVC_NALU_CODEDSLICEEXT = 20,
  271. };
  272. struct AVCDecoderConfigurationRecord {
  273. AVCDecoderConfigurationRecord();
  274. butil::Status Create(const butil::IOBuf& buf);
  275. butil::Status Create(const void* data, size_t len);
  276. int width;
  277. int height;
  278. AVCProfile avc_profile;
  279. AVCLevel avc_level;
  280. int8_t length_size_minus1;
  281. std::vector<std::string> sps_list;
  282. std::vector<std::string> pps_list;
  283. private:
  284. butil::Status ParseSPS(const butil::StringPiece& buf, size_t sps_length);
  285. };
  286. std::ostream& operator<<(std::ostream&, const AVCDecoderConfigurationRecord&);
  287. enum AVCNaluFormat {
  288. AVC_NALU_FORMAT_UNKNOWN = 0,
  289. AVC_NALU_FORMAT_ANNEXB,
  290. AVC_NALU_FORMAT_IBMF,
  291. };
  292. // Iterate NALUs inside RtmpAVCMessage.data
  293. class AVCNaluIterator {
  294. public:
  295. AVCNaluIterator(butil::IOBuf* data, uint32_t length_size_minus1,
  296. AVCNaluFormat* format_inout);
  297. ~AVCNaluIterator();
  298. void operator++();
  299. operator void*() const { return _data; }
  300. butil::IOBuf& operator*() { return _cur_nalu; }
  301. butil::IOBuf* operator->() { return &_cur_nalu; }
  302. AVCNaluType nalu_type() const { return _nalu_type; }
  303. private:
  304. // `data' is mutable, improper to be copied.
  305. DISALLOW_COPY_AND_ASSIGN(AVCNaluIterator);
  306. bool next_as_annexb();
  307. bool next_as_ibmf();
  308. void set_end() { _data = NULL; }
  309. butil::IOBuf* _data;
  310. butil::IOBuf _cur_nalu;
  311. AVCNaluFormat* _format;
  312. uint32_t _length_size_minus1;
  313. AVCNaluType _nalu_type;
  314. };
  315. // ==== Meta data ====
  316. enum RtmpObjectEncoding {
  317. RTMP_AMF0 = 0, // AMF0 object encoding supported by Flash 6 and later
  318. RTMP_AMF3 = 3, // AMF3 encoding from Flash 9 (AS3)
  319. };
  320. const char* RtmpObjectEncoding2Str(RtmpObjectEncoding);
  321. struct RtmpMetaData {
  322. uint32_t timestamp;
  323. AMFObject data;
  324. };
  325. struct RtmpCuePoint {
  326. uint32_t timestamp;
  327. AMFObject data;
  328. };
  329. enum class FlvHeaderFlags : uint8_t {
  330. VIDEO = 0x01,
  331. AUDIO = 0x04,
  332. AUDIO_AND_VIDEO = 0x05,
  333. };
  334. struct FlvWriterOptions {
  335. FlvWriterOptions() = default;
  336. FlvHeaderFlags flv_content_type = FlvHeaderFlags::AUDIO_AND_VIDEO;
  337. };
  338. struct RtmpSharedObjectMessage {
  339. // Not implemented yet.
  340. };
  341. enum FlvTagType {
  342. FLV_TAG_AUDIO = 8,
  343. FLV_TAG_VIDEO = 9,
  344. FLV_TAG_SCRIPT_DATA = 18,
  345. };
  346. class FlvWriter {
  347. public:
  348. // Start appending FLV tags into the buffer
  349. explicit FlvWriter(butil::IOBuf* buf);
  350. explicit FlvWriter(butil::IOBuf* buf, const FlvWriterOptions& options);
  351. // Append a video/audio/metadata/cuepoint message into the output buffer.
  352. butil::Status Write(const RtmpVideoMessage&);
  353. butil::Status Write(const RtmpAudioMessage&);
  354. butil::Status Write(const RtmpMetaData&);
  355. butil::Status Write(const RtmpCuePoint&);
  356. private:
  357. butil::Status WriteScriptData(const butil::IOBuf& req_buf, uint32_t timestamp);
  358. private:
  359. bool _write_header;
  360. butil::IOBuf* _buf;
  361. FlvWriterOptions _options;
  362. };
  363. class FlvReader {
  364. public:
  365. // Start reading FLV tags from the buffer. The data read by the following
  366. // Read functions would be removed from *buf.
  367. explicit FlvReader(butil::IOBuf* buf);
  368. // Get the next message type.
  369. // If it is a valid flv tag, butil::Status::OK() is returned and the
  370. // type is written to *type. Otherwise an error would be returned,
  371. // leaving *type unchanged.
  372. // Note: If error_code of the return value is EAGAIN, the caller
  373. // should wait more data and try call PeekMessageType again.
  374. butil::Status PeekMessageType(FlvTagType* type);
  375. // Read a video/audio/metadata message from the input buffer.
  376. // Caller should use the result of function PeekMessageType to select an
  377. // appropriate function, e.g., if *type is set to FLV_TAG_AUDIO in
  378. // PeekMessageType, caller should call Read(RtmpAudioMessage*) subsequently.
  379. butil::Status Read(RtmpVideoMessage* msg);
  380. butil::Status Read(RtmpAudioMessage* msg);
  381. butil::Status Read(RtmpMetaData* object, std::string* object_name);
  382. private:
  383. butil::Status ReadHeader();
  384. private:
  385. bool _read_header;
  386. butil::IOBuf* _buf;
  387. };
  388. struct RtmpPlayOptions {
  389. // [Required] Name of the stream to play.
  390. // * video (FLV) files: specify the name without a file extension,
  391. // example: "sample".
  392. // * MP3 or ID3 tags: precede the name with mp3,
  393. // example: "mp3:sample".
  394. // * H.264/AAC files: precede the name with mp4 and specify file extension.
  395. // example: "mp4:sample.m4v"
  396. std::string stream_name;
  397. // Specifies the start time in seconds.
  398. // * The default value -2 means the subscriber first tries to play the live
  399. // stream specified in `stream_name'. If alive stream of that name is not
  400. // found, it plays the recorded stream of the same name. If there is no
  401. // recorded stream with that name, the subscriber waits for a new live
  402. // stream with that name and plays it when available.
  403. // * -1: only the live stream specified in `stream_name' is played.
  404. // * 0 or a positive number: a recorded stream specified by `stream_name'
  405. // is played beginning from the time specified by this field. If no
  406. // recorded stream is found, the next item in the playlist is played.
  407. double start;
  408. // Specifies the duration of playback in seconds.
  409. // * The default value -1 means a live stream is played until it is no
  410. // longer available or a recorded stream is played until it ends.
  411. // * A negative number other than -1: interpreted as -1.
  412. // * 0: plays the single frame since the time specified in `start'
  413. // from the beginning of a recorded stream. The value of `start' is
  414. // assumed to be equal to or greater than 0.
  415. // * A positive number: plays a live stream for the time period specified
  416. // by this field. After that it becomes available or plays a recorded
  417. // stream for the time specified by this field. If a stream ends before
  418. // the time specified by `duration', playback ends when the stream ends.
  419. double duration;
  420. // Specifies whether to flush any previous playlist.
  421. bool reset;
  422. RtmpPlayOptions();
  423. };
  424. enum RtmpPublishType {
  425. // The stream is published and the data is recorded to a new file. The file
  426. // is stored on the server in a subdirectory within the directory that
  427. // contains the server application. If the file already exists, it is
  428. // overwritten.
  429. RTMP_PUBLISH_RECORD = 1,
  430. // The stream is published and the data is appended to a file. If no file
  431. // is found, it is created.
  432. RTMP_PUBLISH_APPEND,
  433. // Live data is published without recording it in a file.
  434. RTMP_PUBLISH_LIVE,
  435. };
  436. const char* RtmpPublishType2Str(RtmpPublishType);
  437. bool Str2RtmpPublishType(const butil::StringPiece&, RtmpPublishType*);
  438. // For SetPeerBandwidth
  439. enum RtmpLimitType {
  440. RTMP_LIMIT_HARD = 0,
  441. RTMP_LIMIT_SOFT = 1,
  442. RTMP_LIMIT_DYNAMIC = 2
  443. };
  444. // The common part of RtmpClientStream and RtmpServerStream.
  445. class RtmpStreamBase : public SharedObject
  446. , public Destroyable {
  447. public:
  448. explicit RtmpStreamBase(bool is_client);
  449. // @Destroyable
  450. // For ClientStream, this function must be called to end this stream no matter
  451. // Init() is called or not. Use DestroyingPtr<> which is a specialized unique_ptr
  452. // to call Destroy() automatically.
  453. // If this stream is enclosed in intrusive_ptr<>, this method can be called
  454. // before/during Init(), or multiple times, because the stream is not
  455. // destructed yet after calling Destroy(), otherwise the behavior is
  456. // undefined.
  457. virtual void Destroy();
  458. // Process media messages from the peer.
  459. // Following methods and OnStop() on the same stream are never called
  460. // simultaneously.
  461. // NOTE: Inputs can be modified and consumed.
  462. virtual void OnUserData(void* msg);
  463. virtual void OnCuePoint(RtmpCuePoint*);
  464. virtual void OnMetaData(RtmpMetaData*, const butil::StringPiece&);
  465. virtual void OnSharedObjectMessage(RtmpSharedObjectMessage* msg);
  466. virtual void OnAudioMessage(RtmpAudioMessage* msg);
  467. virtual void OnVideoMessage(RtmpVideoMessage* msg);
  468. // Will be called in the same thread before any OnMetaData/OnCuePoint
  469. // OnSharedObjectMessage/OnAudioMessage/OnVideoMessage are called.
  470. virtual void OnFirstMessage();
  471. // Called when this stream is about to be destroyed or the underlying
  472. // connection is broken. This method and above methods(OnXXX) on the
  473. // same stream are never called simultaneously.
  474. virtual void OnStop();
  475. // Send media messages to the peer.
  476. // Returns 0 on success, -1 otherwise.
  477. virtual int SendCuePoint(const RtmpCuePoint&);
  478. virtual int SendMetaData(const RtmpMetaData&,
  479. const butil::StringPiece& name = "onMetaData");
  480. virtual int SendSharedObjectMessage(const RtmpSharedObjectMessage& msg);
  481. virtual int SendAudioMessage(const RtmpAudioMessage& msg);
  482. virtual int SendAACMessage(const RtmpAACMessage& msg);
  483. virtual int SendVideoMessage(const RtmpVideoMessage& msg);
  484. virtual int SendAVCMessage(const RtmpAVCMessage& msg);
  485. // msg is owned by the caller of this function
  486. virtual int SendUserMessage(void* msg);
  487. // Send a message to the peer to make it stop. The concrete message depends
  488. // on implementation of the stream.
  489. virtual int SendStopMessage(const butil::StringPiece& error_description);
  490. // // Call user's procedure at server-side.
  491. // // request == NULL : send AMF null as the parameter.
  492. // // response == NULL : response is not needed.
  493. // // done == NULL : synchronous call, asynchronous otherwise.
  494. // void Call(Controller* cntl,
  495. // const butil::StringPiece& procedure_name,
  496. // const google::protobuf::Message* request,
  497. // google::protobuf::Message* response,
  498. // google::protobuf::Closure* done);
  499. // Get id of the message stream.
  500. uint32_t stream_id() const { return _message_stream_id; }
  501. // Get id of the chunk stream.
  502. uint32_t chunk_stream_id() const { return _chunk_stream_id; }
  503. // Get ip/port of peer/self
  504. virtual butil::EndPoint remote_side() const;
  505. virtual butil::EndPoint local_side() const;
  506. bool is_client_stream() const { return _is_client; }
  507. bool is_server_stream() const { return !_is_client; }
  508. // True iff OnStop() was called.
  509. bool is_stopped() const { return _stopped; }
  510. // When this stream is created, got from butil::gettimeofday_us().
  511. int64_t create_realtime_us() const { return _create_realtime_us; }
  512. bool is_paused() const { return _paused; }
  513. // True if OnMetaData/OnCuePoint/OnXXXMessage() was ever called.
  514. bool has_data_ever() const { return _has_data_ever; }
  515. // The underlying socket for reading/writing.
  516. Socket* socket() { return _rtmpsock.get(); }
  517. const Socket* socket() const { return _rtmpsock.get(); }
  518. // Returns true when the server accepted play or publish command.
  519. // The acquire fence makes sure the callsite seeing true must be after
  520. // sending play or publish command (possibly in another thread).
  521. bool is_server_accepted() const
  522. { return _is_server_accepted.load(butil::memory_order_acquire); }
  523. // Explicitly notify error to current stream
  524. virtual void SignalError();
  525. protected:
  526. friend class policy::RtmpContext;
  527. friend class policy::RtmpChunkStream;
  528. friend class policy::OnServerStreamCreated;
  529. virtual ~RtmpStreamBase();
  530. int SendMessage(uint32_t timestamp, uint8_t message_type,
  531. const butil::IOBuf& body);
  532. int SendControlMessage(uint8_t message_type, const void* body, size_t);
  533. // OnStop is mutually exclusive with OnXXXMessage, following methods
  534. // implement the exclusion.
  535. bool BeginProcessingMessage(const char* fun_name);
  536. void EndProcessingMessage();
  537. void CallOnUserData(void* data);
  538. void CallOnCuePoint(RtmpCuePoint*);
  539. void CallOnMetaData(RtmpMetaData*, const butil::StringPiece&);
  540. void CallOnSharedObjectMessage(RtmpSharedObjectMessage* msg);
  541. void CallOnAudioMessage(RtmpAudioMessage* msg);
  542. void CallOnVideoMessage(RtmpVideoMessage* msg);
  543. void CallOnStop();
  544. bool _is_client;
  545. bool _paused; // Only used by RtmpServerStream
  546. bool _stopped; // True when OnStop() was called.
  547. bool _processing_msg; // True when OnXXXMessage/OnMetaData/OnCuePoint are called.
  548. bool _has_data_ever;
  549. uint32_t _message_stream_id;
  550. uint32_t _chunk_stream_id;
  551. int64_t _create_realtime_us;
  552. SocketUniquePtr _rtmpsock;
  553. butil::Mutex _call_mutex;
  554. butil::atomic<bool> _is_server_accepted;
  555. };
  556. struct RtmpClientOptions {
  557. // Constructed with default options.
  558. RtmpClientOptions();
  559. // The Server application name the client is connected to.
  560. std::string app;
  561. // Flash Player version. It is the same string as returned by the
  562. // ApplicationScript getversion () function.
  563. std::string flashVer;
  564. // URL of the source SWF file making the connection.
  565. std::string swfUrl;
  566. // URL of the Server. It has the following format:
  567. // protocol://servername:port/appName/appInstance
  568. std::string tcUrl;
  569. // True if proxy is being used.
  570. bool fpad;
  571. // Indicates what audio codecs the client supports.
  572. RtmpAudioCodec audioCodecs;
  573. // Indicates what video codecs are supported.
  574. RtmpVideoCodec videoCodecs;
  575. // Indicates what special video functions are supported.
  576. RtmpVideoFunction videoFunction;
  577. // URL of the web page from where the SWF file was loaded.
  578. std::string pageUrl;
  579. // =======================================================
  580. // Following fields are not part of on-wire RTMP data.
  581. // Timeout(in milliseconds) for creating a stream.
  582. // Default: 1000
  583. int32_t timeout_ms;
  584. // Timeout(in milliseconds) for creating a stream.
  585. // Default: 500
  586. int32_t connect_timeout_ms;
  587. // Value of SetBufferLength sent after Play.
  588. // Default: 1000
  589. uint32_t buffer_length_ms;
  590. // Value of SetChunkSize sent after Play.
  591. // Default: 60000
  592. uint32_t chunk_size;
  593. // Value of WindowAckSize sent after connect message.
  594. // Default: 2500000
  595. uint32_t window_ack_size;
  596. // Indicates whether to use simplified rtmp protocol or not.
  597. // The process of handshaking and connection will be reduced to 0
  598. // RTT by client directly sending a magic number, Connect command
  599. // and CreateStream command to server. Server receiving this magic
  600. // number should recognize it as the beginning of simplified rtmp
  601. // protocol, skip regular handshaking process and change its state
  602. // as if the handshaking has already completed.
  603. // Default: false;
  604. bool simplified_rtmp;
  605. };
  606. // Represent the communication line to one or multiple RTMP servers.
  607. // Notice this does NOT correspond to the "NetConnection" in AS which
  608. // only stands for one server.
  609. class RtmpClient {
  610. public:
  611. RtmpClient();
  612. ~RtmpClient();
  613. RtmpClient(const RtmpClient&);
  614. RtmpClient& operator=(const RtmpClient&);
  615. // Specify the servers to connect.
  616. int Init(butil::EndPoint server_addr_and_port,
  617. const RtmpClientOptions& options);
  618. int Init(const char* server_addr_and_port,
  619. const RtmpClientOptions& options);
  620. int Init(const char* server_addr, int port,
  621. const RtmpClientOptions& options);
  622. int Init(const char* naming_service_url,
  623. const char* load_balancer_name,
  624. const RtmpClientOptions& options);
  625. // True if Init() was successfully called.
  626. bool initialized() const;
  627. const RtmpClientOptions& options() const;
  628. void swap(RtmpClient& other) { _impl.swap(other._impl); }
  629. private:
  630. friend class RtmpClientStream;
  631. butil::intrusive_ptr<RtmpClientImpl> _impl;
  632. };
  633. struct RtmpHashCode {
  634. RtmpHashCode() : _has_hash_code(false), _hash_code(0) {}
  635. void operator=(uint32_t hash_code) {
  636. _has_hash_code = true;
  637. _hash_code = hash_code;
  638. }
  639. operator uint32_t() const { return _hash_code; }
  640. bool has_been_set() const { return _has_hash_code; }
  641. private:
  642. bool _has_hash_code;
  643. uint32_t _hash_code;
  644. };
  645. struct RtmpClientStreamOptions {
  646. // Reuse the same RTMP connection if possible.
  647. // Default: true;
  648. bool share_connection;
  649. // Init() blocks until play or publish is sent.
  650. // Default: false
  651. bool wait_until_play_or_publish_is_sent;
  652. // Max #retries for creating the stream.
  653. // Default: 3
  654. int create_stream_max_retry;
  655. // stream name for play command.
  656. std::string play_name;
  657. // stream name and type for publish command.
  658. std::string publish_name;
  659. RtmpPublishType publish_type; // default: RTMP_PUBLISH_LIVE
  660. // The hash code for consistent hashing load balancer.
  661. RtmpHashCode hash_code;
  662. RtmpClientStreamOptions();
  663. const std::string& stream_name() const
  664. { return !publish_name.empty() ? publish_name : play_name; }
  665. };
  666. // Represent a "NetStream" in AS. Multiple streams can be multiplexed
  667. // into one TCP connection.
  668. class RtmpClientStream : public RtmpStreamBase
  669. , public StreamCreator
  670. , public StreamUserData {
  671. public:
  672. RtmpClientStream();
  673. void Destroy() override;
  674. // Create this stream on `client' according to `options'.
  675. // If any error occurred during initialization, OnStop() will be called.
  676. // If this stream is enclosed in intrusive_ptr<> and:
  677. // - Destroy() was called before, Init() will return immediately.
  678. // - Destroy() is called during creation of the stream, the process will
  679. // be cancelled and OnStop() will be called soon.
  680. void Init(const RtmpClient* client, const RtmpClientStreamOptions& options);
  681. // Change bitrate.
  682. int Play2(const RtmpPlay2Options&);
  683. // Seek the offset (in milliseconds) within a media file or playlist.
  684. int Seek(double offset_ms);
  685. int Pause(bool pause_or_unpause, double offset_ms);
  686. // The options passed to Init()
  687. const RtmpClientStreamOptions& options() const { return _options; }
  688. // In form of "rtmp://HOST/APP/STREAM_NAME"
  689. std::string rtmp_url() const;
  690. protected:
  691. virtual ~RtmpClientStream();
  692. private:
  693. friend class policy::RtmpChunkStream;
  694. friend class policy::OnServerStreamCreated;
  695. friend class OnClientStreamCreated;
  696. friend class RtmpRetryingClientStream;
  697. int Play(const RtmpPlayOptions& opt);
  698. int Publish(const butil::StringPiece& name, RtmpPublishType type);
  699. // @StreamCreator
  700. StreamUserData* OnCreatingStream(SocketUniquePtr* inout, Controller* cntl) override;
  701. void DestroyStreamCreator(Controller* cntl) override;
  702. // @StreamUserData
  703. void DestroyStreamUserData(SocketUniquePtr& sending_sock,
  704. Controller* cntl,
  705. int error_code,
  706. bool end_of_rpc) override;
  707. void OnFailedToCreateStream();
  708. static int RunOnFailed(bthread_id_t id, void* data, int);
  709. void OnStopInternal();
  710. // Called when the stream received a status message. Server may send status
  711. // messages back to client for publish/seek/pause etc commands.
  712. void OnStatus(const RtmpInfo& info);
  713. // The Destroy() w/o dereference _self_ref, to be called internally by
  714. // client stream self.
  715. void SignalError() override;
  716. butil::intrusive_ptr<RtmpClientImpl> _client_impl;
  717. butil::intrusive_ptr<RtmpClientStream> _self_ref;
  718. bthread_id_t _onfail_id;
  719. CallId _create_stream_rpc_id;
  720. bool _from_socketmap;
  721. bool _created_stream_with_play_or_publish;
  722. enum State {
  723. STATE_UNINITIALIZED,
  724. STATE_CREATING,
  725. STATE_CREATED,
  726. STATE_ERROR,
  727. STATE_DESTROYING,
  728. };
  729. State _state;
  730. butil::Mutex _state_mutex;
  731. RtmpClientStreamOptions _options;
  732. };
  733. struct RtmpRetryingClientStreamOptions : public RtmpClientStreamOptions {
  734. // Wait for at least so many milliseconds before next retry.
  735. // Default: 1000
  736. int retry_interval_ms;
  737. // >0: Retry for so many milliseconds approximately.
  738. // 0: Never retry.
  739. // -1: Infinite retries.
  740. // Default: -1
  741. int max_retry_duration_ms;
  742. // Retry so many times without any delay between consecutive retries.
  743. // (controlled by retry_interval_ms)
  744. // Default: 2
  745. int fast_retry_count;
  746. // Stop retrying when ALL created streams fail before playing or
  747. // publishing any data. "ALL" = max(fast_retry_count, 1)
  748. // In most scenarios, this option should be true which may stop
  749. // pointless retries.
  750. // Default: true
  751. bool quit_when_no_data_ever;
  752. RtmpRetryingClientStreamOptions();
  753. };
  754. // Base class for handling the messages received by a SubStream
  755. class RtmpMessageHandler {
  756. public:
  757. virtual void OnPlayable() = 0;
  758. virtual void OnUserData(void*) = 0;
  759. virtual void OnCuePoint(brpc::RtmpCuePoint* cuepoint) = 0;
  760. virtual void OnMetaData(brpc::RtmpMetaData* metadata, const butil::StringPiece& name) = 0;
  761. virtual void OnAudioMessage(brpc::RtmpAudioMessage* msg) = 0;
  762. virtual void OnVideoMessage(brpc::RtmpVideoMessage* msg) = 0;
  763. virtual void OnSharedObjectMessage(RtmpSharedObjectMessage* msg) = 0;
  764. virtual void OnSubStreamStop(RtmpStreamBase* sub_stream) = 0;
  765. virtual ~RtmpMessageHandler() {}
  766. };
  767. class RtmpRetryingClientStream;
  768. // RtmpMessageHandler for RtmpRetryingClientStream
  769. class RetryingClientMessageHandler : public RtmpMessageHandler {
  770. public:
  771. RetryingClientMessageHandler(RtmpRetryingClientStream* parent);
  772. ~RetryingClientMessageHandler() {}
  773. void OnPlayable();
  774. void OnUserData(void*);
  775. void OnCuePoint(brpc::RtmpCuePoint* cuepoint);
  776. void OnMetaData(brpc::RtmpMetaData* metadata, const butil::StringPiece& name);
  777. void OnAudioMessage(brpc::RtmpAudioMessage* msg);
  778. void OnVideoMessage(brpc::RtmpVideoMessage* msg);
  779. void OnSharedObjectMessage(RtmpSharedObjectMessage* msg);
  780. void OnSubStreamStop(RtmpStreamBase* sub_stream);
  781. private:
  782. butil::intrusive_ptr<RtmpRetryingClientStream> _parent;
  783. };
  784. class SubStreamCreator {
  785. public:
  786. // Create a new SubStream and use *message_handler to handle messages from
  787. // the current SubStream. *sub_stream is set iff the creation is successful.
  788. // Note: message_handler is OWNED by this creator and deleted by the creator.
  789. virtual void NewSubStream(RtmpMessageHandler* message_handler,
  790. butil::intrusive_ptr<RtmpStreamBase>* sub_stream) = 0;
  791. // Do the Initialization of sub_stream. If an error happens, sub_stream->Destroy()
  792. // would be called.
  793. // Note: sub_stream is not OWNED by the creator.
  794. virtual void LaunchSubStream(RtmpStreamBase* sub_stream,
  795. RtmpRetryingClientStreamOptions* options) = 0;
  796. virtual ~SubStreamCreator() {}
  797. };
  798. class RtmpRetryingClientStream : public RtmpStreamBase {
  799. public:
  800. RtmpRetryingClientStream();
  801. // Must be called to end this stream no matter Init() is called or not.
  802. void Destroy();
  803. // Initialize this stream with the given sub_stream_creator which may create a
  804. // different sub stream each time.
  805. // NOTE: sub_stream_creator is OWNED by this stream and deleted by this stream.
  806. void Init(SubStreamCreator* sub_stream_creator,
  807. const RtmpRetryingClientStreamOptions& options);
  808. // @RtmpStreamBase
  809. // If the stream is recreated, following methods may return -1 and set
  810. // errno to ERTMPPUBLISHABLE for once. (so that users can be notified to
  811. // resend metadata or header messages).
  812. int SendCuePoint(const RtmpCuePoint&);
  813. int SendMetaData(const RtmpMetaData&,
  814. const butil::StringPiece& name = "onMetaData");
  815. int SendSharedObjectMessage(const RtmpSharedObjectMessage& msg);
  816. int SendAudioMessage(const RtmpAudioMessage& msg);
  817. int SendAACMessage(const RtmpAACMessage& msg);
  818. int SendVideoMessage(const RtmpVideoMessage& msg);
  819. int SendAVCMessage(const RtmpAVCMessage& msg);
  820. butil::EndPoint remote_side() const;
  821. butil::EndPoint local_side() const;
  822. // Call this function to stop current stream. New sub stream will be
  823. // tried to be created later.
  824. void StopCurrentStream();
  825. // If a sub stream was created, this method will be called in the same
  826. // thread before any OnMetaData/OnCuePoint/OnSharedObjectMessage/OnAudioMessage/
  827. // OnVideoMessage are called.
  828. virtual void OnPlayable();
  829. const RtmpRetryingClientStreamOptions& options() const { return _options; }
  830. protected:
  831. ~RtmpRetryingClientStream();
  832. private:
  833. friend class RetryingClientMessageHandler;
  834. void OnSubStreamStop(RtmpStreamBase* sub_stream);
  835. int AcquireStreamToSend(butil::intrusive_ptr<RtmpStreamBase>*);
  836. static void OnRecreateTimer(void* arg);
  837. void Recreate();
  838. void CallOnStopIfNeeded();
  839. butil::intrusive_ptr<RtmpStreamBase> _using_sub_stream;
  840. butil::intrusive_ptr<RtmpRetryingClientStream> _self_ref;
  841. mutable butil::Mutex _stream_mutex;
  842. RtmpRetryingClientStreamOptions _options;
  843. butil::atomic<bool> _destroying;
  844. butil::atomic<bool> _called_on_stop;
  845. bool _changed_stream;
  846. bool _has_timer_ever;
  847. bool _is_server_accepted_ever;
  848. int _num_fast_retries;
  849. int64_t _last_creation_time_us;
  850. int64_t _last_retry_start_time_us;
  851. bthread_timer_t _create_timer_id;
  852. // Note: RtmpClient can be efficiently copied.
  853. RtmpClient _client_copy;
  854. SubStreamCreator* _sub_stream_creator;
  855. };
  856. // Utility function to get components from rtmp_url which could be in forms of:
  857. // rtmp://HOST/APP/STREAM_NAME
  858. // rtmp://HOST/APP (empty stream_name)
  859. // rtmp://HOST (empty app and stream_name)
  860. // rtmp://HOST/APP?vhost=.../STREAM_NAME (This is how SRS put vhost in URL)
  861. // "rtmp://" can be ignored.
  862. // NOTE: query strings after stream_name is not removed and returned as part
  863. // of stream_name.
  864. void ParseRtmpURL(const butil::StringPiece& rtmp_url,
  865. butil::StringPiece* host,
  866. butil::StringPiece* vhost_after_app,
  867. butil::StringPiece* port,
  868. butil::StringPiece* app,
  869. butil::StringPiece* stream_name);
  870. void ParseRtmpHostAndPort(const butil::StringPiece& host_and_port,
  871. butil::StringPiece* host,
  872. butil::StringPiece* port);
  873. butil::StringPiece RemoveQueryStrings(const butil::StringPiece& stream_name,
  874. butil::StringPiece* query_strings);
  875. // Returns "rtmp://HOST/APP/STREAM_NAME"
  876. std::string MakeRtmpURL(const butil::StringPiece& host,
  877. const butil::StringPiece& port,
  878. const butil::StringPiece& app,
  879. const butil::StringPiece& stream_name);
  880. // Returns url removed with beginning "rtmp://".
  881. butil::StringPiece RemoveRtmpPrefix(const butil::StringPiece& url);
  882. // Returns url removed with beginning "xxx://"
  883. butil::StringPiece RemoveProtocolPrefix(const butil::StringPiece& url);
  884. // Implement this class and assign an instance to ServerOption.rtmp_service
  885. // to enable RTMP support.
  886. class RtmpService {
  887. public:
  888. virtual ~RtmpService() {}
  889. // Called when receiving a Pong response from `remote_side'.
  890. virtual void OnPingResponse(const butil::EndPoint& remote_side,
  891. uint32_t ping_timestamp);
  892. // Called to create a server-side stream.
  893. virtual RtmpServerStream* NewStream(const RtmpConnectRequest&) = 0;
  894. private:
  895. friend class StatusService;
  896. friend class policy::RtmpChunkStream;
  897. };
  898. // Represent the "NetStream" on server-side.
  899. class RtmpServerStream : public RtmpStreamBase {
  900. public:
  901. RtmpServerStream();
  902. ~RtmpServerStream();
  903. // Called when receiving a play request.
  904. // Call status->set_error() when the play request is rejected.
  905. // Call done->Run() when the play request is processed (either accepted
  906. // or rejected)
  907. virtual void OnPlay(const RtmpPlayOptions&,
  908. butil::Status* status,
  909. google::protobuf::Closure* done);
  910. // Called when receiving a publish request.
  911. // Call status->set_error() when the publish request is rejected.
  912. // Call done->Run() when the publish request is processed (either accepted
  913. // Returns 0 on success, -1 otherwise.
  914. virtual void OnPublish(const std::string& stream_name,
  915. RtmpPublishType publish_type,
  916. butil::Status* status,
  917. google::protobuf::Closure* done);
  918. // Called when receiving a play2 request.
  919. virtual void OnPlay2(const RtmpPlay2Options&);
  920. // Called when receiving a seek request.
  921. // Returns 0 on success, -1 otherwise.
  922. virtual int OnSeek(double offset_ms);
  923. // Called when receiving a pause/unpause request.
  924. // Returns 0 on success, -1 otherwise.
  925. virtual int OnPause(bool pause_or_unpause, double offset_ms);
  926. // Called when receiving information from Rtmp client on buffer size (in
  927. // milliseconds) that is used to buffer any data coming over a stream.
  928. // This event is sent before the server starts processing the stream.
  929. virtual void OnSetBufferLength(uint32_t buffer_length_ms);
  930. // @RtmpStreamBase, sending StreamNotFound
  931. int SendStopMessage(const butil::StringPiece& error_description);
  932. void Destroy();
  933. private:
  934. friend class policy::RtmpContext;
  935. friend class policy::RtmpChunkStream;
  936. int SendStreamDry();
  937. static int RunOnFailed(bthread_id_t id, void* data, int);
  938. void OnStopInternal();
  939. // Indicating the client supports multiple streams over one connection.
  940. bool _client_supports_stream_multiplexing;
  941. bool _is_publish;
  942. bthread_id_t _onfail_id;
  943. };
  944. } // namespace brpc
  945. #endif // BRPC_RTMP_H