winlin

fix the http flv stream caster.

@@ -95,7 +95,10 @@ int SrsAppCasterFlv::serve_http(ISrsHttpResponseWriter* w, SrsHttpMessage* r) @@ -95,7 +95,10 @@ int SrsAppCasterFlv::serve_http(ISrsHttpResponseWriter* w, SrsHttpMessage* r)
95 srs_assert(conn); 95 srs_assert(conn);
96 96
97 std::string app = srs_path_dirname(r->path()); 97 std::string app = srs_path_dirname(r->path());
  98 + app = srs_string_trim_start(app, "/");
  99 +
98 std::string stream = srs_path_basename(r->path()); 100 std::string stream = srs_path_basename(r->path());
  101 + stream = srs_string_trim_start(stream, "/");
99 102
100 std::string o = output; 103 std::string o = output;
101 if (!app.empty() && app != "/") { 104 if (!app.empty() && app != "/") {
@@ -120,10 +123,15 @@ SrsDynamicHttpConn::SrsDynamicHttpConn(IConnectionManager* cm, st_netfd_t fd, Sr @@ -120,10 +123,15 @@ SrsDynamicHttpConn::SrsDynamicHttpConn(IConnectionManager* cm, st_netfd_t fd, Sr
120 client = NULL; 123 client = NULL;
121 stfd = NULL; 124 stfd = NULL;
122 stream_id = 0; 125 stream_id = 0;
  126 +
  127 + pprint = SrsPithyPrint::create_caster();
123 } 128 }
124 129
125 SrsDynamicHttpConn::~SrsDynamicHttpConn() 130 SrsDynamicHttpConn::~SrsDynamicHttpConn()
126 { 131 {
  132 + close();
  133 +
  134 + srs_freep(pprint);
127 } 135 }
128 136
129 int SrsDynamicHttpConn::on_got_http_message(SrsHttpMessage* msg) 137 int SrsDynamicHttpConn::on_got_http_message(SrsHttpMessage* msg)
@@ -150,12 +158,87 @@ int SrsDynamicHttpConn::proxy(ISrsHttpResponseWriter* w, SrsHttpMessage* r, std: @@ -150,12 +158,87 @@ int SrsDynamicHttpConn::proxy(ISrsHttpResponseWriter* w, SrsHttpMessage* r, std:
150 return ret; 158 return ret;
151 } 159 }
152 160
  161 + char header[9];
  162 + if ((ret = dec.read_header(header)) != ERROR_SUCCESS) {
  163 + if (!srs_is_client_gracefully_close(ret)) {
  164 + srs_error("flv: proxy flv header failed. ret=%d", ret);
  165 + }
  166 + return ret;
  167 + }
  168 + srs_trace("flv: proxy drop flv header.");
  169 +
  170 + char pps[4];
  171 + if ((ret = dec.read_previous_tag_size(pps)) != ERROR_SUCCESS) {
  172 + if (!srs_is_client_gracefully_close(ret)) {
  173 + srs_error("flv: proxy flv header pps failed. ret=%d", ret);
  174 + }
  175 + return ret;
  176 + }
  177 +
153 while (!rr->eof()) { 178 while (!rr->eof()) {
154 - int nb_read = 0;  
155 - if ((ret = rr->read(buffer, SRS_HTTP_FLV_STREAM_BUFFER, &nb_read)) != ERROR_SUCCESS) { 179 + pprint->elapse();
  180 +
  181 + if ((ret = connect()) != ERROR_SUCCESS) {
156 return ret; 182 return ret;
157 } 183 }
158 - //srs_trace("flv: read %dB from %s", nb_read, r->path().c_str()); 184 +
  185 + char type;
  186 + int32_t size;
  187 + u_int32_t time;
  188 + if ((ret = dec.read_tag_header(&type, &size, &time)) != ERROR_SUCCESS) {
  189 + if (!srs_is_client_gracefully_close(ret)) {
  190 + srs_error("flv: proxy tag header failed. ret=%d", ret);
  191 + }
  192 + return ret;
  193 + }
  194 +
  195 + char* data = new char[size];
  196 + if ((ret = dec.read_tag_data(data, size)) != ERROR_SUCCESS) {
  197 + srs_freep(data);
  198 + if (!srs_is_client_gracefully_close(ret)) {
  199 + srs_error("flv: proxy tag data failed. ret=%d", ret);
  200 + }
  201 + return ret;
  202 + }
  203 +
  204 + if ((ret = rtmp_write_packet(type, time, data, size)) != ERROR_SUCCESS) {
  205 + if (!srs_is_client_gracefully_close(ret)) {
  206 + srs_error("flv: proxy rtmp packet failed. ret=%d", ret);
  207 + }
  208 + return ret;
  209 + }
  210 +
  211 + if ((ret = dec.read_previous_tag_size(pps)) != ERROR_SUCCESS) {
  212 + if (!srs_is_client_gracefully_close(ret)) {
  213 + srs_error("flv: proxy tag header pps failed. ret=%d", ret);
  214 + }
  215 + return ret;
  216 + }
  217 + }
  218 +
  219 + return ret;
  220 +}
  221 +
  222 +int SrsDynamicHttpConn::rtmp_write_packet(char type, u_int32_t timestamp, char* data, int size)
  223 +{
  224 + int ret = ERROR_SUCCESS;
  225 +
  226 + SrsSharedPtrMessage* msg = NULL;
  227 +
  228 + if ((ret = srs_rtmp_create_msg(type, timestamp, data, size, stream_id, &msg)) != ERROR_SUCCESS) {
  229 + srs_error("flv: create shared ptr msg failed. ret=%d", ret);
  230 + return ret;
  231 + }
  232 + srs_assert(msg);
  233 +
  234 + if (pprint->can_print()) {
  235 + srs_trace("flv: send msg %s age=%d, dts=%"PRId64", size=%d",
  236 + msg->is_audio()? "A":msg->is_video()? "V":"N", pprint->age(), msg->timestamp, msg->size);
  237 + }
  238 +
  239 + // send out encoded msg.
  240 + if ((ret = client->send_and_free_message(msg, stream_id)) != ERROR_SUCCESS) {
  241 + return ret;
159 } 242 }
160 243
161 return ret; 244 return ret;
@@ -335,13 +418,19 @@ int SrsHttpFileReader::read(void* buf, size_t count, ssize_t* pnread) @@ -335,13 +418,19 @@ int SrsHttpFileReader::read(void* buf, size_t count, ssize_t* pnread)
335 return ret; 418 return ret;
336 } 419 }
337 420
  421 + int total_read = 0;
  422 + while (total_read < count) {
338 int nread = 0; 423 int nread = 0;
339 - if ((ret = http->read((char*)buf, (int)count, &nread)) != ERROR_SUCCESS) { 424 + if ((ret = http->read((char*)buf + total_read, (int)(count - total_read), &nread)) != ERROR_SUCCESS) {
340 return ret; 425 return ret;
341 } 426 }
342 427
  428 + srs_assert(nread);
  429 + total_read += nread;
  430 + }
  431 +
343 if (pnread) { 432 if (pnread) {
344 - *pnread = nread; 433 + *pnread = total_read;
345 } 434 }
346 435
347 return ret; 436 return ret;
@@ -41,6 +41,7 @@ class SrsHttpConn; @@ -41,6 +41,7 @@ class SrsHttpConn;
41 class SrsRtmpClient; 41 class SrsRtmpClient;
42 class SrsStSocket; 42 class SrsStSocket;
43 class SrsRequest; 43 class SrsRequest;
  44 +class SrsPithyPrint;
44 45
45 #include <srs_app_st.hpp> 46 #include <srs_app_st.hpp>
46 #include <srs_app_listener.hpp> 47 #include <srs_app_listener.hpp>
@@ -82,6 +83,7 @@ class SrsDynamicHttpConn : public SrsHttpConn @@ -82,6 +83,7 @@ class SrsDynamicHttpConn : public SrsHttpConn
82 { 83 {
83 private: 84 private:
84 std::string output; 85 std::string output;
  86 + SrsPithyPrint* pprint;
85 private: 87 private:
86 SrsRequest* req; 88 SrsRequest* req;
87 st_netfd_t stfd; 89 st_netfd_t stfd;
@@ -96,6 +98,8 @@ public: @@ -96,6 +98,8 @@ public:
96 public: 98 public:
97 virtual int proxy(ISrsHttpResponseWriter* w, SrsHttpMessage* r, std::string o); 99 virtual int proxy(ISrsHttpResponseWriter* w, SrsHttpMessage* r, std::string o);
98 private: 100 private:
  101 + virtual int rtmp_write_packet(char type, u_int32_t timestamp, char* data, int size);
  102 +private:
99 // connect to rtmp output url. 103 // connect to rtmp output url.
100 // @remark ignore when not connected, reconnect when disconnected. 104 // @remark ignore when not connected, reconnect when disconnected.
101 virtual int connect(); 105 virtual int connect();