winlin

srs-librtmp: implements the read packet.

... ... @@ -31,11 +31,16 @@ int main(int argc, char** argv)
{
srs_rtmp_t rtmp;
// packet data
int type, size;
u_int32_t timestamp;
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/show?vhost=__defaultVhost__/livestream");
rtmp = srs_rtmp_create("rtmp://127.0.0.1:1935/live?vhost=__defaultVhost__/livestream");
if (srs_simple_handshake(rtmp) != 0) {
printf("simple handshake failed.\n");
... ... @@ -55,6 +60,15 @@ int main(int argc, char** argv)
}
printf("play stream success\n");
for (;;) {
if (srs_read_packet(rtmp, &type, &timestamp, &data, &size) != 0) {
goto rtmp_destroy;
}
printf("got packet: type=%s, time=%d, size=%d\n", srs_type2string(type), timestamp, size);
free(data);
}
rtmp_destroy:
srs_rtmp_destroy(rtmp);
... ...
... ... @@ -33,6 +33,8 @@ using namespace std;
#include <srs_lib_simple_socket.hpp>
#include <srs_kernel_log.hpp>
#include <srs_protocol_utility.hpp>
#include <srs_core_autofree.hpp>
#include <srs_protocol_rtmp_stack.hpp>
// if user want to define log, define the folowing macro.
#ifndef SRS_RTMP_USER_DEFINED_LOG
... ... @@ -256,6 +258,79 @@ int srs_publish_stream(srs_rtmp_t rtmp)
return ret;
}
const char* srs_type2string(int type)
{
switch (type) {
case SRS_RTMP_TYPE_AUDIO: return "Audio";
case SRS_RTMP_TYPE_VIDEO: return "Video";
case SRS_RTMP_TYPE_SCRIPT: return "Data";
default: return "Unknown";
}
return "Unknown";
}
int srs_read_packet(srs_rtmp_t rtmp, int* type, u_int32_t* timestamp, char** data, int* size)
{
*type = 0;
*timestamp = 0;
*data = NULL;
*size = 0;
int ret = ERROR_SUCCESS;
srs_assert(rtmp != NULL);
Context* context = (Context*)rtmp;
for (;;) {
SrsCommonMessage* msg = NULL;
if ((ret = context->rtmp->recv_message(&msg)) != ERROR_SUCCESS) {
return ret;
}
if (!msg) {
continue;
}
SrsAutoFree(SrsCommonMessage, msg, false);
if (msg->header.is_audio()) {
*type = SRS_RTMP_TYPE_AUDIO;
*timestamp = (u_int32_t)msg->header.timestamp;
*data = (char*)msg->payload;
*size = (int)msg->size;
// detach bytes from packet.
msg->payload = NULL;
} else if (msg->header.is_video()) {
*type = SRS_RTMP_TYPE_VIDEO;
*timestamp = (u_int32_t)msg->header.timestamp;
*data = (char*)msg->payload;
*size = (int)msg->size;
// detach bytes from packet.
msg->payload = NULL;
} else if (msg->header.is_amf0_data() || msg->header.is_amf3_data()) {
*type = SRS_RTMP_TYPE_SCRIPT;
*data = (char*)msg->payload;
*size = (int)msg->size;
// detach bytes from packet.
msg->payload = NULL;
} else {
// ignore and continue
continue;
}
// got expected message.
break;
}
return ret;
}
int srs_write_packet(srs_rtmp_t rtmp, int type, u_int32_t timestamp, char* data, int size)
{
int ret = ERROR_SUCCESS;
return ret;
}
int srs_ssl_enabled()
{
#ifndef SRS_SSL
... ...
... ... @@ -28,6 +28,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include <srs_librtmp.h>
*/
#include <sys/types.h>
/**
* srs-librtmp is a librtmp like library,
* used to play/publish rtmp stream from/to rtmp server.
... ... @@ -101,6 +103,43 @@ int srs_play_stream(srs_rtmp_t rtmp);
int srs_publish_stream(srs_rtmp_t rtmp);
/**
* E.4.1 FLV Tag, page 75
*/
// 8 = audio
#define SRS_RTMP_TYPE_AUDIO 8
// 9 = video
#define SRS_RTMP_TYPE_VIDEO 9
// 18 = script data
#define SRS_RTMP_TYPE_SCRIPT 18
/**
* convert the flv tag type to string.
* SRS_RTMP_TYPE_AUDIO to "Audio"
* SRS_RTMP_TYPE_VIDEO to "Video"
* SRS_RTMP_TYPE_SCRIPT to "Data"
* otherwise, "Unknown"
*/
const char* srs_type2string(int type);
/**
* read a audio/video/script-data packet from rtmp stream.
* @param type, output the packet type, macros:
* SRS_RTMP_TYPE_AUDIO, FlvTagAudio
* SRS_RTMP_TYPE_VIDEO, FlvTagVideo
* SRS_RTMP_TYPE_SCRIPT, FlvTagScript
* @param timestamp, in ms, overflow in 50days
* @param data, the packet data, according to type:
* FlvTagAudio, @see "E.4.2.1 AUDIODATA"
* FlvTagVideo, @see "E.4.3.1 VIDEODATA"
* FlvTagScript, @see "E.4.4.1 SCRIPTDATA"
* @param size, size of packet.
* @return the error code. 0 for success; otherwise, error.
*
* @remark: for read, user must free the data.
* @remark: for write, user should never free the data, even if error.
*/
int srs_read_packet(srs_rtmp_t rtmp, int* type, u_int32_t* timestamp, char** data, int* size);
int srs_write_packet(srs_rtmp_t rtmp, int type, u_int32_t timestamp, char* data, int size);
/**
* whether srs is compiled with ssl,
* that is, compile srs with ssl: ./configure --with-ssl,.
* if no ssl, complex handshake always error.
... ...
... ... @@ -1025,6 +1025,14 @@ int SrsProtocol::read_message_header(SrsChunkStream* chunk, char fmt, int bh_siz
// ffmpeg/librtmp may donot send this filed, need to detect the value.
// @see also: http://blog.csdn.net/win_lin/article/details/13363699
// the extended-timestamp must be unsigned-int,
// 24bits timestamp: 0xffffff = 16777215ms = 16777.215s = 4.66h
// 32bits timestamp: 0xffffffff = 4294967295ms = 4294967.295s = 1193.046h = 49.71d
// because the rtmp protocol says the 32bits timestamp is about "50 days":
// 3. Byte Order, Alignment, and Time Format
// Because timestamps are generally only 32 bits long, they will roll
// over after fewer than 50 days.
// so, use u_int32_t is right.
u_int32_t timestamp = 0x00;
char* pp = (char*)&timestamp;
pp[3] = *p++;
... ...