mirror of
https://github.com/ossrs/srs.git
synced 2025-03-09 15:49:59 +00:00
Merge branch v5.0.116 into develop
1. MP3: Fix bug for TS or HLS with mp3 codec. v4.0.269 (#296) (#3333) 2. MP3: Add config examples for MP3. #296 3. Script: Refine GitHub actions.
This commit is contained in:
commit
b5aaf67c93
16 changed files with 212 additions and 55 deletions
2
.github/workflows/codeql-analysis.yml
vendored
2
.github/workflows/codeql-analysis.yml
vendored
|
@ -6,7 +6,7 @@ on: [push, pull_request]
|
||||||
jobs:
|
jobs:
|
||||||
analyze:
|
analyze:
|
||||||
name: actions-codeql-analyze
|
name: actions-codeql-analyze
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-20.04
|
||||||
|
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
|
|
80
.github/workflows/test.yml
vendored
80
.github/workflows/test.yml
vendored
|
@ -3,6 +3,22 @@ name: "Test"
|
||||||
# @see https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions#onpushpull_requestbranchestags
|
# @see https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions#onpushpull_requestbranchestags
|
||||||
on: [push, pull_request]
|
on: [push, pull_request]
|
||||||
|
|
||||||
|
# The dependency graph:
|
||||||
|
# multiple-arch-armv7(13m)
|
||||||
|
# multiple-arch-aarch64(7m)
|
||||||
|
# cygwin64-cache(1m)
|
||||||
|
# cygwin64(6m) - Must depends on cygwin64-cache.
|
||||||
|
# fast(0s) - To limit all fastly run jobs after slow jobs.
|
||||||
|
# build-centos7(3m)
|
||||||
|
# build-ubuntu16(3m)
|
||||||
|
# build-ubuntu18(2m)
|
||||||
|
# build-ubuntu20(2m)
|
||||||
|
# build-cross-arm(3m)
|
||||||
|
# build-cross-aarch64(3m)
|
||||||
|
# multiple-arch-amd64(2m)
|
||||||
|
# utest(3m)
|
||||||
|
# coverage(3m) - Must depends on utest.
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
cygwin64-cache:
|
cygwin64-cache:
|
||||||
name: cygwin64-cache
|
name: cygwin64-cache
|
||||||
|
@ -66,7 +82,7 @@ jobs:
|
||||||
name: build-centos7
|
name: build-centos7
|
||||||
runs-on: ubuntu-20.04
|
runs-on: ubuntu-20.04
|
||||||
needs:
|
needs:
|
||||||
- utest
|
- fast
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v2
|
||||||
|
@ -88,7 +104,7 @@ jobs:
|
||||||
name: build-ubuntu16
|
name: build-ubuntu16
|
||||||
runs-on: ubuntu-20.04
|
runs-on: ubuntu-20.04
|
||||||
needs:
|
needs:
|
||||||
- utest
|
- fast
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v2
|
||||||
|
@ -104,7 +120,7 @@ jobs:
|
||||||
name: build-ubuntu18
|
name: build-ubuntu18
|
||||||
runs-on: ubuntu-20.04
|
runs-on: ubuntu-20.04
|
||||||
needs:
|
needs:
|
||||||
- utest
|
- fast
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v2
|
||||||
|
@ -120,7 +136,7 @@ jobs:
|
||||||
name: build-ubuntu20
|
name: build-ubuntu20
|
||||||
runs-on: ubuntu-20.04
|
runs-on: ubuntu-20.04
|
||||||
needs:
|
needs:
|
||||||
- utest
|
- fast
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v2
|
||||||
|
@ -135,6 +151,8 @@ jobs:
|
||||||
build-cross-arm:
|
build-cross-arm:
|
||||||
name: build-cross-arm
|
name: build-cross-arm
|
||||||
runs-on: ubuntu-20.04
|
runs-on: ubuntu-20.04
|
||||||
|
needs:
|
||||||
|
- fast
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v2
|
||||||
|
@ -148,6 +166,8 @@ jobs:
|
||||||
build-cross-aarch64:
|
build-cross-aarch64:
|
||||||
name: build-cross-aarch64
|
name: build-cross-aarch64
|
||||||
runs-on: ubuntu-20.04
|
runs-on: ubuntu-20.04
|
||||||
|
needs:
|
||||||
|
- fast
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v2
|
||||||
|
@ -158,21 +178,6 @@ jobs:
|
||||||
outputs:
|
outputs:
|
||||||
SRS_BUILD_CROSS_AARCH64_DONE: ok
|
SRS_BUILD_CROSS_AARCH64_DONE: ok
|
||||||
|
|
||||||
build:
|
|
||||||
name: build
|
|
||||||
needs:
|
|
||||||
- build-centos7
|
|
||||||
- build-ubuntu16
|
|
||||||
- build-ubuntu18
|
|
||||||
- build-ubuntu20
|
|
||||||
- build-cross-arm
|
|
||||||
- build-cross-aarch64
|
|
||||||
runs-on: ubuntu-20.04
|
|
||||||
steps:
|
|
||||||
- run: echo 'Build done'
|
|
||||||
outputs:
|
|
||||||
SRS_BUILD_DONE: ok
|
|
||||||
|
|
||||||
utest:
|
utest:
|
||||||
name: utest
|
name: utest
|
||||||
runs-on: ubuntu-20.04
|
runs-on: ubuntu-20.04
|
||||||
|
@ -229,8 +234,8 @@ jobs:
|
||||||
outputs:
|
outputs:
|
||||||
SRS_COVERAGE_DONE: ok
|
SRS_COVERAGE_DONE: ok
|
||||||
|
|
||||||
multile-arch-armv7:
|
multiple-arch-armv7:
|
||||||
name: multile-arch-armv7
|
name: multiple-arch-armv7
|
||||||
runs-on: ubuntu-20.04
|
runs-on: ubuntu-20.04
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
|
@ -251,8 +256,8 @@ jobs:
|
||||||
outputs:
|
outputs:
|
||||||
SRS_MULTIPLE_ARCH_ARMV7_DONE: ok
|
SRS_MULTIPLE_ARCH_ARMV7_DONE: ok
|
||||||
|
|
||||||
multile-arch-aarch64:
|
multiple-arch-aarch64:
|
||||||
name: multile-arch-aarch64
|
name: multiple-arch-aarch64
|
||||||
runs-on: ubuntu-20.04
|
runs-on: ubuntu-20.04
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
|
@ -273,11 +278,11 @@ jobs:
|
||||||
outputs:
|
outputs:
|
||||||
SRS_MULTIPLE_ARCH_AARCH64_DONE: ok
|
SRS_MULTIPLE_ARCH_AARCH64_DONE: ok
|
||||||
|
|
||||||
multile-arch-amd64:
|
multiple-arch-amd64:
|
||||||
name: multile-arch-amd64
|
name: multiple-arch-amd64
|
||||||
runs-on: ubuntu-20.04
|
runs-on: ubuntu-20.04
|
||||||
needs:
|
needs:
|
||||||
- utest
|
- fast
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v2
|
||||||
|
@ -297,15 +302,30 @@ jobs:
|
||||||
outputs:
|
outputs:
|
||||||
SRS_MULTIPLE_ARCH_AMD64_DONE: ok
|
SRS_MULTIPLE_ARCH_AMD64_DONE: ok
|
||||||
|
|
||||||
|
fast:
|
||||||
|
name: fast
|
||||||
|
needs:
|
||||||
|
- cygwin64-cache
|
||||||
|
runs-on: ubuntu-20.04
|
||||||
|
steps:
|
||||||
|
- run: echo 'Start fast jobs'
|
||||||
|
outputs:
|
||||||
|
SRS_FAST_DONE: ok
|
||||||
|
|
||||||
done:
|
done:
|
||||||
name: done
|
name: done
|
||||||
needs:
|
needs:
|
||||||
- cygwin64
|
- cygwin64
|
||||||
- build
|
|
||||||
- coverage
|
- coverage
|
||||||
- multile-arch-armv7
|
- build-centos7
|
||||||
- multile-arch-aarch64
|
- build-ubuntu16
|
||||||
- multile-arch-amd64
|
- build-ubuntu18
|
||||||
|
- build-ubuntu20
|
||||||
|
- build-cross-arm
|
||||||
|
- build-cross-aarch64
|
||||||
|
- multiple-arch-armv7
|
||||||
|
- multiple-arch-aarch64
|
||||||
|
- multiple-arch-amd64
|
||||||
runs-on: ubuntu-20.04
|
runs-on: ubuntu-20.04
|
||||||
steps:
|
steps:
|
||||||
- run: echo 'All done'
|
- run: echo 'All done'
|
||||||
|
|
19
trunk/conf/mp3.conf
Normal file
19
trunk/conf/mp3.conf
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
listen 1935;
|
||||||
|
max_connections 1000;
|
||||||
|
daemon off;
|
||||||
|
srs_log_tank console;
|
||||||
|
http_server {
|
||||||
|
enabled on;
|
||||||
|
listen 8080;
|
||||||
|
dir ./objs/nginx/html;
|
||||||
|
}
|
||||||
|
vhost __defaultVhost__ {
|
||||||
|
http_remux {
|
||||||
|
enabled on;
|
||||||
|
mount [vhost]/[app]/[stream].flv;
|
||||||
|
}
|
||||||
|
hls {
|
||||||
|
enabled on;
|
||||||
|
hls_acodec mp3;
|
||||||
|
}
|
||||||
|
}
|
15
trunk/conf/mp3.http.conf
Normal file
15
trunk/conf/mp3.http.conf
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
listen 1935;
|
||||||
|
max_connections 1000;
|
||||||
|
daemon off;
|
||||||
|
srs_log_tank console;
|
||||||
|
http_server {
|
||||||
|
enabled on;
|
||||||
|
listen 8080;
|
||||||
|
dir ./objs/nginx/html;
|
||||||
|
}
|
||||||
|
vhost __defaultVhost__ {
|
||||||
|
http_remux {
|
||||||
|
enabled on;
|
||||||
|
mount [vhost]/[app]/[stream].mp3;
|
||||||
|
}
|
||||||
|
}
|
15
trunk/conf/mp3.ts.conf
Normal file
15
trunk/conf/mp3.ts.conf
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
listen 1935;
|
||||||
|
max_connections 1000;
|
||||||
|
daemon off;
|
||||||
|
srs_log_tank console;
|
||||||
|
http_server {
|
||||||
|
enabled on;
|
||||||
|
listen 8080;
|
||||||
|
dir ./objs/nginx/html;
|
||||||
|
}
|
||||||
|
vhost __defaultVhost__ {
|
||||||
|
http_remux {
|
||||||
|
enabled on;
|
||||||
|
mount [vhost]/[app]/[stream].ts;
|
||||||
|
}
|
||||||
|
}
|
|
@ -20,6 +20,7 @@ The changelog for SRS.
|
||||||
|
|
||||||
## SRS 5.0 Changelog
|
## SRS 5.0 Changelog
|
||||||
|
|
||||||
|
* v5.0, 2022-12-25, For [#296](https://github.com/ossrs/srs/issues/296): MP3: Support mp3 for RTMP/HLS/HTTP-FLV/HTTP-TS/HLS etc. v5.0.116
|
||||||
* v5.0, 2022-12-24, Fix [#3328](https://github.com/ossrs/srs/issues/3328): Docker: Avoiding duplicated copy files. v5.0.115
|
* v5.0, 2022-12-24, Fix [#3328](https://github.com/ossrs/srs/issues/3328): Docker: Avoiding duplicated copy files. v5.0.115
|
||||||
* v5.0, 2022-12-20, Merge [#3321](https://github.com/ossrs/srs/pull/3321): GB: Refine lazy object GC. v5.0.114
|
* v5.0, 2022-12-20, Merge [#3321](https://github.com/ossrs/srs/pull/3321): GB: Refine lazy object GC. v5.0.114
|
||||||
* v5.0, 2022-12-18, Merge [#3324](https://github.com/ossrs/srs/pull/3324): Asan: Support parse asan symbol backtrace log. v5.0.113
|
* v5.0, 2022-12-18, Merge [#3324](https://github.com/ossrs/srs/pull/3324): Asan: Support parse asan symbol backtrace log. v5.0.113
|
||||||
|
@ -130,6 +131,7 @@ The changelog for SRS.
|
||||||
|
|
||||||
## SRS 4.0 Changelog
|
## SRS 4.0 Changelog
|
||||||
|
|
||||||
|
* v4.0, 2022-12-24, For [#296](https://github.com/ossrs/srs/issues/296): MP3: Fix bug for TS or HLS with mp3 codec. v4.0.269
|
||||||
* v4.0, 2022-11-22, Pick [#3079](https://github.com/ossrs/srs/issues/3079): WebRTC: Fix no audio and video issue for Firefox. v4.0.268
|
* v4.0, 2022-11-22, Pick [#3079](https://github.com/ossrs/srs/issues/3079): WebRTC: Fix no audio and video issue for Firefox. v4.0.268
|
||||||
* v4.0, 2022-10-10, For [#2901](https://github.com/ossrs/srs/issues/2901): Edge: Fast disconnect and reconnect. v4.0.267
|
* v4.0, 2022-10-10, For [#2901](https://github.com/ossrs/srs/issues/2901): Edge: Fast disconnect and reconnect. v4.0.267
|
||||||
* v4.0, 2022-09-27, For [#3167](https://github.com/ossrs/srs/issues/3167): WebRTC: Refine sequence jitter algorithm. v4.0.266
|
* v4.0, 2022-09-27, For [#3167](https://github.com/ossrs/srs/issues/3167): WebRTC: Refine sequence jitter algorithm. v4.0.266
|
||||||
|
|
|
@ -1851,11 +1851,11 @@ srs_error_t SrsConfig::parse_options(int argc, char** argv)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (show_version) {
|
if (show_version) {
|
||||||
fprintf(stderr, "%s\n", RTMP_SIG_SRS_VERSION);
|
fprintf(stdout, "%s\n", RTMP_SIG_SRS_VERSION);
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
if (show_signature) {
|
if (show_signature) {
|
||||||
fprintf(stderr, "%s\n", RTMP_SIG_SRS_SERVER);
|
fprintf(stdout, "%s\n", RTMP_SIG_SRS_SERVER);
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -202,6 +202,7 @@ SrsHlsMuxer::SrsHlsMuxer()
|
||||||
async = new SrsAsyncCallWorker();
|
async = new SrsAsyncCallWorker();
|
||||||
context = new SrsTsContext();
|
context = new SrsTsContext();
|
||||||
segments = new SrsFragmentWindow();
|
segments = new SrsFragmentWindow();
|
||||||
|
latest_acodec_ = SrsAudioCodecIdForbidden;
|
||||||
|
|
||||||
memset(key, 0, 16);
|
memset(key, 0, 16);
|
||||||
memset(iv, 0, 16);
|
memset(iv, 0, 16);
|
||||||
|
@ -263,6 +264,24 @@ int SrsHlsMuxer::deviation()
|
||||||
return deviation_ts;
|
return deviation_ts;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SrsAudioCodecId SrsHlsMuxer::latest_acodec()
|
||||||
|
{
|
||||||
|
// If current context writer exists, we query from it.
|
||||||
|
if (current && current->tscw) return current->tscw->acodec();
|
||||||
|
|
||||||
|
// Get the configured or updated config.
|
||||||
|
return latest_acodec_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SrsHlsMuxer::set_latest_acodec(SrsAudioCodecId v)
|
||||||
|
{
|
||||||
|
// Refresh the codec in context writer for current segment.
|
||||||
|
if (current && current->tscw) current->tscw->set_acodec(v);
|
||||||
|
|
||||||
|
// Refresh the codec for future segments.
|
||||||
|
latest_acodec_ = v;
|
||||||
|
}
|
||||||
|
|
||||||
srs_error_t SrsHlsMuxer::initialize()
|
srs_error_t SrsHlsMuxer::initialize()
|
||||||
{
|
{
|
||||||
return srs_success;
|
return srs_success;
|
||||||
|
@ -371,6 +390,8 @@ srs_error_t SrsHlsMuxer::segment_open()
|
||||||
srs_warn("hls: use aac for other codec=%s", default_acodec_str.c_str());
|
srs_warn("hls: use aac for other codec=%s", default_acodec_str.c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Now that we know the latest audio codec in stream, use it.
|
||||||
|
if (latest_acodec_ != SrsAudioCodecIdForbidden) default_acodec = latest_acodec_;
|
||||||
|
|
||||||
// load the default vcodec from config.
|
// load the default vcodec from config.
|
||||||
SrsVideoCodecId default_vcodec = SrsVideoCodecIdAVC;
|
SrsVideoCodecId default_vcodec = SrsVideoCodecIdAVC;
|
||||||
|
@ -969,6 +990,13 @@ srs_error_t SrsHlsController::on_sequence_header()
|
||||||
srs_error_t SrsHlsController::write_audio(SrsAudioFrame* frame, int64_t pts)
|
srs_error_t SrsHlsController::write_audio(SrsAudioFrame* frame, int64_t pts)
|
||||||
{
|
{
|
||||||
srs_error_t err = srs_success;
|
srs_error_t err = srs_success;
|
||||||
|
|
||||||
|
// Refresh the codec ASAP.
|
||||||
|
if (muxer->latest_acodec() != frame->acodec()->id) {
|
||||||
|
srs_trace("HLS: Switch audio codec %d(%s) to %d(%s)", muxer->latest_acodec(), srs_audio_codec_id2str(muxer->latest_acodec()).c_str(),
|
||||||
|
frame->acodec()->id, srs_audio_codec_id2str(frame->acodec()->id).c_str());
|
||||||
|
muxer->set_latest_acodec(frame->acodec()->id);
|
||||||
|
}
|
||||||
|
|
||||||
// write audio to cache.
|
// write audio to cache.
|
||||||
if ((err = tsmc->cache_audio(frame, pts)) != srs_success) {
|
if ((err = tsmc->cache_audio(frame, pts)) != srs_success) {
|
||||||
|
|
|
@ -156,6 +156,9 @@ private:
|
||||||
SrsHlsSegment* current;
|
SrsHlsSegment* current;
|
||||||
// The ts context, to keep cc continous between ts.
|
// The ts context, to keep cc continous between ts.
|
||||||
SrsTsContext* context;
|
SrsTsContext* context;
|
||||||
|
private:
|
||||||
|
// Latest audio codec, parsed from stream.
|
||||||
|
SrsAudioCodecId latest_acodec_;
|
||||||
public:
|
public:
|
||||||
SrsHlsMuxer();
|
SrsHlsMuxer();
|
||||||
virtual ~SrsHlsMuxer();
|
virtual ~SrsHlsMuxer();
|
||||||
|
@ -166,6 +169,9 @@ public:
|
||||||
virtual std::string ts_url();
|
virtual std::string ts_url();
|
||||||
virtual srs_utime_t duration();
|
virtual srs_utime_t duration();
|
||||||
virtual int deviation();
|
virtual int deviation();
|
||||||
|
public:
|
||||||
|
SrsAudioCodecId latest_acodec();
|
||||||
|
void set_latest_acodec(SrsAudioCodecId v);
|
||||||
public:
|
public:
|
||||||
// Initialize the hls muxer.
|
// Initialize the hls muxer.
|
||||||
virtual srs_error_t initialize();
|
virtual srs_error_t initialize();
|
||||||
|
|
|
@ -829,7 +829,9 @@ void SrsLiveStream::http_hooks_on_stop(ISrsHttpMessage* r)
|
||||||
srs_error_t SrsLiveStream::streaming_send_messages(ISrsBufferEncoder* enc, SrsSharedPtrMessage** msgs, int nb_msgs)
|
srs_error_t SrsLiveStream::streaming_send_messages(ISrsBufferEncoder* enc, SrsSharedPtrMessage** msgs, int nb_msgs)
|
||||||
{
|
{
|
||||||
srs_error_t err = srs_success;
|
srs_error_t err = srs_success;
|
||||||
|
|
||||||
|
// TODO: In gop cache, we know both the audio and video codec, so we should notice the encoder, which might depends
|
||||||
|
// on setting the correct codec information, for example, HTTP-TS or HLS will write PMT.
|
||||||
for (int i = 0; i < nb_msgs; i++) {
|
for (int i = 0; i < nb_msgs; i++) {
|
||||||
SrsSharedPtrMessage* msg = msgs[i];
|
SrsSharedPtrMessage* msg = msgs[i];
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,6 @@
|
||||||
|
|
||||||
#define VERSION_MAJOR 4
|
#define VERSION_MAJOR 4
|
||||||
#define VERSION_MINOR 0
|
#define VERSION_MINOR 0
|
||||||
#define VERSION_REVISION 268
|
#define VERSION_REVISION 269
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -9,6 +9,6 @@
|
||||||
|
|
||||||
#define VERSION_MAJOR 5
|
#define VERSION_MAJOR 5
|
||||||
#define VERSION_MINOR 0
|
#define VERSION_MINOR 0
|
||||||
#define VERSION_REVISION 115
|
#define VERSION_REVISION 116
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -595,6 +595,9 @@ srs_error_t SrsFrame::initialize(SrsCodecConfig* c)
|
||||||
srs_error_t SrsFrame::add_sample(char* bytes, int size)
|
srs_error_t SrsFrame::add_sample(char* bytes, int size)
|
||||||
{
|
{
|
||||||
srs_error_t err = srs_success;
|
srs_error_t err = srs_success;
|
||||||
|
|
||||||
|
// Ignore empty sample.
|
||||||
|
if (!bytes || size <= 0) return err;
|
||||||
|
|
||||||
if (nb_samples >= SrsMaxNbSamples) {
|
if (nb_samples >= SrsMaxNbSamples) {
|
||||||
return srs_error_new(ERROR_HLS_DECODE_ERROR, "Frame samples overflow");
|
return srs_error_new(ERROR_HLS_DECODE_ERROR, "Frame samples overflow");
|
||||||
|
@ -2063,20 +2066,13 @@ srs_error_t SrsFormat::audio_mp3_demux(SrsBuffer* stream, int64_t timestamp)
|
||||||
// we always decode aac then mp3.
|
// we always decode aac then mp3.
|
||||||
srs_assert(acodec->id == SrsAudioCodecIdMP3);
|
srs_assert(acodec->id == SrsAudioCodecIdMP3);
|
||||||
|
|
||||||
// Update the RAW MP3 data.
|
// Update the RAW MP3 data. Note the start is 12 bits syncword 0xFFF, so we should not skip any bytes, for detail
|
||||||
|
// please see ISO_IEC_11172-3-MP3-1993.pdf page 20 and 26.
|
||||||
raw = stream->data() + stream->pos();
|
raw = stream->data() + stream->pos();
|
||||||
nb_raw = stream->size() - stream->pos();
|
nb_raw = stream->size() - stream->pos();
|
||||||
|
|
||||||
stream->skip(1);
|
|
||||||
if (stream->empty()) {
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
char* data = stream->data() + stream->pos();
|
|
||||||
int size = stream->size() - stream->pos();
|
|
||||||
|
|
||||||
// mp3 payload.
|
// mp3 payload.
|
||||||
if ((err = audio->add_sample(data, size)) != srs_success) {
|
if ((err = audio->add_sample(raw, nb_raw)) != srs_success) {
|
||||||
return srs_error_wrap(err, "add audio frame");
|
return srs_error_wrap(err, "add audio frame");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2676,8 +2676,8 @@ SrsTsContextWriter::SrsTsContextWriter(ISrsStreamWriter* w, SrsTsContext* c, Srs
|
||||||
{
|
{
|
||||||
writer = w;
|
writer = w;
|
||||||
context = c;
|
context = c;
|
||||||
|
|
||||||
acodec = ac;
|
acodec_ = ac;
|
||||||
vcodec = vc;
|
vcodec = vc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2692,7 +2692,7 @@ srs_error_t SrsTsContextWriter::write_audio(SrsTsMessage* audio)
|
||||||
srs_info("hls: write audio pts=%" PRId64 ", dts=%" PRId64 ", size=%d",
|
srs_info("hls: write audio pts=%" PRId64 ", dts=%" PRId64 ", size=%d",
|
||||||
audio->pts, audio->dts, audio->PES_packet_length);
|
audio->pts, audio->dts, audio->PES_packet_length);
|
||||||
|
|
||||||
if ((err = context->encode(writer, audio, vcodec, acodec)) != srs_success) {
|
if ((err = context->encode(writer, audio, vcodec, acodec_)) != srs_success) {
|
||||||
return srs_error_wrap(err, "ts: write audio");
|
return srs_error_wrap(err, "ts: write audio");
|
||||||
}
|
}
|
||||||
srs_info("hls encode audio ok");
|
srs_info("hls encode audio ok");
|
||||||
|
@ -2707,7 +2707,7 @@ srs_error_t SrsTsContextWriter::write_video(SrsTsMessage* video)
|
||||||
srs_info("hls: write video pts=%" PRId64 ", dts=%" PRId64 ", size=%d",
|
srs_info("hls: write video pts=%" PRId64 ", dts=%" PRId64 ", size=%d",
|
||||||
video->pts, video->dts, video->PES_packet_length);
|
video->pts, video->dts, video->PES_packet_length);
|
||||||
|
|
||||||
if ((err = context->encode(writer, video, vcodec, acodec)) != srs_success) {
|
if ((err = context->encode(writer, video, vcodec, acodec_)) != srs_success) {
|
||||||
return srs_error_wrap(err, "ts: write video");
|
return srs_error_wrap(err, "ts: write video");
|
||||||
}
|
}
|
||||||
srs_info("hls encode video ok");
|
srs_info("hls encode video ok");
|
||||||
|
@ -2725,6 +2725,16 @@ void SrsTsContextWriter::update_video_codec(SrsVideoCodecId v)
|
||||||
vcodec = v;
|
vcodec = v;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SrsAudioCodecId SrsTsContextWriter::acodec()
|
||||||
|
{
|
||||||
|
return acodec_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SrsTsContextWriter::set_acodec(SrsAudioCodecId v)
|
||||||
|
{
|
||||||
|
acodec_ = v;
|
||||||
|
}
|
||||||
|
|
||||||
SrsEncFileWriter::SrsEncFileWriter()
|
SrsEncFileWriter::SrsEncFileWriter()
|
||||||
{
|
{
|
||||||
memset(iv,0,16);
|
memset(iv,0,16);
|
||||||
|
@ -3217,6 +3227,13 @@ srs_error_t SrsTsTransmuxer::write_audio(int64_t timestamp, char* data, int size
|
||||||
if (format->acodec->id == SrsAudioCodecIdAAC && format->audio->aac_packet_type == SrsAudioAacFrameTraitSequenceHeader) {
|
if (format->acodec->id == SrsAudioCodecIdAAC && format->audio->aac_packet_type == SrsAudioAacFrameTraitSequenceHeader) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Switch audio codec if not AAC.
|
||||||
|
if (tscw->acodec() != format->acodec->id) {
|
||||||
|
srs_trace("TS: Switch audio codec %d(%s) to %d(%s)", tscw->acodec(), srs_audio_codec_id2str(tscw->acodec()).c_str(),
|
||||||
|
format->acodec->id, srs_audio_codec_id2str(format->acodec->id).c_str());
|
||||||
|
tscw->set_acodec(format->acodec->id);
|
||||||
|
}
|
||||||
|
|
||||||
// the dts calc from rtmp/flv header.
|
// the dts calc from rtmp/flv header.
|
||||||
// @remark for http ts stream, the timestamp is always monotonically increase,
|
// @remark for http ts stream, the timestamp is always monotonically increase,
|
||||||
|
|
|
@ -107,8 +107,8 @@ enum SrsTsStream
|
||||||
// ISO/IEC 11172 Video
|
// ISO/IEC 11172 Video
|
||||||
// ITU-T Rec. H.262 | ISO/IEC 13818-2 Video or ISO/IEC 11172-2 constrained parameter video stream
|
// ITU-T Rec. H.262 | ISO/IEC 13818-2 Video or ISO/IEC 11172-2 constrained parameter video stream
|
||||||
// ISO/IEC 11172 Audio
|
// ISO/IEC 11172 Audio
|
||||||
|
SrsTsStreamAudioMp3 = 0x03,
|
||||||
// ISO/IEC 13818-3 Audio
|
// ISO/IEC 13818-3 Audio
|
||||||
SrsTsStreamAudioMp3 = 0x04,
|
|
||||||
// ITU-T Rec. H.222.0 | ISO/IEC 13818-1 private_sections
|
// ITU-T Rec. H.222.0 | ISO/IEC 13818-1 private_sections
|
||||||
// ITU-T Rec. H.222.0 | ISO/IEC 13818-1 PES packets containing private data
|
// ITU-T Rec. H.222.0 | ISO/IEC 13818-1 PES packets containing private data
|
||||||
// ISO/IEC 13522 MHEG
|
// ISO/IEC 13522 MHEG
|
||||||
|
@ -1260,7 +1260,7 @@ private:
|
||||||
// User must config the codec in right way.
|
// User must config the codec in right way.
|
||||||
// @see https://github.com/ossrs/srs/issues/301
|
// @see https://github.com/ossrs/srs/issues/301
|
||||||
SrsVideoCodecId vcodec;
|
SrsVideoCodecId vcodec;
|
||||||
SrsAudioCodecId acodec;
|
SrsAudioCodecId acodec_;
|
||||||
private:
|
private:
|
||||||
SrsTsContext* context;
|
SrsTsContext* context;
|
||||||
ISrsStreamWriter* writer;
|
ISrsStreamWriter* writer;
|
||||||
|
@ -1277,6 +1277,10 @@ public:
|
||||||
// Get or update the video codec of ts muxer.
|
// Get or update the video codec of ts muxer.
|
||||||
virtual SrsVideoCodecId video_codec();
|
virtual SrsVideoCodecId video_codec();
|
||||||
virtual void update_video_codec(SrsVideoCodecId v);
|
virtual void update_video_codec(SrsVideoCodecId v);
|
||||||
|
public:
|
||||||
|
// Get and set the audio codec.
|
||||||
|
SrsAudioCodecId acodec();
|
||||||
|
void set_acodec(SrsAudioCodecId v);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Used for HLS Encryption
|
// Used for HLS Encryption
|
||||||
|
|
|
@ -3471,11 +3471,23 @@ VOID TEST(KernelCodecTest, AVFrame)
|
||||||
EXPECT_TRUE(20 == f.samples[1].size);
|
EXPECT_TRUE(20 == f.samples[1].size);
|
||||||
EXPECT_TRUE(2 == f.nb_samples);
|
EXPECT_TRUE(2 == f.nb_samples);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (true) {
|
||||||
|
SrsAudioFrame f;
|
||||||
|
EXPECT_TRUE(0 == f.nb_samples);
|
||||||
|
|
||||||
|
HELPER_EXPECT_SUCCESS(f.add_sample((char*)1, 0));
|
||||||
|
EXPECT_TRUE(0 == f.nb_samples);
|
||||||
|
|
||||||
|
HELPER_EXPECT_SUCCESS(f.add_sample(NULL, 1));
|
||||||
|
EXPECT_TRUE(0 == f.nb_samples);
|
||||||
|
}
|
||||||
|
|
||||||
if (true) {
|
if (true) {
|
||||||
SrsAudioFrame f;
|
SrsAudioFrame f;
|
||||||
for (int i = 0; i < SrsMaxNbSamples; i++) {
|
for (int i = 0; i < SrsMaxNbSamples; i++) {
|
||||||
HELPER_EXPECT_SUCCESS(f.add_sample((char*)(int64_t)i, i*10));
|
HELPER_EXPECT_SUCCESS(f.add_sample((char*)(int64_t)(i + 1), i*10 + 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
srs_error_t err = f.add_sample((char*)1, 1);
|
srs_error_t err = f.add_sample((char*)1, 1);
|
||||||
|
@ -3601,18 +3613,39 @@ VOID TEST(KernelCodecTest, AudioFormat)
|
||||||
HELPER_EXPECT_SUCCESS(f.on_audio(0, (char*)"\x00", 0));
|
HELPER_EXPECT_SUCCESS(f.on_audio(0, (char*)"\x00", 0));
|
||||||
HELPER_EXPECT_SUCCESS(f.on_audio(0, (char*)"\x00", 1));
|
HELPER_EXPECT_SUCCESS(f.on_audio(0, (char*)"\x00", 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// For MP3
|
||||||
if (true) {
|
if (true) {
|
||||||
SrsFormat f;
|
SrsFormat f;
|
||||||
HELPER_EXPECT_SUCCESS(f.initialize());
|
HELPER_EXPECT_SUCCESS(f.initialize());
|
||||||
|
HELPER_EXPECT_SUCCESS(f.on_audio(0, (char*)"\x20", 1));
|
||||||
|
EXPECT_TRUE(0 == f.nb_raw);
|
||||||
|
EXPECT_TRUE(0 == f.audio->nb_samples);
|
||||||
|
|
||||||
HELPER_EXPECT_SUCCESS(f.on_audio(0, (char*)"\x20\x00", 2));
|
HELPER_EXPECT_SUCCESS(f.on_audio(0, (char*)"\x20\x00", 2));
|
||||||
EXPECT_TRUE(1 == f.nb_raw);
|
EXPECT_TRUE(1 == f.nb_raw);
|
||||||
EXPECT_TRUE(0 == f.audio->nb_samples);
|
EXPECT_TRUE(1 == f.audio->nb_samples);
|
||||||
|
|
||||||
HELPER_EXPECT_SUCCESS(f.on_audio(0, (char*)"\x20\x00\x00", 3));
|
HELPER_EXPECT_SUCCESS(f.on_audio(0, (char*)"\x20\x00\x00", 3));
|
||||||
EXPECT_TRUE(2 == f.nb_raw);
|
EXPECT_TRUE(2 == f.nb_raw);
|
||||||
EXPECT_TRUE(1 == f.audio->nb_samples);
|
EXPECT_TRUE(1 == f.audio->nb_samples);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// For AAC
|
||||||
|
if (true) {
|
||||||
|
SrsFormat f;
|
||||||
|
HELPER_EXPECT_SUCCESS(f.initialize());
|
||||||
|
HELPER_EXPECT_FAILED(f.on_audio(0, (char*)"\xa0", 1));
|
||||||
|
|
||||||
|
HELPER_EXPECT_SUCCESS(f.on_audio(0, (char*)"\xaf\x00\x12\x10", 4));
|
||||||
|
HELPER_EXPECT_SUCCESS(f.on_audio(0, (char*)"\xa0\x01", 2));
|
||||||
|
EXPECT_TRUE(0 == f.nb_raw);
|
||||||
|
EXPECT_TRUE(0 == f.audio->nb_samples);
|
||||||
|
|
||||||
|
HELPER_EXPECT_SUCCESS(f.on_audio(0, (char*)"\xa0\x01\x00", 3));
|
||||||
|
EXPECT_TRUE(1 == f.nb_raw);
|
||||||
|
EXPECT_TRUE(1 == f.audio->nb_samples);
|
||||||
|
}
|
||||||
|
|
||||||
if (true) {
|
if (true) {
|
||||||
SrsFormat f;
|
SrsFormat f;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue