int SrsEdgeIngester::process_publish_message(SrsMessage* msg) { int ret = ERROR_SUCCESS; SrsSource* source = _source; // process audio packet if (msg->header.is_audio()) { if ((ret = source->on_audio(msg)) != ERROR_SUCCESS) { srs_error("source process audio message failed. ret=%d", ret); return ret; } } // process video packet if (msg->header.is_video()) { if ((ret = source->on_video(msg)) != ERROR_SUCCESS) { srs_error("source process video message failed. ret=%d", ret); return ret; } } // process aggregate packet if (msg->header.is_aggregate()) { if ((ret = source->on_aggregate(msg)) != ERROR_SUCCESS) { srs_error("source process aggregate message failed. ret=%d", ret); return ret; } return ret; } // process onMetaData if (msg->header.is_amf0_data() || msg->header.is_amf3_data()) { SrsPacket* pkt = NULL; if ((ret = client->decode_message(msg, &pkt)) != ERROR_SUCCESS) { srs_error("decode onMetaData message failed. ret=%d", ret); return ret; } SrsAutoFree(SrsPacket, pkt); if (dynamic_cast<SrsOnMetaDataPacket*>(pkt)) { SrsOnMetaDataPacket* metadata = dynamic_cast<SrsOnMetaDataPacket*>(pkt); if ((ret = source->on_meta_data(msg, metadata)) != ERROR_SUCCESS) { srs_error("source process onMetaData message failed. ret=%d", ret); return ret; } srs_info("process onMetaData message success."); return ret; } srs_info("ignore AMF0/AMF3 data message."); return ret; } return ret; }
int SrsRtmp::identify_create_stream_client(SrsCreateStreamPacket* req, int stream_id, SrsClientType& type, std::string& stream_name) { int ret = ERROR_SUCCESS; if (true) { SrsCommonMessage* msg = new SrsCommonMessage(); SrsCreateStreamResPacket* pkt = new SrsCreateStreamResPacket(req->transaction_id, stream_id); msg->set_packet(pkt, 0); if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) { srs_error("send createStream response message failed. ret=%d", ret); return ret; } srs_info("send createStream response message success."); } while (true) { SrsCommonMessage* msg = NULL; if ((ret = protocol->recv_message(&msg)) != ERROR_SUCCESS) { srs_error("recv identify client message failed. ret=%d", ret); return ret; } SrsAutoFree(SrsCommonMessage, msg, false); if (!msg->header.is_amf0_command() && !msg->header.is_amf3_command()) { srs_trace("identify ignore messages except " "AMF0/AMF3 command message. type=%#x", msg->header.message_type); continue; } if ((ret = msg->decode_packet(protocol)) != ERROR_SUCCESS) { srs_error("identify decode message failed. ret=%d", ret); return ret; } SrsPacket* pkt = msg->get_packet(); if (dynamic_cast<SrsPlayPacket*>(pkt)) { SrsPlayPacket* play = dynamic_cast<SrsPlayPacket*>(pkt); type = SrsClientPlay; stream_name = play->stream_name; srs_trace("identity client type=play, stream_name=%s", stream_name.c_str()); return ret; } if (dynamic_cast<SrsPublishPacket*>(pkt)) { srs_info("identify client by publish, falsh publish."); return identify_flash_publish_client( dynamic_cast<SrsPublishPacket*>(pkt), type, stream_name); } srs_trace("ignore AMF0/AMF3 command message."); } return ret; }
int SrsRtmpClient::connect_app(std::string app, std::string tc_url) { int ret = ERROR_SUCCESS; // Connect(vhost, app) if (true) { SrsCommonMessage* msg = new SrsCommonMessage(); SrsConnectAppPacket* pkt = new SrsConnectAppPacket(); msg->set_packet(pkt, 0); pkt->command_object = new SrsAmf0Object(); pkt->command_object->set("app", new SrsAmf0String(app.c_str())); pkt->command_object->set("swfUrl", new SrsAmf0String()); pkt->command_object->set("tcUrl", new SrsAmf0String(tc_url.c_str())); pkt->command_object->set("fpad", new SrsAmf0Boolean(false)); pkt->command_object->set("capabilities", new SrsAmf0Number(239)); pkt->command_object->set("audioCodecs", new SrsAmf0Number(3575)); pkt->command_object->set("videoCodecs", new SrsAmf0Number(252)); pkt->command_object->set("videoFunction", new SrsAmf0Number(1)); pkt->command_object->set("pageUrl", new SrsAmf0String()); pkt->command_object->set("objectEncoding", new SrsAmf0Number(0)); if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) { return ret; } } // Set Window Acknowledgement size(2500000) if (true) { SrsCommonMessage* msg = new SrsCommonMessage(); SrsSetWindowAckSizePacket* pkt = new SrsSetWindowAckSizePacket(); pkt->ackowledgement_window_size = 2500000; msg->set_packet(pkt, 0); if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) { return ret; } } // expect connect _result SrsCommonMessage* msg = NULL; SrsConnectAppResPacket* pkt = NULL; if ((ret = srs_rtmp_expect_message<SrsConnectAppResPacket>(protocol, &msg, &pkt)) != ERROR_SUCCESS) { srs_error("expect connect app response message failed. ret=%d", ret); return ret; } SrsAutoFree(SrsCommonMessage, msg, false); srs_info("get connect app response message"); return ret; }
int SrsEdgeIngester::ingest() { int ret = ERROR_SUCCESS; client->set_recv_timeout(SRS_EDGE_INGESTER_TIMEOUT_US); SrsPithyPrint pithy_print(SRS_CONSTS_STAGE_EDGE); while (pthread->can_loop()) { // switch to other st-threads. st_usleep(0); pithy_print.elapse(); // pithy print if (pithy_print.can_print()) { kbps->sample(); srs_trace("<- "SRS_CONSTS_LOG_EDGE_PLAY " time=%"PRId64", okbps=%d,%d,%d, ikbps=%d,%d,%d", pithy_print.age(), kbps->get_send_kbps(), kbps->get_send_kbps_30s(), kbps->get_send_kbps_5m(), kbps->get_recv_kbps(), kbps->get_recv_kbps_30s(), kbps->get_recv_kbps_5m()); } // read from client. SrsMessage* msg = NULL; if ((ret = client->recv_message(&msg)) != ERROR_SUCCESS) { if (!srs_is_client_gracefully_close(ret)) { srs_error("pull origin server message failed. ret=%d", ret); } return ret; } srs_verbose("edge loop recv message. ret=%d", ret); srs_assert(msg); SrsAutoFree(SrsMessage, msg); if ((ret = process_publish_message(msg)) != ERROR_SUCCESS) { return ret; } } return ret; }
int SrsRtmp::identify_client(int stream_id, SrsClientType& type, std::string& stream_name) { type = SrsClientUnknown; int ret = ERROR_SUCCESS; while (true) { SrsCommonMessage* msg = NULL; if ((ret = protocol->recv_message(&msg)) != ERROR_SUCCESS) { srs_error("recv identify client message failed. ret=%d", ret); return ret; } SrsAutoFree(SrsCommonMessage, msg, false); if (!msg->header.is_amf0_command() && !msg->header.is_amf3_command()) { srs_trace("identify ignore messages except " "AMF0/AMF3 command message. type=%#x", msg->header.message_type); continue; } if ((ret = msg->decode_packet(protocol)) != ERROR_SUCCESS) { srs_error("identify decode message failed. ret=%d", ret); return ret; } SrsPacket* pkt = msg->get_packet(); if (dynamic_cast<SrsCreateStreamPacket*>(pkt)) { srs_info("identify client by create stream, play or flash publish."); return identify_create_stream_client( dynamic_cast<SrsCreateStreamPacket*>(pkt), stream_id, type, stream_name); } if (dynamic_cast<SrsFMLEStartPacket*>(pkt)) { srs_info("identify client by releaseStream, fmle publish."); return identify_fmle_publish_client( dynamic_cast<SrsFMLEStartPacket*>(pkt), type, stream_name); } srs_trace("ignore AMF0/AMF3 command message."); } return ret; }
int SrsRtmp::connect_app(SrsRequest* req) { int ret = ERROR_SUCCESS; SrsCommonMessage* msg = NULL; SrsConnectAppPacket* pkt = NULL; if ((ret = srs_rtmp_expect_message<SrsConnectAppPacket>(protocol, &msg, &pkt)) != ERROR_SUCCESS) { srs_error("expect connect app message failed. ret=%d", ret); return ret; } SrsAutoFree(SrsCommonMessage, msg, false); srs_info("get connect app message"); SrsAmf0Any* prop = NULL; if ((prop = pkt->command_object->ensure_property_string("tcUrl")) == NULL) { ret = ERROR_RTMP_REQ_CONNECT; srs_error("invalid request, must specifies the tcUrl. ret=%d", ret); return ret; } req->tcUrl = srs_amf0_convert<SrsAmf0String>(prop)->value; if ((prop = pkt->command_object->ensure_property_string("pageUrl")) != NULL) { req->pageUrl = srs_amf0_convert<SrsAmf0String>(prop)->value; } if ((prop = pkt->command_object->ensure_property_string("swfUrl")) != NULL) { req->swfUrl = srs_amf0_convert<SrsAmf0String>(prop)->value; } if ((prop = pkt->command_object->ensure_property_number("objectEncoding")) != NULL) { req->objectEncoding = srs_amf0_convert<SrsAmf0Number>(prop)->value; } srs_info("get connect app message params success."); return req->discovery_app(); }
int SrsSource::on_video(SrsCommonMessage* video) { int ret = ERROR_SUCCESS; SrsSharedPtrMessage* msg = new SrsSharedPtrMessage(); SrsAutoFree(SrsSharedPtrMessage, msg, false); if ((ret = msg->initialize(video)) != ERROR_SUCCESS) { srs_error("initialize the video failed. ret=%d", ret); return ret; } srs_verbose("initialize shared ptr video success."); #ifdef SRS_HLS if ((ret = hls->on_video(msg->copy())) != ERROR_SUCCESS) { srs_error("hls process video message failed. ret=%d", ret); return ret; } #endif // copy to all consumer if (true) { std::vector<SrsConsumer*>::iterator it; for (it = consumers.begin(); it != consumers.end(); ++it) { SrsConsumer* consumer = *it; if ((ret = consumer->enqueue(msg->copy(), sample_rate, frame_rate)) != ERROR_SUCCESS) { srs_error("dispatch the video failed. ret=%d", ret); return ret; } } srs_info("dispatch video success."); } // copy to all forwarders. if (true) { std::vector<SrsForwarder*>::iterator it; for (it = forwarders.begin(); it != forwarders.end(); ++it) { SrsForwarder* forwarder = *it; if ((ret = forwarder->on_video(msg->copy())) != ERROR_SUCCESS) { srs_error("forwarder process video message failed. ret=%d", ret); return ret; } } } // cache the sequence header if h264 if (SrsCodec::video_is_sequence_header(msg->payload, msg->size)) { srs_freep(cache_sh_video); cache_sh_video = msg->copy(); srs_trace("update video sequence header success. size=%d", msg->header.payload_length); return ret; } // cache the last gop packets if ((ret = gop_cache->cache(msg)) != ERROR_SUCCESS) { srs_error("shrink gop cache failed. ret=%d", ret); return ret; } srs_verbose("cache gop success."); return ret; }
int SrsRtmp::start_fmle_publish(int stream_id) { int ret = ERROR_SUCCESS; // FCPublish double fc_publish_tid = 0; if (true) { SrsCommonMessage* msg = NULL; SrsFMLEStartPacket* pkt = NULL; if ((ret = srs_rtmp_expect_message<SrsFMLEStartPacket>(protocol, &msg, &pkt)) != ERROR_SUCCESS) { srs_error("recv FCPublish message failed. ret=%d", ret); return ret; } srs_info("recv FCPublish request message success."); SrsAutoFree(SrsCommonMessage, msg, false); fc_publish_tid = pkt->transaction_id; } // FCPublish response if (true) { SrsCommonMessage* msg = new SrsCommonMessage(); SrsFMLEStartResPacket* pkt = new SrsFMLEStartResPacket(fc_publish_tid); msg->set_packet(pkt, 0); if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) { srs_error("send FCPublish response message failed. ret=%d", ret); return ret; } srs_info("send FCPublish response message success."); } // createStream double create_stream_tid = 0; if (true) { SrsCommonMessage* msg = NULL; SrsCreateStreamPacket* pkt = NULL; if ((ret = srs_rtmp_expect_message<SrsCreateStreamPacket>(protocol, &msg, &pkt)) != ERROR_SUCCESS) { srs_error("recv createStream message failed. ret=%d", ret); return ret; } srs_info("recv createStream request message success."); SrsAutoFree(SrsCommonMessage, msg, false); create_stream_tid = pkt->transaction_id; } // createStream response if (true) { SrsCommonMessage* msg = new SrsCommonMessage(); SrsCreateStreamResPacket* pkt = new SrsCreateStreamResPacket(create_stream_tid, stream_id); msg->set_packet(pkt, 0); if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) { srs_error("send createStream response message failed. ret=%d", ret); return ret; } srs_info("send createStream response message success."); } // publish if (true) { SrsCommonMessage* msg = NULL; SrsPublishPacket* pkt = NULL; if ((ret = srs_rtmp_expect_message<SrsPublishPacket>(protocol, &msg, &pkt)) != ERROR_SUCCESS) { srs_error("recv publish message failed. ret=%d", ret); return ret; } srs_info("recv publish request message success."); SrsAutoFree(SrsCommonMessage, msg, false); } // publish response onFCPublish(NetStream.Publish.Start) if (true) { SrsCommonMessage* msg = new SrsCommonMessage(); SrsOnStatusCallPacket* pkt = new SrsOnStatusCallPacket(); pkt->command_name = RTMP_AMF0_COMMAND_ON_FC_PUBLISH; pkt->data->set(StatusCode, new SrsAmf0String(StatusCodePublishStart)); pkt->data->set(StatusDescription, new SrsAmf0String("Started publishing stream.")); msg->set_packet(pkt, stream_id); if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) { srs_error("send onFCPublish(NetStream.Publish.Start) message failed. ret=%d", ret); return ret; } srs_info("send onFCPublish(NetStream.Publish.Start) message success."); } // publish response onStatus(NetStream.Publish.Start) if (true) { SrsCommonMessage* msg = new SrsCommonMessage(); SrsOnStatusCallPacket* pkt = new SrsOnStatusCallPacket(); pkt->data->set(StatusLevel, new SrsAmf0String(StatusLevelStatus)); pkt->data->set(StatusCode, new SrsAmf0String(StatusCodePublishStart)); pkt->data->set(StatusDescription, new SrsAmf0String("Started publishing stream.")); pkt->data->set(StatusClientId, new SrsAmf0String(RTMP_SIG_CLIENT_ID)); msg->set_packet(pkt, stream_id); if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) { srs_error("send onStatus(NetStream.Publish.Start) message failed. ret=%d", ret); return ret; } srs_info("send onStatus(NetStream.Publish.Start) message success."); } srs_info("FMLE publish success."); return ret; }