winlin

basic media cache framework

@@ -86,7 +86,7 @@ MODULE_FILES=("srs_core" "srs_core_log" "srs_core_server" @@ -86,7 +86,7 @@ MODULE_FILES=("srs_core" "srs_core_log" "srs_core_server"
86 "srs_core_error" "srs_core_conn" "srs_core_client" 86 "srs_core_error" "srs_core_conn" "srs_core_client"
87 "srs_core_rtmp" "srs_core_socket" "srs_core_buffer" 87 "srs_core_rtmp" "srs_core_socket" "srs_core_buffer"
88 "srs_core_auto_free" "srs_core_protocol" "srs_core_amf0" 88 "srs_core_auto_free" "srs_core_protocol" "srs_core_amf0"
89 - "srs_core_stream") 89 + "srs_core_stream" "srs_core_source")
90 MODULE_DIR="src/core" . auto/modules.sh 90 MODULE_DIR="src/core" . auto/modules.sh
91 CORE_OBJS="${MODULE_OBJS[@]}" 91 CORE_OBJS="${MODULE_OBJS[@]}"
92 92
@@ -30,6 +30,10 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -30,6 +30,10 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 #include <srs_core_rtmp.hpp> 30 #include <srs_core_rtmp.hpp>
31 #include <srs_core_protocol.hpp> 31 #include <srs_core_protocol.hpp>
32 #include <srs_core_auto_free.hpp> 32 #include <srs_core_auto_free.hpp>
  33 +#include <srs_core_source.hpp>
  34 +
  35 +// wait for client message.
  36 +#define SRS_PULSE_TIME_MS 100
33 37
34 SrsClient::SrsClient(SrsServer* srs_server, st_netfd_t client_stfd) 38 SrsClient::SrsClient(SrsServer* srs_server, st_netfd_t client_stfd)
35 : SrsConnection(srs_server, client_stfd) 39 : SrsConnection(srs_server, client_stfd)
@@ -113,6 +117,11 @@ int SrsClient::do_cycle() @@ -113,6 +117,11 @@ int SrsClient::do_cycle()
113 } 117 }
114 srs_verbose("set chunk size success"); 118 srs_verbose("set chunk size success");
115 119
  120 + // find a source to publish.
  121 + SrsSource* source = SrsSource::find(req->get_stream_url());
  122 + srs_assert(source != NULL);
  123 + srs_info("source found, url=%s", req->get_stream_url().c_str());
  124 +
116 switch (type) { 125 switch (type) {
117 case SrsClientPlay: { 126 case SrsClientPlay: {
118 srs_verbose("start to play stream %s.", req->stream.c_str()); 127 srs_verbose("start to play stream %s.", req->stream.c_str());
@@ -122,7 +131,7 @@ int SrsClient::do_cycle() @@ -122,7 +131,7 @@ int SrsClient::do_cycle()
122 return ret; 131 return ret;
123 } 132 }
124 srs_info("start to play stream %s success", req->stream.c_str()); 133 srs_info("start to play stream %s success", req->stream.c_str());
125 - return streaming_play(); 134 + return streaming_play(source);
126 } 135 }
127 case SrsClientPublish: { 136 case SrsClientPublish: {
128 srs_verbose("start to publish stream %s.", req->stream.c_str()); 137 srs_verbose("start to publish stream %s.", req->stream.c_str());
@@ -132,7 +141,7 @@ int SrsClient::do_cycle() @@ -132,7 +141,7 @@ int SrsClient::do_cycle()
132 return ret; 141 return ret;
133 } 142 }
134 srs_info("start to publish stream %s success", req->stream.c_str()); 143 srs_info("start to publish stream %s success", req->stream.c_str());
135 - return streaming_publish(); 144 + return streaming_publish(source);
136 } 145 }
137 default: { 146 default: {
138 ret = ERROR_SYSTEM_CLIENT_INVALID; 147 ret = ERROR_SYSTEM_CLIENT_INVALID;
@@ -144,13 +153,58 @@ int SrsClient::do_cycle() @@ -144,13 +153,58 @@ int SrsClient::do_cycle()
144 return ret; 153 return ret;
145 } 154 }
146 155
147 -int SrsClient::streaming_play() 156 +int SrsClient::streaming_play(SrsSource* source)
148 { 157 {
149 int ret = ERROR_SUCCESS; 158 int ret = ERROR_SUCCESS;
  159 +
  160 + SrsConsumer* consumer = source->create_consumer();
  161 + srs_assert(consumer != NULL);
  162 + SrsAutoFree(SrsConsumer, consumer, false);
  163 + srs_verbose("consumer created.");
  164 +
  165 + while (true) {
  166 + bool ready = false;
  167 + if ((ret = rtmp->can_read(SRS_PULSE_TIME_MS, ready)) != ERROR_SUCCESS) {
  168 + srs_error("wait client control message failed. ret=%d", ret);
  169 + return ret;
  170 + }
  171 + srs_verbose("client pulse %dms, ready=%d", SRS_PULSE_TIME_MS, ready);
  172 +
  173 + // read from client.
  174 + if (ready) {
  175 + SrsMessage* msg = NULL;
  176 + if ((ret = rtmp->recv_message(&msg)) != ERROR_SUCCESS) {
  177 + srs_error("recv client control message failed. ret=%d", ret);
  178 + return ret;
  179 + }
  180 +
  181 + SrsAutoFree(SrsMessage, msg, false);
  182 + // TODO: process it.
  183 + }
  184 +
  185 + // get messages from consumer.
  186 + SrsMessage** msgs = NULL;
  187 + int count = 0;
  188 + if ((ret = consumer->get_packets(0, msgs, count)) != ERROR_SUCCESS) {
  189 + srs_error("get messages from consumer failed. ret=%d", ret);
  190 + return ret;
  191 + }
  192 + SrsAutoFree(SrsMessage*, msgs, true);
  193 +
  194 + // sendout messages
  195 + for (int i = 0; i < count; i++) {
  196 + SrsMessage* msg = msgs[i];
  197 + if ((ret = rtmp->send_message(msg)) != ERROR_SUCCESS) {
  198 + srs_error("send message to client failed. ret=%d", ret);
  199 + return ret;
  200 + }
  201 + }
  202 + }
  203 +
150 return ret; 204 return ret;
151 } 205 }
152 206
153 -int SrsClient::streaming_publish() 207 +int SrsClient::streaming_publish(SrsSource* source)
154 { 208 {
155 int ret = ERROR_SUCCESS; 209 int ret = ERROR_SUCCESS;
156 210
@@ -163,6 +217,17 @@ int SrsClient::streaming_publish() @@ -163,6 +217,17 @@ int SrsClient::streaming_publish()
163 217
164 SrsAutoFree(SrsMessage, msg, false); 218 SrsAutoFree(SrsMessage, msg, false);
165 219
  220 + // process audio packet
  221 + if (msg->header.is_audio() && ((ret = source->on_audio(msg)) != ERROR_SUCCESS)) {
  222 + srs_error("process audio message failed. ret=%d", ret);
  223 + return ret;
  224 + }
  225 + // process video packet
  226 + if (msg->header.is_video() && ((ret = source->on_video(msg)) != ERROR_SUCCESS)) {
  227 + srs_error("process video message failed. ret=%d", ret);
  228 + return ret;
  229 + }
  230 +
166 // process onMetaData 231 // process onMetaData
167 if (msg->header.is_amf0_data() || msg->header.is_amf3_data()) { 232 if (msg->header.is_amf0_data() || msg->header.is_amf3_data()) {
168 if ((ret = msg->decode_packet()) != ERROR_SUCCESS) { 233 if ((ret = msg->decode_packet()) != ERROR_SUCCESS) {
@@ -173,6 +238,12 @@ int SrsClient::streaming_publish() @@ -173,6 +238,12 @@ int SrsClient::streaming_publish()
173 SrsPacket* pkt = msg->get_packet(); 238 SrsPacket* pkt = msg->get_packet();
174 if (dynamic_cast<SrsOnMetaDataPacket*>(pkt)) { 239 if (dynamic_cast<SrsOnMetaDataPacket*>(pkt)) {
175 SrsOnMetaDataPacket* metadata = dynamic_cast<SrsOnMetaDataPacket*>(pkt); 240 SrsOnMetaDataPacket* metadata = dynamic_cast<SrsOnMetaDataPacket*>(pkt);
  241 + if ((ret = source->on_meta_data(metadata)) != ERROR_SUCCESS) {
  242 + srs_error("process onMetaData message failed. ret=%d", ret);
  243 + return ret;
  244 + }
  245 + srs_trace("process onMetaData message success.");
  246 + continue;
176 } 247 }
177 248
178 srs_trace("ignore AMF0/AMF3 data message."); 249 srs_trace("ignore AMF0/AMF3 data message.");
@@ -35,6 +35,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -35,6 +35,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
35 class SrsRtmp; 35 class SrsRtmp;
36 class SrsRequest; 36 class SrsRequest;
37 class SrsResponse; 37 class SrsResponse;
  38 +class SrsSource;
38 39
39 /** 40 /**
40 * the client provides the main logic control for RTMP clients. 41 * the client provides the main logic control for RTMP clients.
@@ -52,8 +53,8 @@ public: @@ -52,8 +53,8 @@ public:
52 protected: 53 protected:
53 virtual int do_cycle(); 54 virtual int do_cycle();
54 private: 55 private:
55 - virtual int streaming_play();  
56 - virtual int streaming_publish(); 56 + virtual int streaming_play(SrsSource* source);
  57 + virtual int streaming_publish(SrsSource* source);
57 virtual int get_peer_ip(); 58 virtual int get_peer_ip();
58 }; 59 };
59 60
@@ -48,6 +48,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -48,6 +48,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
48 #define ERROR_SOCKET_READ 207 48 #define ERROR_SOCKET_READ 207
49 #define ERROR_SOCKET_READ_FULLY 208 49 #define ERROR_SOCKET_READ_FULLY 208
50 #define ERROR_SOCKET_WRITE 209 50 #define ERROR_SOCKET_WRITE 209
  51 +#define ERROR_SOCKET_WAIT 210
51 52
52 #define ERROR_RTMP_PLAIN_REQUIRED 300 53 #define ERROR_RTMP_PLAIN_REQUIRED 300
53 #define ERROR_RTMP_CHUNK_START 301 54 #define ERROR_RTMP_CHUNK_START 301
@@ -273,6 +273,11 @@ SrsProtocol::~SrsProtocol() @@ -273,6 +273,11 @@ SrsProtocol::~SrsProtocol()
273 srs_freep(skt); 273 srs_freep(skt);
274 } 274 }
275 275
  276 +int SrsProtocol::can_read(int timeout_ms, bool& ready)
  277 +{
  278 + return skt->can_read(timeout_ms, ready);
  279 +}
  280 +
276 int SrsProtocol::recv_message(SrsMessage** pmsg) 281 int SrsProtocol::recv_message(SrsMessage** pmsg)
277 { 282 {
278 *pmsg = NULL; 283 *pmsg = NULL;
@@ -858,6 +863,16 @@ SrsMessageHeader::~SrsMessageHeader() @@ -858,6 +863,16 @@ SrsMessageHeader::~SrsMessageHeader()
858 { 863 {
859 } 864 }
860 865
  866 +bool SrsMessageHeader::is_audio()
  867 +{
  868 + return message_type == RTMP_MSG_AudioMessage;
  869 +}
  870 +
  871 +bool SrsMessageHeader::is_video()
  872 +{
  873 + return message_type == RTMP_MSG_VideoMessage;
  874 +}
  875 +
861 bool SrsMessageHeader::is_amf0_command() 876 bool SrsMessageHeader::is_amf0_command()
862 { 877 {
863 return message_type == RTMP_MSG_AMF0CommandMessage; 878 return message_type == RTMP_MSG_AMF0CommandMessage;
@@ -94,6 +94,10 @@ public: @@ -94,6 +94,10 @@ public:
94 virtual ~SrsProtocol(); 94 virtual ~SrsProtocol();
95 public: 95 public:
96 /** 96 /**
  97 + * whether the peer can read.
  98 + */
  99 + virtual int can_read(int timeout_ms, bool& ready);
  100 + /**
97 * recv a message with raw/undecoded payload from peer. 101 * recv a message with raw/undecoded payload from peer.
98 * the payload is not decoded, use srs_rtmp_expect_message<T> if requires 102 * the payload is not decoded, use srs_rtmp_expect_message<T> if requires
99 * specifies message. 103 * specifies message.
@@ -179,6 +183,8 @@ struct SrsMessageHeader @@ -179,6 +183,8 @@ struct SrsMessageHeader
179 SrsMessageHeader(); 183 SrsMessageHeader();
180 virtual ~SrsMessageHeader(); 184 virtual ~SrsMessageHeader();
181 185
  186 + bool is_audio();
  187 + bool is_video();
182 bool is_amf0_command(); 188 bool is_amf0_command();
183 bool is_amf0_data(); 189 bool is_amf0_data();
184 bool is_amf3_command(); 190 bool is_amf3_command();
@@ -112,6 +112,16 @@ int SrsRequest::discovery_app() @@ -112,6 +112,16 @@ int SrsRequest::discovery_app()
112 return ret; 112 return ret;
113 } 113 }
114 114
  115 +std::string SrsRequest::get_stream_url()
  116 +{
  117 + std::string url = vhost;
  118 +
  119 + url += app;
  120 + url += stream;
  121 +
  122 + return url;
  123 +}
  124 +
115 SrsResponse::SrsResponse() 125 SrsResponse::SrsResponse()
116 { 126 {
117 stream_id = SRS_DEFAULT_SID; 127 stream_id = SRS_DEFAULT_SID;
@@ -132,6 +142,21 @@ SrsRtmp::~SrsRtmp() @@ -132,6 +142,21 @@ SrsRtmp::~SrsRtmp()
132 srs_freep(protocol); 142 srs_freep(protocol);
133 } 143 }
134 144
  145 +int SrsRtmp::recv_message(SrsMessage** pmsg)
  146 +{
  147 + return protocol->recv_message(pmsg);
  148 +}
  149 +
  150 +int SrsRtmp::can_read(int timeout_ms, bool& ready)
  151 +{
  152 + return protocol->can_read(timeout_ms, ready);
  153 +}
  154 +
  155 +int SrsRtmp::send_message(SrsMessage* msg)
  156 +{
  157 + return protocol->send_message(msg);
  158 +}
  159 +
135 int SrsRtmp::handshake() 160 int SrsRtmp::handshake()
136 { 161 {
137 int ret = ERROR_SUCCESS; 162 int ret = ERROR_SUCCESS;
@@ -178,11 +203,6 @@ int SrsRtmp::handshake() @@ -178,11 +203,6 @@ int SrsRtmp::handshake()
178 return ret; 203 return ret;
179 } 204 }
180 205
181 -int SrsRtmp::recv_message(SrsMessage** pmsg)  
182 -{  
183 - return protocol->recv_message(pmsg);  
184 -}  
185 -  
186 int SrsRtmp::connect_app(SrsRequest* req) 206 int SrsRtmp::connect_app(SrsRequest* req)
187 { 207 {
188 int ret = ERROR_SUCCESS; 208 int ret = ERROR_SUCCESS;
@@ -62,6 +62,7 @@ struct SrsRequest @@ -62,6 +62,7 @@ struct SrsRequest
62 * disconvery vhost/app from tcUrl. 62 * disconvery vhost/app from tcUrl.
63 */ 63 */
64 virtual int discovery_app(); 64 virtual int discovery_app();
  65 + virtual std::string get_stream_url();
65 }; 66 };
66 67
67 /** 68 /**
@@ -99,8 +100,11 @@ public: @@ -99,8 +100,11 @@ public:
99 SrsRtmp(st_netfd_t client_stfd); 100 SrsRtmp(st_netfd_t client_stfd);
100 virtual ~SrsRtmp(); 101 virtual ~SrsRtmp();
101 public: 102 public:
102 - virtual int handshake();  
103 virtual int recv_message(SrsMessage** pmsg); 103 virtual int recv_message(SrsMessage** pmsg);
  104 + virtual int can_read(int timeout_ms, bool& ready);
  105 + virtual int send_message(SrsMessage* msg);
  106 +public:
  107 + virtual int handshake();
104 virtual int connect_app(SrsRequest* req); 108 virtual int connect_app(SrsRequest* req);
105 virtual int set_window_ack_size(int ack_size); 109 virtual int set_window_ack_size(int ack_size);
106 /** 110 /**
@@ -34,6 +34,26 @@ SrsSocket::~SrsSocket() @@ -34,6 +34,26 @@ SrsSocket::~SrsSocket()
34 { 34 {
35 } 35 }
36 36
  37 +int SrsSocket::can_read(int timeout_ms, bool& ready)
  38 +{
  39 + ready = false;
  40 + int ret = ERROR_SUCCESS;
  41 +
  42 + // If the named file descriptor object is ready for I/O within the specified amount of time,
  43 + // a value of 0 is returned. Otherwise, a value of -1 is returned and errno is set to
  44 + // indicate the error
  45 + if(st_netfd_poll(stfd, POLLIN, timeout_ms * 1000) == -1){
  46 + if(errno == ETIME){
  47 + return ret;
  48 + }
  49 +
  50 + return ERROR_SOCKET_WAIT;
  51 + }
  52 +
  53 + ready = true;
  54 + return ret;
  55 +}
  56 +
37 int SrsSocket::read(const void* buf, size_t size, ssize_t* nread) 57 int SrsSocket::read(const void* buf, size_t size, ssize_t* nread)
38 { 58 {
39 int ret = ERROR_SUCCESS; 59 int ret = ERROR_SUCCESS;
@@ -44,6 +44,7 @@ public: @@ -44,6 +44,7 @@ public:
44 SrsSocket(st_netfd_t client_stfd); 44 SrsSocket(st_netfd_t client_stfd);
45 virtual ~SrsSocket(); 45 virtual ~SrsSocket();
46 public: 46 public:
  47 + virtual int can_read(int timeout_ms, bool& ready);
47 virtual int read(const void* buf, size_t size, ssize_t* nread); 48 virtual int read(const void* buf, size_t size, ssize_t* nread);
48 virtual int read_fully(const void* buf, size_t size, ssize_t* nread); 49 virtual int read_fully(const void* buf, size_t size, ssize_t* nread);
49 virtual int write(const void* buf, size_t size, ssize_t* nwrite); 50 virtual int write(const void* buf, size_t size, ssize_t* nwrite);
  1 +/*
  2 +The MIT License (MIT)
  3 +
  4 +Copyright (c) 2013 winlin
  5 +
  6 +Permission is hereby granted, free of charge, to any person obtaining a copy of
  7 +this software and associated documentation files (the "Software"), to deal in
  8 +the Software without restriction, including without limitation the rights to
  9 +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
  10 +the Software, and to permit persons to whom the Software is furnished to do so,
  11 +subject to the following conditions:
  12 +
  13 +The above copyright notice and this permission notice shall be included in all
  14 +copies or substantial portions of the Software.
  15 +
  16 +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17 +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
  18 +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
  19 +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
  20 +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  21 +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  22 +*/
  23 +
  24 +#include <srs_core_source.hpp>
  25 +
  26 +#include <srs_core_log.hpp>
  27 +#include <srs_core_protocol.hpp>
  28 +
  29 +std::map<std::string, SrsSource*> SrsSource::pool;
  30 +
  31 +SrsSource* SrsSource::find(std::string stream_url)
  32 +{
  33 + if (pool.find(stream_url) == pool.end()) {
  34 + pool[stream_url] = new SrsSource(stream_url);
  35 + srs_verbose("create new source for url=%s", stream_url.c_str());
  36 + }
  37 +
  38 + return pool[stream_url];
  39 +}
  40 +
  41 +SrsConsumer::SrsConsumer()
  42 +{
  43 +}
  44 +
  45 +SrsConsumer::~SrsConsumer()
  46 +{
  47 +}
  48 +
  49 +int SrsConsumer::get_packets(int max_count, SrsMessage**& msgs, int& count)
  50 +{
  51 + msgs = NULL;
  52 + count = 0;
  53 +
  54 + int ret = ERROR_SUCCESS;
  55 + return ret;
  56 +}
  57 +
  58 +SrsSource::SrsSource(std::string _stream_url)
  59 +{
  60 + stream_url = _stream_url;
  61 +}
  62 +
  63 +SrsSource::~SrsSource()
  64 +{
  65 +}
  66 +
  67 +int SrsSource::on_meta_data(SrsOnMetaDataPacket* metadata)
  68 +{
  69 + int ret = ERROR_SUCCESS;
  70 + return ret;
  71 +}
  72 +
  73 +int SrsSource::on_audio(SrsMessage* audio)
  74 +{
  75 + int ret = ERROR_SUCCESS;
  76 + return ret;
  77 +}
  78 +
  79 +int SrsSource::on_video(SrsMessage* audio)
  80 +{
  81 + int ret = ERROR_SUCCESS;
  82 + return ret;
  83 +}
  84 +
  85 +SrsConsumer* SrsSource::create_consumer()
  86 +{
  87 + SrsConsumer* consumer = new SrsConsumer();
  88 + return consumer;
  89 +}
  90 +
  1 +/*
  2 +The MIT License (MIT)
  3 +
  4 +Copyright (c) 2013 winlin
  5 +
  6 +Permission is hereby granted, free of charge, to any person obtaining a copy of
  7 +this software and associated documentation files (the "Software"), to deal in
  8 +the Software without restriction, including without limitation the rights to
  9 +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
  10 +the Software, and to permit persons to whom the Software is furnished to do so,
  11 +subject to the following conditions:
  12 +
  13 +The above copyright notice and this permission notice shall be included in all
  14 +copies or substantial portions of the Software.
  15 +
  16 +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17 +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
  18 +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
  19 +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
  20 +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  21 +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  22 +*/
  23 +
  24 +#ifndef SRS_CORE_SOURCE_HPP
  25 +#define SRS_CORE_SOURCE_HPP
  26 +
  27 +/*
  28 +#include <srs_core_source.hpp>
  29 +*/
  30 +
  31 +#include <srs_core.hpp>
  32 +
  33 +#include <map>
  34 +#include <string>
  35 +
  36 +class SrsMessage;
  37 +class SrsOnMetaDataPacket;
  38 +
  39 +/**
  40 +* the consumer for SrsSource, that is a play client.
  41 +*/
  42 +class SrsConsumer
  43 +{
  44 +public:
  45 + SrsConsumer();
  46 + virtual ~SrsConsumer();
  47 +public:
  48 + /**
  49 + * get packets in consumer queue.
  50 + * @msgs SrsMessages*[], output the prt array.
  51 + * @count the count in array.
  52 + * @max_count the max count to dequeue, 0 to dequeue all.
  53 + */
  54 + virtual int get_packets(int max_count, SrsMessage**& msgs, int& count);
  55 +};
  56 +
  57 +/**
  58 +* live streaming source.
  59 +*/
  60 +class SrsSource
  61 +{
  62 +private:
  63 + static std::map<std::string, SrsSource*> pool;
  64 +public:
  65 + /**
  66 + * find stream by vhost/app/stream.
  67 + * @stream_url the stream url, for example, myserver.xxx.com/app/stream
  68 + * @return the matched source, never be NULL.
  69 + * @remark stream_url should without port and schema.
  70 + */
  71 + static SrsSource* find(std::string stream_url);
  72 +private:
  73 + std::string stream_url;
  74 +public:
  75 + SrsSource(std::string _stream_url);
  76 + virtual ~SrsSource();
  77 +public:
  78 + virtual int on_meta_data(SrsOnMetaDataPacket* metadata);
  79 + virtual int on_audio(SrsMessage* audio);
  80 + virtual int on_video(SrsMessage* video);
  81 +public:
  82 + virtual SrsConsumer* create_consumer();
  83 +};
  84 +
  85 +#endif
@@ -14,6 +14,8 @@ file @@ -14,6 +14,8 @@ file
14 ..\core\srs_core_conn.cpp, 14 ..\core\srs_core_conn.cpp,
15 ..\core\srs_core_client.hpp, 15 ..\core\srs_core_client.hpp,
16 ..\core\srs_core_client.cpp, 16 ..\core\srs_core_client.cpp,
  17 + ..\core\srs_core_source.hpp,
  18 + ..\core\srs_core_source.cpp,
17 ..\core\srs_core_rtmp.hpp, 19 ..\core\srs_core_rtmp.hpp,
18 ..\core\srs_core_rtmp.cpp, 20 ..\core\srs_core_rtmp.cpp,
19 ..\core\srs_core_protocol.hpp, 21 ..\core\srs_core_protocol.hpp,