diff --git a/trunk/doc/CHANGELOG.md b/trunk/doc/CHANGELOG.md
index b58b10ac6b..cbaf484e10 100644
--- a/trunk/doc/CHANGELOG.md
+++ b/trunk/doc/CHANGELOG.md
@@ -7,6 +7,7 @@ The changelog for SRS.
## SRS 6.0 Changelog
+* v6.0, 2023-09-18, Merge [#3804](https://github.com/ossrs/srs/pull/3804): Support FFmpeg timecode, fix AMF0 parsing failed. v6.0.77 (#3804)
* v6.0, 2023-09-18, Merge [#3722](https://github.com/ossrs/srs/pull/3722): Bugfix: HEVC SRT stream supports multiple PPS fields. v6.0.76 (#3722)
* v6.0, 2023-09-08, Merge [#3597](https://github.com/ossrs/srs/pull/3597): Fix RBSP stream parsing bug, should drop 0x03. v6.0.75 (#3597)
* v6.0, 2023-09-08, Merge [#3794](https://github.com/ossrs/srs/pull/3794): Support SRS Stack token for authentication. v6.0.74 (#3794)
@@ -88,6 +89,7 @@ The changelog for SRS.
## SRS 5.0 Changelog
+* v5.0, 2023-09-18, Merge [#3804](https://github.com/ossrs/srs/pull/3804): Support FFmpeg timecode, fix AMF0 parsing failed. v5.0.179 (#3804)
* v5.0, 2023-09-08, Merge [#3597](https://github.com/ossrs/srs/pull/3597): Fix RBSP stream parsing bug, should drop 0x03. v5.0.178 (#3597)
* v5.0, 2023-09-07, Merge [#3795](https://github.com/ossrs/srs/pull/3795): Fix dash crash if format not supported. v5.0.177 (#3795)
* v5.0, 2023-08-30, Merge [#3779](https://github.com/ossrs/srs/pull/3779): Support HTTP-API for fetching reload result. v5.0.176 (#3779)
diff --git a/trunk/src/app/srs_app_utility.cpp b/trunk/src/app/srs_app_utility.cpp
index 3af4b6d52d..ea2d61516e 100644
--- a/trunk/src/app/srs_app_utility.cpp
+++ b/trunk/src/app/srs_app_utility.cpp
@@ -1379,65 +1379,6 @@ void srs_api_dump_summaries(SrsJsonObject* obj)
sys->set("conn_srs", SrsJsonAny::integer(nrs->nb_conn_srs));
}
-string srs_string_dumps_hex(const std::string& str)
-{
- return srs_string_dumps_hex(str.c_str(), str.size());
-}
-
-string srs_string_dumps_hex(const char* str, int length)
-{
- return srs_string_dumps_hex(str, length, INT_MAX);
-}
-
-string srs_string_dumps_hex(const char* str, int length, int limit)
-{
- return srs_string_dumps_hex(str, length, limit, ' ', 128, '\n');
-}
-
-string srs_string_dumps_hex(const char* str, int length, int limit, char seperator, int line_limit, char newline)
-{
- // 1 byte trailing '\0'.
- const int LIMIT = 1024*16 + 1;
- static char buf[LIMIT];
-
- int len = 0;
- for (int i = 0; i < length && i < limit && len < LIMIT; ++i) {
- int nb = snprintf(buf + len, LIMIT - len, "%02x", (uint8_t)str[i]);
- if (nb <= 0 || nb >= LIMIT - len) {
- break;
- }
- len += nb;
-
- // Only append seperator and newline when not last byte.
- if (i < length - 1 && i < limit - 1 && len < LIMIT) {
- if (seperator) {
- buf[len++] = seperator;
- }
-
- if (newline && line_limit && i > 0 && ((i + 1) % line_limit) == 0) {
- buf[len++] = newline;
- }
- }
- }
-
- // Empty string.
- if (len <= 0) {
- return "";
- }
-
- // If overflow, cut the trailing newline.
- if (newline && len >= LIMIT - 2 && buf[len - 1] == newline) {
- len--;
- }
-
- // If overflow, cut the trailing seperator.
- if (seperator && len >= LIMIT - 3 && buf[len - 1] == seperator) {
- len--;
- }
-
- return string(buf, len);
-}
-
string srs_getenv(const string& key)
{
string ekey = key;
diff --git a/trunk/src/app/srs_app_utility.hpp b/trunk/src/app/srs_app_utility.hpp
index 23074ce7b3..84f413dfe8 100644
--- a/trunk/src/app/srs_app_utility.hpp
+++ b/trunk/src/app/srs_app_utility.hpp
@@ -677,13 +677,6 @@ extern bool srs_is_boolean(std::string str);
// Dump summaries for /api/v1/summaries.
extern void srs_api_dump_summaries(SrsJsonObject* obj);
-// Dump string(str in length) to hex, it will process min(limit, length) chars.
-// Append seperator between each elem, and newline when exceed line_limit, '\0' to ignore.
-extern std::string srs_string_dumps_hex(const std::string& str);
-extern std::string srs_string_dumps_hex(const char* str, int length);
-extern std::string srs_string_dumps_hex(const char* str, int length, int limit);
-extern std::string srs_string_dumps_hex(const char* str, int length, int limit, char seperator, int line_limit, char newline);
-
// Get ENV variable, which may starts with $.
// srs_getenv("EIP") is srs_getenv("$EIP")
extern std::string srs_getenv(const std::string& key);
diff --git a/trunk/src/core/srs_core_version5.hpp b/trunk/src/core/srs_core_version5.hpp
index 163f2a2a67..f37c0df662 100644
--- a/trunk/src/core/srs_core_version5.hpp
+++ b/trunk/src/core/srs_core_version5.hpp
@@ -9,6 +9,6 @@
#define VERSION_MAJOR 5
#define VERSION_MINOR 0
-#define VERSION_REVISION 178
+#define VERSION_REVISION 179
#endif
diff --git a/trunk/src/core/srs_core_version6.hpp b/trunk/src/core/srs_core_version6.hpp
index 43e4f07f40..a4762604d2 100644
--- a/trunk/src/core/srs_core_version6.hpp
+++ b/trunk/src/core/srs_core_version6.hpp
@@ -9,6 +9,6 @@
#define VERSION_MAJOR 6
#define VERSION_MINOR 0
-#define VERSION_REVISION 76
+#define VERSION_REVISION 77
#endif
diff --git a/trunk/src/protocol/srs_protocol_rtmp_stack.cpp b/trunk/src/protocol/srs_protocol_rtmp_stack.cpp
index 83426b1427..63f19b8a83 100644
--- a/trunk/src/protocol/srs_protocol_rtmp_stack.cpp
+++ b/trunk/src/protocol/srs_protocol_rtmp_stack.cpp
@@ -595,6 +595,12 @@ srs_error_t SrsProtocol::do_decode_message(SrsMessageHeader& header, SrsBuffer*
// decode specified packet type
if (header.is_amf0_command() || header.is_amf3_command() || header.is_amf0_data() || header.is_amf3_data()) {
+ // Ignore FFmpeg timecode, see https://github.com/ossrs/srs/issues/3803
+ if (stream->left() == 4 && (uint8_t)*stream->head() == 0x00) {
+ srs_warn("Ignore FFmpeg timecode, data=[%s]", srs_string_dumps_hex(stream->head(), 4).c_str());
+ return err;
+ }
+
// skip 1bytes to decode the amf3 command.
if (header.is_amf3_command() && stream->require(1)) {
stream->skip(1);
diff --git a/trunk/src/protocol/srs_protocol_utility.cpp b/trunk/src/protocol/srs_protocol_utility.cpp
index efddea33f4..dd3a34a571 100644
--- a/trunk/src/protocol/srs_protocol_utility.cpp
+++ b/trunk/src/protocol/srs_protocol_utility.cpp
@@ -24,6 +24,7 @@ using namespace std;
#include
#include
+#include
#include
#include
#include
@@ -962,3 +963,63 @@ utsname* srs_get_system_uname_info()
return system_info;
}
#endif
+
+string srs_string_dumps_hex(const std::string& str)
+{
+ return srs_string_dumps_hex(str.c_str(), str.size());
+}
+
+string srs_string_dumps_hex(const char* str, int length)
+{
+ return srs_string_dumps_hex(str, length, INT_MAX);
+}
+
+string srs_string_dumps_hex(const char* str, int length, int limit)
+{
+ return srs_string_dumps_hex(str, length, limit, ' ', 128, '\n');
+}
+
+string srs_string_dumps_hex(const char* str, int length, int limit, char seperator, int line_limit, char newline)
+{
+ // 1 byte trailing '\0'.
+ const int LIMIT = 1024*16 + 1;
+ static char buf[LIMIT];
+
+ int len = 0;
+ for (int i = 0; i < length && i < limit && len < LIMIT; ++i) {
+ int nb = snprintf(buf + len, LIMIT - len, "%02x", (uint8_t)str[i]);
+ if (nb <= 0 || nb >= LIMIT - len) {
+ break;
+ }
+ len += nb;
+
+ // Only append seperator and newline when not last byte.
+ if (i < length - 1 && i < limit - 1 && len < LIMIT) {
+ if (seperator) {
+ buf[len++] = seperator;
+ }
+
+ if (newline && line_limit && i > 0 && ((i + 1) % line_limit) == 0) {
+ buf[len++] = newline;
+ }
+ }
+ }
+
+ // Empty string.
+ if (len <= 0) {
+ return "";
+ }
+
+ // If overflow, cut the trailing newline.
+ if (newline && len >= LIMIT - 2 && buf[len - 1] == newline) {
+ len--;
+ }
+
+ // If overflow, cut the trailing seperator.
+ if (seperator && len >= LIMIT - 3 && buf[len - 1] == seperator) {
+ len--;
+ }
+
+ return string(buf, len);
+}
+
diff --git a/trunk/src/protocol/srs_protocol_utility.hpp b/trunk/src/protocol/srs_protocol_utility.hpp
index f51ca2e4cd..eaa853b9e3 100644
--- a/trunk/src/protocol/srs_protocol_utility.hpp
+++ b/trunk/src/protocol/srs_protocol_utility.hpp
@@ -196,5 +196,12 @@ extern srs_error_t srs_ioutil_read_all(ISrsReader* in, std::string& content);
extern utsname* srs_get_system_uname_info();
#endif
+// Dump string(str in length) to hex, it will process min(limit, length) chars.
+// Append seperator between each elem, and newline when exceed line_limit, '\0' to ignore.
+extern std::string srs_string_dumps_hex(const std::string& str);
+extern std::string srs_string_dumps_hex(const char* str, int length);
+extern std::string srs_string_dumps_hex(const char* str, int length, int limit);
+extern std::string srs_string_dumps_hex(const char* str, int length, int limit, char seperator, int line_limit, char newline);
+
#endif