Skip to content

Commit

Permalink
MP3: Fix bug for TS or HLS with mp3 codec. v4.0.269 (ossrs#296)
Browse files Browse the repository at this point in the history
1. Refresh HLS audio codec if changed in stream.
2. Refresh TS audio codec if changed in stream.
3. Fix mp3 demux bug in SrsFormat::audio_mp3_demux.
4. Use 3(MPEG1) not 4(MPEG2) as PMT stream type, follow FFmpeg.
  • Loading branch information
winlinvip committed Dec 24, 2022
1 parent 2573a25 commit 0b54b0e
Show file tree
Hide file tree
Showing 7 changed files with 67 additions and 18 deletions.
1 change: 1 addition & 0 deletions trunk/doc/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ The changelog for SRS.

## 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-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
Expand Down
28 changes: 28 additions & 0 deletions trunk/src/app/srs_app_hls.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,7 @@ SrsHlsMuxer::SrsHlsMuxer()
async = new SrsAsyncCallWorker();
context = new SrsTsContext();
segments = new SrsFragmentWindow();
latest_acodec_ = SrsAudioCodecIdForbidden;

memset(key, 0, 16);
memset(iv, 0, 16);
Expand Down Expand Up @@ -263,6 +264,24 @@ int SrsHlsMuxer::deviation()
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()
{
return srs_success;
Expand Down Expand Up @@ -371,6 +390,8 @@ srs_error_t SrsHlsMuxer::segment_open()
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.
SrsVideoCodecId default_vcodec = SrsVideoCodecIdAVC;
Expand Down Expand Up @@ -963,6 +984,13 @@ srs_error_t SrsHlsController::on_sequence_header()
srs_error_t SrsHlsController::write_audio(SrsAudioFrame* frame, int64_t pts)
{
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.
if ((err = tsmc->cache_audio(frame, pts)) != srs_success) {
Expand Down
6 changes: 6 additions & 0 deletions trunk/src/app/srs_app_hls.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,9 @@ class SrsHlsMuxer
SrsHlsSegment* current;
// The ts context, to keep cc continous between ts.
SrsTsContext* context;
private:
// Latest audio codec, parsed from stream.
SrsAudioCodecId latest_acodec_;
public:
SrsHlsMuxer();
virtual ~SrsHlsMuxer();
Expand All @@ -166,6 +169,9 @@ class SrsHlsMuxer
virtual std::string ts_url();
virtual srs_utime_t duration();
virtual int deviation();
public:
SrsAudioCodecId latest_acodec();
void set_latest_acodec(SrsAudioCodecId v);
public:
// Initialize the hls muxer.
virtual srs_error_t initialize();
Expand Down
2 changes: 1 addition & 1 deletion trunk/src/core/srs_core_version4.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@

#define VERSION_MAJOR 4
#define VERSION_MINOR 0
#define VERSION_REVISION 268
#define VERSION_REVISION 269

#endif
13 changes: 3 additions & 10 deletions trunk/src/kernel/srs_kernel_codec.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1407,20 +1407,13 @@ srs_error_t SrsFormat::audio_mp3_demux(SrsBuffer* stream, int64_t timestamp)
// we always decode aac then mp3.
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();
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.
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");
}

Expand Down
25 changes: 21 additions & 4 deletions trunk/src/kernel/srs_kernel_ts.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2598,8 +2598,8 @@ SrsTsContextWriter::SrsTsContextWriter(ISrsStreamWriter* w, SrsTsContext* c, Srs
{
writer = w;
context = c;
acodec = ac;

acodec_ = ac;
vcodec = vc;
}

Expand All @@ -2614,7 +2614,7 @@ srs_error_t SrsTsContextWriter::write_audio(SrsTsMessage* audio)
srs_info("hls: write audio pts=%" PRId64 ", dts=%" PRId64 ", size=%d",
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");
}
srs_info("hls encode audio ok");
Expand All @@ -2629,7 +2629,7 @@ srs_error_t SrsTsContextWriter::write_video(SrsTsMessage* video)
srs_info("hls: write video pts=%" PRId64 ", dts=%" PRId64 ", size=%d",
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");
}
srs_info("hls encode video ok");
Expand All @@ -2642,6 +2642,16 @@ SrsVideoCodecId SrsTsContextWriter::video_codec()
return vcodec;
}

SrsAudioCodecId SrsTsContextWriter::acodec()
{
return acodec_;
}

void SrsTsContextWriter::set_acodec(SrsAudioCodecId v)
{
acodec_ = v;
}

SrsEncFileWriter::SrsEncFileWriter()
{
memset(iv,0,16);
Expand Down Expand Up @@ -3079,6 +3089,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) {
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.
// @remark for http ts stream, the timestamp is always monotonically increase,
Expand Down
10 changes: 7 additions & 3 deletions trunk/src/kernel/srs_kernel_ts.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ enum SrsTsPidApply
SrsTsPidApplyAudio, // vor audio
};

// Table 2-29 - Stream type assignments
// Table 2-29 - Stream type assignments, hls-mpeg-ts-iso13818-1.pdf, page 66
enum SrsTsStream
{
// ITU-T | ISO/IEC Reserved
Expand All @@ -106,8 +106,8 @@ enum SrsTsStream
// ISO/IEC 11172 Video
// ITU-T Rec. H.262 | ISO/IEC 13818-2 Video or ISO/IEC 11172-2 constrained parameter video stream
// ISO/IEC 11172 Audio
SrsTsStreamAudioMp3 = 0x03,
// 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 PES packets containing private data
// ISO/IEC 13522 MHEG
Expand Down Expand Up @@ -1243,7 +1243,7 @@ class SrsTsContextWriter
// User must config the codec in right way.
// @see https://github.com/ossrs/srs/issues/301
SrsVideoCodecId vcodec;
SrsAudioCodecId acodec;
SrsAudioCodecId acodec_;
private:
SrsTsContext* context;
ISrsStreamWriter* writer;
Expand All @@ -1259,6 +1259,10 @@ class SrsTsContextWriter
public:
// get the video codec of ts muxer.
virtual SrsVideoCodecId video_codec();
public:
// Get and set the audio codec.
SrsAudioCodecId acodec();
void set_acodec(SrsAudioCodecId v);
};

// Used for HLS Encryption
Expand Down

0 comments on commit 0b54b0e

Please sign in to comment.