diff --git a/trunk/research/librtmp/srs_play.c b/trunk/research/librtmp/srs_play.c index ab6142df0..00953fcea 100644 --- a/trunk/research/librtmp/srs_play.c +++ b/trunk/research/librtmp/srs_play.c @@ -25,6 +25,8 @@ gcc srs_play.c ../../objs/lib/srs_librtmp.a -g -O0 -lstdc++ -o srs_play */ #include +#include + #include "../../objs/include/srs_librtmp.h" int main(int argc, char** argv) @@ -33,14 +35,14 @@ int main(int argc, char** argv) // packet data int type, size; - u_int32_t timestamp; + u_int32_t timestamp = 0; char* data; printf("suck rtmp stream like rtmpdump\n"); printf("srs(simple-rtmp-server) client librtmp library.\n"); printf("version: %d.%d.%d\n", srs_version_major(), srs_version_minor(), srs_version_revision()); - rtmp = srs_rtmp_create("rtmp://127.0.0.1:1935/live?vhost=__defaultVhost__/livestream"); + rtmp = srs_rtmp_create("rtmp://127.0.0.1:1935/live/livestream"); if (srs_simple_handshake(rtmp) != 0) { printf("simple handshake failed.\n"); diff --git a/trunk/research/librtmp/srs_publish.c b/trunk/research/librtmp/srs_publish.c index 0e10eceb2..b475c7a43 100644 --- a/trunk/research/librtmp/srs_publish.c +++ b/trunk/research/librtmp/srs_publish.c @@ -25,12 +25,20 @@ gcc srs_publish.c ../../objs/lib/srs_librtmp.a -g -O0 -lstdc++ -o srs_publish */ #include +#include +#include + #include "../../objs/include/srs_librtmp.h" int main(int argc, char** argv) { srs_rtmp_t rtmp; + // packet data + int type, size; + u_int32_t timestamp = 0; + char* data; + printf("publish rtmp stream to server like FMLE/FFMPEG/Encoder\n"); printf("srs(simple-rtmp-server) client librtmp library.\n"); printf("version: %d.%d.%d\n", srs_version_major(), srs_version_minor(), srs_version_revision()); @@ -55,6 +63,20 @@ int main(int argc, char** argv) } printf("publish stream success\n"); + for (;;) { + type = SRS_RTMP_TYPE_VIDEO; + timestamp += 40; + size = 4096; + data = (char*)malloc(4096); + + if (srs_write_packet(rtmp, type, timestamp, data, size) != 0) { + goto rtmp_destroy; + } + printf("sent packet: type=%s, time=%d, size=%d\n", srs_type2string(type), timestamp, size); + + usleep(40 * 1000); + } + rtmp_destroy: srs_rtmp_destroy(rtmp); diff --git a/trunk/src/app/srs_core_source.cpp b/trunk/src/app/srs_core_source.cpp index 1aac3d4c5..72eef4f66 100644 --- a/trunk/src/app/srs_core_source.cpp +++ b/trunk/src/app/srs_core_source.cpp @@ -677,7 +677,7 @@ int SrsSource::on_meta_data(SrsCommonMessage* msg, SrsOnMetaDataPacket* metadata cache_metadata = new SrsSharedPtrMessage(); // dump message to shared ptr message. - if ((ret = cache_metadata->initialize(msg, payload, size)) != ERROR_SUCCESS) { + if ((ret = cache_metadata->initialize(&msg->header, payload, size)) != ERROR_SUCCESS) { srs_error("initialize the cache metadata failed. ret=%d", ret); return ret; } diff --git a/trunk/src/libs/srs_librtmp.cpp b/trunk/src/libs/srs_librtmp.cpp index 15ad38459..c7dd0a502 100644 --- a/trunk/src/libs/srs_librtmp.cpp +++ b/trunk/src/libs/srs_librtmp.cpp @@ -328,6 +328,51 @@ int srs_read_packet(srs_rtmp_t rtmp, int* type, u_int32_t* timestamp, char** dat int srs_write_packet(srs_rtmp_t rtmp, int type, u_int32_t timestamp, char* data, int size) { int ret = ERROR_SUCCESS; + + srs_assert(rtmp != NULL); + Context* context = (Context*)rtmp; + + SrsSharedPtrMessage* msg = NULL; + + if (type == SRS_RTMP_TYPE_AUDIO) { + SrsMessageHeader header; + header.initialize_audio(size, timestamp, context->stream_id); + + msg = new SrsSharedPtrMessage(); + if ((ret = msg->initialize(&header, data, size)) != ERROR_SUCCESS) { + srs_freepa(data); + return ret; + } + } else if (type == SRS_RTMP_TYPE_VIDEO) { + SrsMessageHeader header; + header.initialize_video(size, timestamp, context->stream_id); + + msg = new SrsSharedPtrMessage(); + if ((ret = msg->initialize(&header, data, size)) != ERROR_SUCCESS) { + srs_freepa(data); + return ret; + } + } else if (type == SRS_RTMP_TYPE_SCRIPT) { + SrsMessageHeader header; + header.initialize_amf0_script(size, context->stream_id); + + msg = new SrsSharedPtrMessage(); + if ((ret = msg->initialize(&header, data, size)) != ERROR_SUCCESS) { + srs_freepa(data); + return ret; + } + } + + if (msg) { + // send out encoded msg. + if ((ret = context->rtmp->send_message(msg)) != ERROR_SUCCESS) { + return ret; + } + } else { + // directly free data if not sent out. + srs_freepa(data); + } + return ret; } diff --git a/trunk/src/rtmp/srs_protocol_rtmp_stack.cpp b/trunk/src/rtmp/srs_protocol_rtmp_stack.cpp index 575caf1b5..ac8808219 100644 --- a/trunk/src/rtmp/srs_protocol_rtmp_stack.cpp +++ b/trunk/src/rtmp/srs_protocol_rtmp_stack.cpp @@ -1193,6 +1193,33 @@ bool SrsMessageHeader::is_user_control_message() return message_type == RTMP_MSG_UserControlMessage; } +void SrsMessageHeader::initialize_amf0_script(int size, int stream) +{ + message_type = RTMP_MSG_AMF0DataMessage; + payload_length = (int32_t)size; + timestamp_delta = (int32_t)0; + timestamp = (int64_t)0; + stream_id = (int32_t)stream; +} + +void SrsMessageHeader::initialize_audio(int size, u_int32_t time, int stream) +{ + message_type = RTMP_MSG_AudioMessage; + payload_length = (int32_t)size; + timestamp_delta = (int32_t)time; + timestamp = (int64_t)time; + stream_id = (int32_t)stream; +} + +void SrsMessageHeader::initialize_video(int size, u_int32_t time, int stream) +{ + message_type = RTMP_MSG_VideoMessage; + payload_length = (int32_t)size; + timestamp_delta = (int32_t)time; + timestamp = (int64_t)time; + stream_id = (int32_t)stream; +} + SrsChunkStream::SrsChunkStream(int _cid) { fmt = 0; @@ -1516,7 +1543,7 @@ int SrsSharedPtrMessage::initialize(SrsCommonMessage* source) { int ret = ERROR_SUCCESS; - if ((ret = initialize(source, (char*)source->payload, source->size)) != ERROR_SUCCESS) { + if ((ret = initialize(&source->header, (char*)source->payload, source->size)) != ERROR_SUCCESS) { return ret; } @@ -1527,7 +1554,7 @@ int SrsSharedPtrMessage::initialize(SrsCommonMessage* source) return ret; } -int SrsSharedPtrMessage::initialize(SrsCommonMessage* source, char* payload, int size) +int SrsSharedPtrMessage::initialize(SrsMessageHeader* source, char* payload, int size) { int ret = ERROR_SUCCESS; @@ -1540,7 +1567,7 @@ int SrsSharedPtrMessage::initialize(SrsCommonMessage* source, char* payload, int return ret; } - header = source->header; + header = *source; header.payload_length = size; ptr = new SrsSharedPtr(); @@ -1549,9 +1576,9 @@ int SrsSharedPtrMessage::initialize(SrsCommonMessage* source, char* payload, int ptr->payload = payload; ptr->size = size; - if (source->header.is_video()) { + if (source->is_video()) { ptr->perfer_cid = RTMP_CID_Video; - } else if (source->header.is_audio()) { + } else if (source->is_audio()) { ptr->perfer_cid = RTMP_CID_Audio; } else { ptr->perfer_cid = RTMP_CID_OverConnection2; diff --git a/trunk/src/rtmp/srs_protocol_rtmp_stack.hpp b/trunk/src/rtmp/srs_protocol_rtmp_stack.hpp index cbca5f654..2c2c4cb7c 100644 --- a/trunk/src/rtmp/srs_protocol_rtmp_stack.hpp +++ b/trunk/src/rtmp/srs_protocol_rtmp_stack.hpp @@ -262,6 +262,10 @@ struct SrsMessageHeader bool is_window_ackledgement_size(); bool is_set_chunk_size(); bool is_user_control_message(); + + void initialize_amf0_script(int size, int stream); + void initialize_audio(int size, u_int32_t time, int stream); + void initialize_video(int size, u_int32_t time, int stream); }; /** @@ -434,9 +438,9 @@ public: virtual int initialize(SrsCommonMessage* source); /** * set the shared payload. - * we will use the payload, donot use the payload of source. + * use source header, and specified param payload. */ - virtual int initialize(SrsCommonMessage* source, char* payload, int size); + virtual int initialize(SrsMessageHeader* source, char* payload, int size); virtual SrsSharedPtrMessage* copy(); public: /**