refine the protocol, add comments, add utest for empty packet
正在显示
3 个修改的文件
包含
51 行增加
和
18 行删除
| @@ -497,6 +497,8 @@ int SrsProtocol::do_send_message(SrsMessage* msg, SrsPacket* packet) | @@ -497,6 +497,8 @@ int SrsProtocol::do_send_message(SrsMessage* msg, SrsPacket* packet) | ||
| 497 | } | 497 | } |
| 498 | } else { | 498 | } else { |
| 499 | // write no message header chunk stream, fmt is 3 | 499 | // write no message header chunk stream, fmt is 3 |
| 500 | + // @remark, if perfer_cid > 0x3F, that is, use 2B/3B chunk header, | ||
| 501 | + // SRS will rollback to 1B chunk header. | ||
| 500 | *pheader++ = 0xC0 | (msg->header.perfer_cid & 0x3F); | 502 | *pheader++ = 0xC0 | (msg->header.perfer_cid & 0x3F); |
| 501 | 503 | ||
| 502 | // chunk extended timestamp header, 0 or 4 bytes, big-endian | 504 | // chunk extended timestamp header, 0 or 4 bytes, big-endian |
| @@ -550,7 +552,8 @@ int SrsProtocol::do_send_message(SrsMessage* msg, SrsPacket* packet) | @@ -550,7 +552,8 @@ int SrsProtocol::do_send_message(SrsMessage* msg, SrsPacket* packet) | ||
| 550 | } | 552 | } |
| 551 | } while (p < (char*)msg->payload + msg->size); | 553 | } while (p < (char*)msg->payload + msg->size); |
| 552 | 554 | ||
| 553 | - if ((ret = on_send_message(msg, packet)) != ERROR_SUCCESS) { | 555 | + // only process the callback event when with packet |
| 556 | + if (packet && (ret = on_send_packet(msg, packet)) != ERROR_SUCCESS) { | ||
| 554 | srs_error("hook the send message failed. ret=%d", ret); | 557 | srs_error("hook the send message failed. ret=%d", ret); |
| 555 | return ret; | 558 | return ret; |
| 556 | } | 559 | } |
| @@ -1224,7 +1227,7 @@ int SrsProtocol::read_message_header(SrsChunkStream* chunk, char fmt, int bh_siz | @@ -1224,7 +1227,7 @@ int SrsProtocol::read_message_header(SrsChunkStream* chunk, char fmt, int bh_siz | ||
| 1224 | */ | 1227 | */ |
| 1225 | if (!is_first_chunk_of_msg && chunk_timestamp > 0 && chunk_timestamp != timestamp) { | 1228 | if (!is_first_chunk_of_msg && chunk_timestamp > 0 && chunk_timestamp != timestamp) { |
| 1226 | mh_size -= 4; | 1229 | mh_size -= 4; |
| 1227 | - srs_warn("no 4bytes extended timestamp in the continued chunk"); | 1230 | + srs_info("no 4bytes extended timestamp in the continued chunk"); |
| 1228 | } else { | 1231 | } else { |
| 1229 | chunk->header.timestamp = timestamp; | 1232 | chunk->header.timestamp = timestamp; |
| 1230 | } | 1233 | } |
| @@ -1251,18 +1254,11 @@ int SrsProtocol::read_message_header(SrsChunkStream* chunk, char fmt, int bh_siz | @@ -1251,18 +1254,11 @@ int SrsProtocol::read_message_header(SrsChunkStream* chunk, char fmt, int bh_siz | ||
| 1251 | // milliseconds. | 1254 | // milliseconds. |
| 1252 | // in a word, 31bits timestamp is ok. | 1255 | // in a word, 31bits timestamp is ok. |
| 1253 | // convert extended timestamp to 31bits. | 1256 | // convert extended timestamp to 31bits. |
| 1254 | - if (chunk->header.timestamp > 0x7fffffff) { | ||
| 1255 | - srs_warn("RTMP 31bits timestamp overflow, time=%"PRId64, chunk->header.timestamp); | ||
| 1256 | - } | ||
| 1257 | chunk->header.timestamp &= 0x7fffffff; | 1257 | chunk->header.timestamp &= 0x7fffffff; |
| 1258 | 1258 | ||
| 1259 | - // valid message | ||
| 1260 | - if (chunk->header.payload_length < 0) { | ||
| 1261 | - ret = ERROR_RTMP_MSG_INVLIAD_SIZE; | ||
| 1262 | - srs_error("RTMP message size must not be negative. size=%d, ret=%d", | ||
| 1263 | - chunk->header.payload_length, ret); | ||
| 1264 | - return ret; | ||
| 1265 | - } | 1259 | + // valid message, the payload_length is 24bits, |
| 1260 | + // so it should never be negative. | ||
| 1261 | + srs_assert(chunk->header.payload_length >= 0); | ||
| 1266 | 1262 | ||
| 1267 | // copy header to msg | 1263 | // copy header to msg |
| 1268 | chunk->msg->header = chunk->header; | 1264 | chunk->msg->header = chunk->header; |
| @@ -1417,14 +1413,12 @@ int SrsProtocol::on_recv_message(SrsMessage* msg) | @@ -1417,14 +1413,12 @@ int SrsProtocol::on_recv_message(SrsMessage* msg) | ||
| 1417 | return ret; | 1413 | return ret; |
| 1418 | } | 1414 | } |
| 1419 | 1415 | ||
| 1420 | -int SrsProtocol::on_send_message(SrsMessage* msg, SrsPacket* packet) | 1416 | +int SrsProtocol::on_send_packet(SrsMessage* msg, SrsPacket* packet) |
| 1421 | { | 1417 | { |
| 1422 | int ret = ERROR_SUCCESS; | 1418 | int ret = ERROR_SUCCESS; |
| 1423 | 1419 | ||
| 1424 | - // ignore raw bytes oriented RTMP message. | ||
| 1425 | - if (!packet) { | ||
| 1426 | - return ret; | ||
| 1427 | - } | 1420 | + // should never be raw bytes oriented RTMP message. |
| 1421 | + srs_assert(packet); | ||
| 1428 | 1422 | ||
| 1429 | switch (msg->header.message_type) { | 1423 | switch (msg->header.message_type) { |
| 1430 | case RTMP_MSG_SetChunkSize: { | 1424 | case RTMP_MSG_SetChunkSize: { |
| @@ -170,6 +170,7 @@ public: | @@ -170,6 +170,7 @@ public: | ||
| 170 | * always NULL if error, | 170 | * always NULL if error, |
| 171 | * NULL for unknown packet but return success. | 171 | * NULL for unknown packet but return success. |
| 172 | * never NULL if decode success. | 172 | * never NULL if decode success. |
| 173 | + * @remark, drop message when msg is empty or payload length is empty. | ||
| 173 | */ | 174 | */ |
| 174 | virtual int recv_message(SrsMessage** pmsg); | 175 | virtual int recv_message(SrsMessage** pmsg); |
| 175 | /** | 176 | /** |
| @@ -237,7 +238,7 @@ private: | @@ -237,7 +238,7 @@ private: | ||
| 237 | /** | 238 | /** |
| 238 | * when message sentout, update the context. | 239 | * when message sentout, update the context. |
| 239 | */ | 240 | */ |
| 240 | - virtual int on_send_message(SrsMessage* msg, SrsPacket* packet); | 241 | + virtual int on_send_packet(SrsMessage* msg, SrsPacket* packet); |
| 241 | private: | 242 | private: |
| 242 | /** | 243 | /** |
| 243 | * auto response the ack message. | 244 | * auto response the ack message. |
| @@ -4425,3 +4425,41 @@ VOID TEST(ProtocolStackTest, ProtocolRecvVCid3BMax) | @@ -4425,3 +4425,41 @@ VOID TEST(ProtocolStackTest, ProtocolRecvVCid3BMax) | ||
| 4425 | EXPECT_EQ(65599, msg->header.perfer_cid); | 4425 | EXPECT_EQ(65599, msg->header.perfer_cid); |
| 4426 | } | 4426 | } |
| 4427 | 4427 | ||
| 4428 | +/** | ||
| 4429 | +* recv a zero length video message. | ||
| 4430 | +*/ | ||
| 4431 | +VOID TEST(ProtocolStackTest, ProtocolRecvV0LenMessage) | ||
| 4432 | +{ | ||
| 4433 | + MockBufferIO bio; | ||
| 4434 | + SrsProtocol proto(&bio); | ||
| 4435 | + | ||
| 4436 | + // video message | ||
| 4437 | + char data[] = { | ||
| 4438 | + // video #1 | ||
| 4439 | + // 12bytes header, 1byts chunk header, 11bytes msg heder | ||
| 4440 | + (char)0x03, | ||
| 4441 | + (char)0x00, (char)0x00, (char)0x00, // timestamp | ||
| 4442 | + (char)0x00, (char)0x00, (char)0x00, // length | ||
| 4443 | + (char)0x09, // message_type | ||
| 4444 | + (char)0x00, (char)0x00, (char)0x00, (char)0x00, // stream_id | ||
| 4445 | + | ||
| 4446 | + // video #2 | ||
| 4447 | + // 12bytes header, 1byts chunk header, 11bytes msg heder | ||
| 4448 | + (char)0x03, | ||
| 4449 | + (char)0x00, (char)0x00, (char)0x00, // timestamp | ||
| 4450 | + (char)0x00, (char)0x00, (char)0x04, // length | ||
| 4451 | + (char)0x09, // message_type | ||
| 4452 | + (char)0x00, (char)0x00, (char)0x00, (char)0x00, // stream_id | ||
| 4453 | + // msg payload start | ||
| 4454 | + (char)0x00, (char)0x00, (char)0x07, (char)0x63 | ||
| 4455 | + }; | ||
| 4456 | + bio.in_buffer.append(data, sizeof(data)); | ||
| 4457 | + | ||
| 4458 | + SrsMessage* msg = NULL; | ||
| 4459 | + ASSERT_TRUE(ERROR_SUCCESS == proto.recv_message(&msg)); | ||
| 4460 | + SrsAutoFree(SrsMessage, msg); | ||
| 4461 | + EXPECT_TRUE(msg->header.is_video()); | ||
| 4462 | + // protocol stack will ignore the empty video message. | ||
| 4463 | + EXPECT_EQ(4, msg->header.payload_length); | ||
| 4464 | +} | ||
| 4465 | + |
-
请 注册 或 登录 后发表评论