int SrsRtmp::identify_create_stream_client(SrsCreateStreamPacket* req, int stream_id, SrsClientType& type, 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 SrsRtmpServer::identify_client(int stream_id, SrsClientType& type, 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); } if (dynamic_cast<SrsPlayPacket*>(pkt)) { srs_info("level0 identify client by play."); return identify_play_client(dynamic_cast<SrsPlayPacket*>(pkt), type, stream_name); } srs_trace("ignore AMF0/AMF3 command message."); } return ret; }
int srs_rtmp_expect_message(SrsProtocol* protocol, SrsCommonMessage** pmsg, T** ppacket) { *pmsg = NULL; *ppacket = NULL; int ret = ERROR_SUCCESS; while (true) { SrsCommonMessage* msg = NULL; if ((ret = protocol->recv_message(&msg)) != ERROR_SUCCESS) { srs_error("recv message failed. ret=%d", ret); return ret; } srs_verbose("recv message success."); if ((ret = msg->decode_packet(protocol)) != ERROR_SUCCESS) { delete msg; srs_error("decode message failed. ret=%d", ret); return ret; } T* pkt = dynamic_cast<T*>(msg->get_packet()); if (!pkt) { delete msg; srs_trace("drop message(type=%d, size=%d, time=%"PRId64", sid=%d).", msg->header.message_type, msg->header.payload_length, msg->header.timestamp, msg->header.stream_id); continue; } *pmsg = msg; *ppacket = pkt; break; } return ret; }
int SrsRtmpConn::flash_publish(SrsSource* source) { int ret = ERROR_SUCCESS; if ((ret = refer->check(req->pageUrl, _srs_config->get_refer_publish(req->vhost))) != ERROR_SUCCESS) { srs_error("flash check publish_refer failed. ret=%d", ret); return ret; } srs_verbose("flash check publish_refer success."); SrsPithyPrint pithy_print(SRS_STAGE_PUBLISH_USER); // notify the hls to prepare when publish start. if ((ret = source->on_publish(req)) != ERROR_SUCCESS) { srs_error("flash hls on_publish failed. ret=%d", ret); return ret; } srs_verbose("flash hls on_publish success."); while (true) { // switch to other st-threads. st_usleep(0); SrsCommonMessage* msg = NULL; if ((ret = rtmp->recv_message(&msg)) != ERROR_SUCCESS) { if (!srs_is_client_gracefully_close(ret)) { srs_error("flash recv identify client message failed. ret=%d", ret); } return ret; } SrsAutoFree(SrsCommonMessage, msg, false); pithy_print.set_age(msg->header.timestamp); // reportable if (pithy_print.can_print()) { srs_trace("<- time=%"PRId64", obytes=%"PRId64", ibytes=%"PRId64", okbps=%d, ikbps=%d", pithy_print.get_age(), rtmp->get_send_bytes(), rtmp->get_recv_bytes(), rtmp->get_send_kbps(), rtmp->get_recv_kbps()); } // process UnPublish event. if (msg->header.is_amf0_command() || msg->header.is_amf3_command()) { if ((ret = msg->decode_packet(rtmp->get_protocol())) != ERROR_SUCCESS) { srs_error("flash decode unpublish message failed. ret=%d", ret); return ret; } // flash unpublish. // TODO: maybe need to support republish. srs_trace("flash flash publish finished."); return ERROR_CONTROL_REPUBLISH; } // video, audio, data message if ((ret = process_publish_message(source, msg)) != ERROR_SUCCESS) { srs_error("flash process publish message failed. ret=%d", ret); return ret; } } return ret; }
int SrsRtmpConn::fmle_publish(SrsSource* source) { int ret = ERROR_SUCCESS; if ((ret = refer->check(req->pageUrl, _srs_config->get_refer_publish(req->vhost))) != ERROR_SUCCESS) { srs_error("fmle check publish_refer failed. ret=%d", ret); return ret; } srs_verbose("fmle check publish_refer success."); SrsPithyPrint pithy_print(SRS_STAGE_PUBLISH_USER); // notify the hls to prepare when publish start. if ((ret = source->on_publish(req)) != ERROR_SUCCESS) { srs_error("fmle hls on_publish failed. ret=%d", ret); return ret; } srs_verbose("fmle hls on_publish success."); while (true) { // switch to other st-threads. st_usleep(0); SrsCommonMessage* msg = NULL; if ((ret = rtmp->recv_message(&msg)) != ERROR_SUCCESS) { srs_error("fmle recv identify client message failed. ret=%d", ret); return ret; } SrsAutoFree(SrsCommonMessage, msg, false); pithy_print.set_age(msg->header.timestamp); // reportable if (pithy_print.can_print()) { srs_trace("<- time=%"PRId64", obytes=%"PRId64", ibytes=%"PRId64", okbps=%d, ikbps=%d", pithy_print.get_age(), rtmp->get_send_bytes(), rtmp->get_recv_bytes(), rtmp->get_send_kbps(), rtmp->get_recv_kbps()); } // process UnPublish event. if (msg->header.is_amf0_command() || msg->header.is_amf3_command()) { if ((ret = msg->decode_packet(rtmp->get_protocol())) != ERROR_SUCCESS) { srs_error("fmle decode unpublish message failed. ret=%d", ret); return ret; } SrsPacket* pkt = msg->get_packet(); if (dynamic_cast<SrsFMLEStartPacket*>(pkt)) { SrsFMLEStartPacket* unpublish = dynamic_cast<SrsFMLEStartPacket*>(pkt); if ((ret = rtmp->fmle_unpublish(res->stream_id, unpublish->transaction_id)) != ERROR_SUCCESS) { return ret; } return ERROR_CONTROL_REPUBLISH; } srs_trace("fmle ignore AMF0/AMF3 command message."); continue; } // video, audio, data message if ((ret = process_publish_message(source, msg)) != ERROR_SUCCESS) { srs_error("fmle process publish message failed. ret=%d", ret); return ret; } } return ret; }