1
0
Fork 0
mirror of https://github.com/ossrs/srs.git synced 2025-03-09 15:49:59 +00:00

For #299, A/V init mp4 are fine.

This commit is contained in:
winlin 2017-03-05 18:44:37 +08:00
parent 886930c22a
commit 3ec9df6578
6 changed files with 461 additions and 8 deletions

View file

@ -560,7 +560,8 @@ int SrsFormat::on_audio(int64_t timestamp, char* data, int size)
}
// @see: E.4.2 Audio Tags, video_file_format_spec_v10_1.pdf, page 76
SrsAudioCodecId codec = (SrsAudioCodecId)((buffer->read_1bytes() >> 4) & 0x0f);
uint8_t v = buffer->read_1bytes();
SrsAudioCodecId codec = (SrsAudioCodecId)((v >> 4) & 0x0f);
if (codec != SrsAudioCodecIdMP3 && codec != SrsAudioCodecIdAAC) {
return ret;
@ -1361,6 +1362,21 @@ int SrsFormat::audio_mp3_demux(SrsBuffer* stream, int64_t timestamp)
audio->cts = 0;
audio->dts = timestamp;
// @see: E.4.2 Audio Tags, video_file_format_spec_v10_1.pdf, page 76
int8_t sound_format = stream->read_1bytes();
int8_t sound_type = sound_format & 0x01;
int8_t sound_size = (sound_format >> 1) & 0x01;
int8_t sound_rate = (sound_format >> 2) & 0x03;
sound_format = (sound_format >> 4) & 0x0f;
SrsAudioCodecId codec_id = (SrsAudioCodecId)sound_format;
acodec->id = codec_id;
acodec->sound_type = (SrsAudioChannels)sound_type;
acodec->sound_rate = (SrsAudioSampleRate)sound_rate;
acodec->sound_size = (SrsAudioSampleBits)sound_size;
// we always decode aac then mp3.
srs_assert(acodec->id == SrsAudioCodecIdMP3);

View file

@ -515,14 +515,17 @@ public:
*/
class SrsAudioCodecConfig : public SrsCodecConfig
{
// In FLV specification.
public:
// audio specified
SrsAudioCodecId id;
// audio aac specified.
SrsAudioSampleRate sound_rate;
SrsAudioSampleBits sound_size;
// TODO: FIXME: Rename to sound_channels.
SrsAudioChannels sound_type;
int audio_data_rate; // in bps
// In AAC specification.
public:
/**
* audio specified
@ -539,6 +542,7 @@ public:
* channelConfiguration
*/
uint8_t aac_channels;
// Sequence header payload.
public:
/**
* the aac extra data, the AAC sequence header,

View file

@ -226,6 +226,8 @@ int SrsMp4Box::discovery(SrsBuffer* buf, SrsMp4Box** ppbox)
case SrsMp4BoxTypeMP4A: box = new SrsMp4AudioSampleEntry(); break;
case SrsMp4BoxTypeESDS: box = new SrsMp4EsdsBox(); break;
case SrsMp4BoxTypeUDTA: box = new SrsMp4UserDataBox(); break;
case SrsMp4BoxTypeMVEX: box = new SrsMp4MovieExtendsBox(); break;
case SrsMp4BoxTypeTREX: box = new SrsMp4TrackExtendsBox(); break;
default:
ret = ERROR_MP4_BOX_ILLEGAL_TYPE;
srs_error("MP4 illegal box type=%d. ret=%d", type, ret);
@ -690,7 +692,19 @@ SrsMp4MovieHeaderBox* SrsMp4MovieBox::mvhd()
void SrsMp4MovieBox::set_mvhd(SrsMp4MovieHeaderBox* v)
{
remove(SrsMp4BoxTypeMVHD);
boxes.insert(boxes.begin(), v);
boxes.push_back(v);
}
SrsMp4MovieExtendsBox* SrsMp4MovieBox::mvex()
{
SrsMp4Box* box = get(SrsMp4BoxTypeMVEX);
return dynamic_cast<SrsMp4MovieExtendsBox*>(box);
}
void SrsMp4MovieBox::set_mvex(SrsMp4MovieExtendsBox* v)
{
remove(SrsMp4BoxTypeMVEX);
boxes.push_back(v);
}
SrsMp4TrackBox* SrsMp4MovieBox::video()
@ -884,6 +898,77 @@ int SrsMp4MovieHeaderBox::decode_header(SrsBuffer* buf)
return ret;
}
SrsMp4MovieExtendsBox::SrsMp4MovieExtendsBox()
{
type = SrsMp4BoxTypeMVEX;
}
SrsMp4MovieExtendsBox::~SrsMp4MovieExtendsBox()
{
}
SrsMp4TrackExtendsBox* SrsMp4MovieExtendsBox::trex()
{
SrsMp4Box* box = get(SrsMp4BoxTypeTREX);
return dynamic_cast<SrsMp4TrackExtendsBox*>(box);
}
void SrsMp4MovieExtendsBox::set_trex(SrsMp4TrackExtendsBox* v)
{
remove(SrsMp4BoxTypeTREX);
boxes.push_back(v);
}
SrsMp4TrackExtendsBox::SrsMp4TrackExtendsBox()
{
type = SrsMp4BoxTypeTREX;
track_ID = default_sample_size = default_sample_flags = 0;
default_sample_size = default_sample_duration = default_sample_description_index = 0;
}
SrsMp4TrackExtendsBox::~SrsMp4TrackExtendsBox()
{
}
int SrsMp4TrackExtendsBox::nb_header()
{
return SrsMp4FullBox::nb_header() + 4*5;
}
int SrsMp4TrackExtendsBox::encode_header(SrsBuffer* buf)
{
int ret = ERROR_SUCCESS;
if ((ret = SrsMp4FullBox::encode_header(buf)) != ERROR_SUCCESS) {
return ret;
}
buf->write_4bytes(track_ID);
buf->write_4bytes(default_sample_description_index);
buf->write_4bytes(default_sample_duration);
buf->write_4bytes(default_sample_size);
buf->write_4bytes(default_sample_flags);
return ret;
}
int SrsMp4TrackExtendsBox::decode_header(SrsBuffer* buf)
{
int ret = ERROR_SUCCESS;
if ((ret = SrsMp4FullBox::decode_header(buf)) != ERROR_SUCCESS) {
return ret;
}
track_ID = buf->read_4bytes();
default_sample_description_index = buf->read_4bytes();
default_sample_duration = buf->read_4bytes();
default_sample_size = buf->read_4bytes();
default_sample_flags = buf->read_4bytes();
return ret;
}
SrsMp4TrackBox::SrsMp4TrackBox()
{
type = SrsMp4BoxTypeTRAK;
@ -4010,7 +4095,8 @@ int SrsMp4Decoder::parse_ftyp(SrsMp4FileTypeBox* ftyp)
// File Type Box (ftyp)
bool legal_brand = false;
static SrsMp4BoxBrand legal_brands[] = {
SrsMp4BoxBrandISOM, SrsMp4BoxBrandISO2, SrsMp4BoxBrandAVC1, SrsMp4BoxBrandMP41
SrsMp4BoxBrandISOM, SrsMp4BoxBrandISO2, SrsMp4BoxBrandAVC1, SrsMp4BoxBrandMP41,
SrsMp4BoxBrandISO5
};
for (int i = 0; i < sizeof(legal_brands)/sizeof(SrsMp4BoxBrand); i++) {
if (ftyp->major_brand == legal_brands[i]) {
@ -4375,7 +4461,7 @@ int SrsMp4Encoder::flush()
mvhd->timescale = 1000; // Use tbn ms.
mvhd->duration_in_tbn = srs_max(vduration, aduration);
mvhd->next_track_ID++;
mvhd->next_track_ID = 1; // Starts from 1, increase when use it.
if (nb_videos) {
SrsMp4TrackBox* trak = new SrsMp4TrackBox();

View file

@ -64,6 +64,8 @@ class SrsMp4VideoMeidaHeaderBox;
class SrsMp4DataInformationBox;
class SrsMp4DataReferenceBox;
class SrsMp4SoundMeidaHeaderBox;
class SrsMp4MovieExtendsBox;
class SrsMp4TrackExtendsBox;
/**
* 4.2 Object Structure
@ -109,6 +111,8 @@ enum SrsMp4BoxType
SrsMp4BoxTypeMP4A = 0x6d703461, // 'mp4a'
SrsMp4BoxTypeESDS = 0x65736473, // 'esds'
SrsMp4BoxTypeUDTA = 0x75647461, // 'udta'
SrsMp4BoxTypeMVEX = 0x6d766578, // 'mvex'
SrsMp4BoxTypeTREX = 0x74726578, // 'trex'
};
/**
@ -134,6 +138,9 @@ enum SrsMp4BoxBrand
SrsMp4BoxBrandISO2 = 0x69736f32, // 'iso2'
SrsMp4BoxBrandAVC1 = 0x61766331, // 'avc1'
SrsMp4BoxBrandMP41 = 0x6d703431, // 'mp41'
SrsMp4BoxBrandISO5 = 0x69736f35, // 'iso5'
SrsMp4BoxBrandMP42 = 0x6d703432, // 'mp42'
SrsMp4BoxBrandDASH = 0x64617368, // 'dash'
};
/**
@ -321,6 +328,9 @@ public:
// Get the header of moov.
virtual SrsMp4MovieHeaderBox* mvhd();
virtual void set_mvhd(SrsMp4MovieHeaderBox* v);
// Get the movie extends header.
virtual SrsMp4MovieExtendsBox* mvex();
virtual void set_mvex(SrsMp4MovieExtendsBox* v);
// Get the first video track.
virtual SrsMp4TrackBox* video();
// Get the first audio track.
@ -395,6 +405,47 @@ enum SrsMp4TrackType
SrsMp4TrackTypeVideo = 0x02,
};
/**
* 8.8.1 Movie Extends Box (mvex)
* ISO_IEC_14496-12-base-format-2012.pdf, page 64
* This box warns readers that there might be Movie Fragment Boxes in this file. To know of all samples in the
* tracks, these Movie Fragment Boxes must be found and scanned in order, and their information logically
* added to that found in the Movie Box.
*/
class SrsMp4MovieExtendsBox : public SrsMp4Box
{
public:
SrsMp4MovieExtendsBox();
virtual ~SrsMp4MovieExtendsBox();
public:
// Get the track extends box.
virtual SrsMp4TrackExtendsBox* trex();
virtual void set_trex(SrsMp4TrackExtendsBox* v);
};
/**
* 8.8.3 Track Extends Box(trex)
* ISO_IEC_14496-12-base-format-2012.pdf, page 65
*/
class SrsMp4TrackExtendsBox : public SrsMp4FullBox
{
public:
// identifies the track; this shall be the track ID of a track in the Movie Box
uint32_t track_ID;
// these fields set up defaults used in the track fragments.
uint32_t default_sample_description_index;
uint32_t default_sample_duration;
uint32_t default_sample_size;
uint32_t default_sample_flags;
public:
SrsMp4TrackExtendsBox();
virtual ~SrsMp4TrackExtendsBox();
protected:
virtual int nb_header();
virtual int encode_header(SrsBuffer* buf);
virtual int decode_header(SrsBuffer* buf);
};
/**
* 8.3.1 Track Box (trak)
* ISO_IEC_14496-12-base-format-2012.pdf, page 32