Skip to content

Commit

Permalink
Support FFmpeg timecode, fix AMF0 parsing failed. v5.0.179 (#3804)
Browse files Browse the repository at this point in the history
Please see #3803 for detail:

1. When using FFmpeg with the `-map 0` option, there may be a 4-byte
timecode in the AMF0 Data.
2. SRS should be able to handle this packet without causing a parsing
error, as it's generally expected to be an AMF0 string, not a 4-byte
timecode.
3. Disregard the timecode since SRS doesn't utilize it.

See [Error submitting a packet to the muxer: Broken pipe, Error muxing a
packet](https://trac.ffmpeg.org/ticket/10565)

---------

Co-authored-by: john <hondaxiao@tencent.com>
  • Loading branch information
winlinvip and xiaozhihong committed Sep 18, 2023
1 parent b352fd0 commit bc0a516
Show file tree
Hide file tree
Showing 7 changed files with 76 additions and 67 deletions.
1 change: 1 addition & 0 deletions trunk/doc/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ The changelog for SRS.
<a name="v5-changes"></a>

## 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)
Expand Down
59 changes: 0 additions & 59 deletions trunk/src/app/srs_app_utility.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
7 changes: 0 additions & 7 deletions trunk/src/app/srs_app_utility.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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") === srs_getenv("$EIP")
extern std::string srs_getenv(const std::string& key);
Expand Down
2 changes: 1 addition & 1 deletion trunk/src/core/srs_core_version5.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@

#define VERSION_MAJOR 5
#define VERSION_MINOR 0
#define VERSION_REVISION 178
#define VERSION_REVISION 179

#endif
6 changes: 6 additions & 0 deletions trunk/src/protocol/srs_protocol_rtmp_stack.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
61 changes: 61 additions & 0 deletions trunk/src/protocol/srs_protocol_utility.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ using namespace std;
#include <srs_protocol_rtmp_stack.hpp>
#include <srs_protocol_io.hpp>

#include <limits.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <net/if.h>
Expand Down Expand Up @@ -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);
}

7 changes: 7 additions & 0 deletions trunk/src/protocol/srs_protocol_utility.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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

0 comments on commit bc0a516

Please sign in to comment.