mirror of
				https://github.com/ossrs/srs.git
				synced 2025-03-09 15:49:59 +00:00 
			
		
		
		
	update readme
This commit is contained in:
		
							parent
							
								
									ac7ee10b60
								
							
						
					
					
						commit
						e8eb050bf2
					
				
					 5 changed files with 162 additions and 15 deletions
				
			
		| 
						 | 
				
			
			@ -123,7 +123,6 @@ Please select your language:
 | 
			
		|||
* [SRS 2.0 English][v2_EN_Home]
 | 
			
		||||
* [SRS 2.0 Chinese][v2_CN_Home]
 | 
			
		||||
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
### SRS 3.0 wiki
 | 
			
		||||
 | 
			
		||||
Please select your language:
 | 
			
		||||
| 
						 | 
				
			
			@ -182,6 +181,8 @@ Please select your language:
 | 
			
		|||
- [ ] Support MPEG-DASH, the future streaming protocol, read [#299][bug #299].
 | 
			
		||||
- [ ] Support HLS+, please read [#466][bug #466] and [#468][bug #468].
 | 
			
		||||
 | 
			
		||||
### Change Logs
 | 
			
		||||
 | 
			
		||||
### V3 changes
 | 
			
		||||
 | 
			
		||||
* v3.0, 2017-01-19, for [#742][bug #742] refine source, meta and origin hub. 3.0.16
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -250,6 +250,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 | 
			
		|||
#define ERROR_MP4_BOX_ILLEGAL_BRAND         3074
 | 
			
		||||
#define ERROR_MP4_NOT_NON_SEEKABLE          3075
 | 
			
		||||
#define ERROR_MP4_ESDS_SL_Config            3076
 | 
			
		||||
#define ERROR_MP4_ILLEGAL_MOOV              3077
 | 
			
		||||
 | 
			
		||||
///////////////////////////////////////////////////////
 | 
			
		||||
// HTTP/StreamCaster/KAFKA protocol error.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -141,15 +141,17 @@ extern ISrsThreadContext* _srs_context;
 | 
			
		|||
    #define srs_trace(msg, ...)   _srs_log->trace(NULL, _srs_context->get_id(), msg, ##__VA_ARGS__)
 | 
			
		||||
    #define srs_warn(msg, ...)    _srs_log->warn(NULL, _srs_context->get_id(), msg, ##__VA_ARGS__)
 | 
			
		||||
    #define srs_error(msg, ...)   _srs_log->error(NULL, _srs_context->get_id(), msg, ##__VA_ARGS__)
 | 
			
		||||
#endif
 | 
			
		||||
// use __FUNCTION__ to print c method
 | 
			
		||||
#elif 0
 | 
			
		||||
#if 0
 | 
			
		||||
    #define srs_verbose(msg, ...) _srs_log->verbose(__FUNCTION__, _srs_context->get_id(), msg, ##__VA_ARGS__)
 | 
			
		||||
    #define srs_info(msg, ...)    _srs_log->info(__FUNCTION__, _srs_context->get_id(), msg, ##__VA_ARGS__)
 | 
			
		||||
    #define srs_trace(msg, ...)   _srs_log->trace(__FUNCTION__, _srs_context->get_id(), msg, ##__VA_ARGS__)
 | 
			
		||||
    #define srs_warn(msg, ...)    _srs_log->warn(__FUNCTION__, _srs_context->get_id(), msg, ##__VA_ARGS__)
 | 
			
		||||
    #define srs_error(msg, ...)   _srs_log->error(__FUNCTION__, _srs_context->get_id(), msg, ##__VA_ARGS__)
 | 
			
		||||
#endif
 | 
			
		||||
// use __PRETTY_FUNCTION__ to print c++ class:method
 | 
			
		||||
#else
 | 
			
		||||
#if 0
 | 
			
		||||
    #define srs_verbose(msg, ...) _srs_log->verbose(__PRETTY_FUNCTION__, _srs_context->get_id(), msg, ##__VA_ARGS__)
 | 
			
		||||
    #define srs_info(msg, ...)    _srs_log->info(__PRETTY_FUNCTION__, _srs_context->get_id(), msg, ##__VA_ARGS__)
 | 
			
		||||
    #define srs_trace(msg, ...)   _srs_log->trace(__PRETTY_FUNCTION__, _srs_context->get_id(), msg, ##__VA_ARGS__)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -121,6 +121,19 @@ bool SrsMp4Box::is_mdat()
 | 
			
		|||
    return type == SrsMp4BoxTypeMDAT;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
SrsMp4Box* SrsMp4Box::get(SrsMp4BoxType bt)
 | 
			
		||||
{
 | 
			
		||||
    vector<SrsMp4Box*>::iterator it;
 | 
			
		||||
    for (it = boxes.begin(); it != boxes.end(); ++it) {
 | 
			
		||||
        SrsMp4Box* box = *it;
 | 
			
		||||
        if (box->type == bt) {
 | 
			
		||||
            return box;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int SrsMp4Box::discovery(SrsBuffer* buf, SrsMp4Box** ppbox)
 | 
			
		||||
{
 | 
			
		||||
    *ppbox = NULL;
 | 
			
		||||
| 
						 | 
				
			
			@ -625,6 +638,40 @@ SrsMp4MovieBox::~SrsMp4MovieBox()
 | 
			
		|||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
SrsMp4MovieHeaderBox* SrsMp4MovieBox::mvhd()
 | 
			
		||||
{
 | 
			
		||||
    SrsMp4Box* box = get(SrsMp4BoxTypeMVHD);
 | 
			
		||||
    return dynamic_cast<SrsMp4MovieHeaderBox*>(box);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
SrsMp4TrackBox* SrsMp4MovieBox::video()
 | 
			
		||||
{
 | 
			
		||||
    for (int i = 0; i < boxes.size(); i++) {
 | 
			
		||||
        SrsMp4Box* box = boxes.at(i);
 | 
			
		||||
        if (box->type == SrsMp4BoxTypeTRAK) {
 | 
			
		||||
            SrsMp4TrackBox* trak = dynamic_cast<SrsMp4TrackBox*>(box);
 | 
			
		||||
            if ((trak->track_type() & SrsMp4TrackTypeVideo) == SrsMp4TrackTypeVideo) {
 | 
			
		||||
                return trak;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
SrsMp4TrackBox* SrsMp4MovieBox::audio()
 | 
			
		||||
{
 | 
			
		||||
    for (int i = 0; i < boxes.size(); i++) {
 | 
			
		||||
        SrsMp4Box* box = boxes.at(i);
 | 
			
		||||
        if (box->type == SrsMp4BoxTypeTRAK) {
 | 
			
		||||
            SrsMp4TrackBox* trak = dynamic_cast<SrsMp4TrackBox*>(box);
 | 
			
		||||
            if ((trak->track_type() & SrsMp4TrackTypeAudio) == SrsMp4TrackTypeAudio) {
 | 
			
		||||
                return trak;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int SrsMp4MovieBox::nb_header()
 | 
			
		||||
{
 | 
			
		||||
    return SrsMp4Box::nb_header();
 | 
			
		||||
| 
						 | 
				
			
			@ -659,6 +706,11 @@ SrsMp4MovieHeaderBox::~SrsMp4MovieHeaderBox()
 | 
			
		|||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint64_t SrsMp4MovieHeaderBox::duration()
 | 
			
		||||
{
 | 
			
		||||
    return duration_in_tbn * 1000 / timescale;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int SrsMp4MovieHeaderBox::nb_header()
 | 
			
		||||
{
 | 
			
		||||
    int size = SrsMp4FullBox::nb_header();
 | 
			
		||||
| 
						 | 
				
			
			@ -686,12 +738,12 @@ int SrsMp4MovieHeaderBox::encode_header(SrsBuffer* buf)
 | 
			
		|||
        buf->write_8bytes(creation_time);
 | 
			
		||||
        buf->write_8bytes(modification_time);
 | 
			
		||||
        buf->write_4bytes(timescale);
 | 
			
		||||
        buf->write_8bytes(duration);
 | 
			
		||||
        buf->write_8bytes(duration_in_tbn);
 | 
			
		||||
    } else {
 | 
			
		||||
        buf->write_4bytes((uint32_t)creation_time);
 | 
			
		||||
        buf->write_4bytes((uint32_t)modification_time);
 | 
			
		||||
        buf->write_4bytes(timescale);
 | 
			
		||||
        buf->write_4bytes((uint32_t)duration);
 | 
			
		||||
        buf->write_4bytes((uint32_t)duration_in_tbn);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    buf->write_4bytes(rate);
 | 
			
		||||
| 
						 | 
				
			
			@ -721,12 +773,12 @@ int SrsMp4MovieHeaderBox::decode_header(SrsBuffer* buf)
 | 
			
		|||
        creation_time = buf->read_8bytes();
 | 
			
		||||
        modification_time = buf->read_8bytes();
 | 
			
		||||
        timescale = buf->read_4bytes();
 | 
			
		||||
        duration = buf->read_8bytes();
 | 
			
		||||
        duration_in_tbn = buf->read_8bytes();
 | 
			
		||||
    } else {
 | 
			
		||||
        creation_time = buf->read_4bytes();
 | 
			
		||||
        modification_time = buf->read_4bytes();
 | 
			
		||||
        timescale = buf->read_4bytes();
 | 
			
		||||
        duration = buf->read_4bytes();
 | 
			
		||||
        duration_in_tbn = buf->read_4bytes();
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    rate = buf->read_4bytes();
 | 
			
		||||
| 
						 | 
				
			
			@ -769,6 +821,18 @@ SrsMp4TrackHeaderBox::~SrsMp4TrackHeaderBox()
 | 
			
		|||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
SrsMp4TrackType SrsMp4TrackBox::track_type()
 | 
			
		||||
{
 | 
			
		||||
    SrsMp4Box* box = get(SrsMp4BoxTypeMDIA);
 | 
			
		||||
    if (!box) {
 | 
			
		||||
        return SrsMp4TrackTypeForbidden;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    // TODO: Maybe should discovery all mdia boxes.
 | 
			
		||||
    SrsMp4MediaBox* mdia = dynamic_cast<SrsMp4MediaBox*>(box);
 | 
			
		||||
    return mdia->track_type();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int SrsMp4TrackHeaderBox::nb_header()
 | 
			
		||||
{
 | 
			
		||||
    int size = SrsMp4FullBox::nb_header();
 | 
			
		||||
| 
						 | 
				
			
			@ -962,6 +1026,23 @@ SrsMp4MediaBox::~SrsMp4MediaBox()
 | 
			
		|||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
SrsMp4TrackType SrsMp4MediaBox::track_type()
 | 
			
		||||
{
 | 
			
		||||
    SrsMp4Box* box = get(SrsMp4BoxTypeHDLR);
 | 
			
		||||
    if (!box) {
 | 
			
		||||
        return SrsMp4TrackTypeForbidden;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    SrsMp4HandlerReferenceBox* hdlr = dynamic_cast<SrsMp4HandlerReferenceBox*>(box);
 | 
			
		||||
    if (hdlr->handler_type == SrsMp4HandlerTypeSOUN) {
 | 
			
		||||
        return SrsMp4TrackTypeAudio;
 | 
			
		||||
    } else if (hdlr->handler_type == SrsMp4HandlerTypeVIDE) {
 | 
			
		||||
        return SrsMp4TrackTypeVideo;
 | 
			
		||||
    } else {
 | 
			
		||||
        return SrsMp4TrackTypeForbidden;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
SrsMp4MediaHeaderBox::SrsMp4MediaHeaderBox()
 | 
			
		||||
{
 | 
			
		||||
    type = SrsMp4BoxTypeMDHD;
 | 
			
		||||
| 
						 | 
				
			
			@ -1084,12 +1165,12 @@ SrsMp4HandlerReferenceBox::~SrsMp4HandlerReferenceBox()
 | 
			
		|||
 | 
			
		||||
bool SrsMp4HandlerReferenceBox::is_video()
 | 
			
		||||
{
 | 
			
		||||
    return handler_type == SrsMp4BoxTypeVIDE;
 | 
			
		||||
    return handler_type == SrsMp4HandlerTypeVIDE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool SrsMp4HandlerReferenceBox::is_audio()
 | 
			
		||||
{
 | 
			
		||||
    return handler_type == SrsMp4BoxTypeSOUN;
 | 
			
		||||
    return handler_type == SrsMp4HandlerTypeSOUN;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int SrsMp4HandlerReferenceBox::nb_header()
 | 
			
		||||
| 
						 | 
				
			
			@ -1124,7 +1205,7 @@ int SrsMp4HandlerReferenceBox::decode_header(SrsBuffer* buf)
 | 
			
		|||
    }
 | 
			
		||||
    
 | 
			
		||||
    buf->skip(4);
 | 
			
		||||
    handler_type = buf->read_4bytes();
 | 
			
		||||
    handler_type = (SrsMp4HandlerType)buf->read_4bytes();
 | 
			
		||||
    buf->skip(12);
 | 
			
		||||
    
 | 
			
		||||
    if ((ret = srs_mp4_string_read(buf, name, left_space(buf))) != ERROR_SUCCESS) {
 | 
			
		||||
| 
						 | 
				
			
			@ -2766,6 +2847,24 @@ int SrsMp4Decoder::initialize(ISrsReader* r)
 | 
			
		|||
int SrsMp4Decoder::parse_moov(SrsMp4MovieBox* moov)
 | 
			
		||||
{
 | 
			
		||||
    int ret = ERROR_SUCCESS;
 | 
			
		||||
    
 | 
			
		||||
    SrsMp4MovieHeaderBox* mvhd = moov->mvhd();
 | 
			
		||||
    if (!mvhd) {
 | 
			
		||||
        ret = ERROR_MP4_ILLEGAL_MOOV;
 | 
			
		||||
        srs_error("MP4 missing mvhd. ret=%d", ret);
 | 
			
		||||
        return ret;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    SrsMp4TrackBox* vide = moov->video();
 | 
			
		||||
    SrsMp4TrackBox* soun = moov->audio();
 | 
			
		||||
    if (!vide && !soun) {
 | 
			
		||||
        ret = ERROR_MP4_ILLEGAL_MOOV;
 | 
			
		||||
        srs_error("MP4 missing audio and video track. ret=%d", ret);
 | 
			
		||||
        return ret;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    srs_trace("MP4 moov dur=%dms, vide=%d, soun=%d", mvhd->duration(), vide != NULL, soun != NULL);
 | 
			
		||||
    
 | 
			
		||||
    return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -81,9 +81,18 @@ enum SrsMp4BoxType
 | 
			
		|||
    SrsMp4BoxTypeMP4A = 0x6d703461, // 'mp4a'
 | 
			
		||||
    SrsMp4BoxTypeESDS = 0x65736473, // 'esds'
 | 
			
		||||
    SrsMp4BoxTypeUDTA = 0x75647461, // 'udta'
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 8.4.3.3 Semantics
 | 
			
		||||
 * ISO_IEC_14496-12-base-format-2012.pdf, page 37
 | 
			
		||||
 */
 | 
			
		||||
enum SrsMp4HandlerType
 | 
			
		||||
{
 | 
			
		||||
    SrsMp4HandlerTypeForbidden = 0x00,
 | 
			
		||||
    
 | 
			
		||||
    SrsMp4BoxTypeVIDE = 0x76696465, // 'vide'
 | 
			
		||||
    SrsMp4BoxTypeSOUN = 0x736f756e, // 'soun'
 | 
			
		||||
    SrsMp4HandlerTypeVIDE = 0x76696465, // 'vide'
 | 
			
		||||
    SrsMp4HandlerTypeSOUN = 0x736f756e, // 'soun'
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
| 
						 | 
				
			
			@ -121,7 +130,7 @@ public:
 | 
			
		|||
    SrsMp4BoxType type;
 | 
			
		||||
    // For box 'uuid'.
 | 
			
		||||
    uint8_t* usertype;
 | 
			
		||||
private:
 | 
			
		||||
protected:
 | 
			
		||||
    std::vector<SrsMp4Box*> boxes;
 | 
			
		||||
private:
 | 
			
		||||
    // The position at buffer to start demux the box.
 | 
			
		||||
| 
						 | 
				
			
			@ -138,6 +147,9 @@ public:
 | 
			
		|||
    virtual bool is_ftyp();
 | 
			
		||||
    virtual bool is_moov();
 | 
			
		||||
    virtual bool is_mdat();
 | 
			
		||||
    // Get the contained box of specific type.
 | 
			
		||||
    // @return The first matched box.
 | 
			
		||||
    virtual SrsMp4Box* get(SrsMp4BoxType bt);
 | 
			
		||||
    /**
 | 
			
		||||
     * Discovery the box from buffer.
 | 
			
		||||
     * @param ppbox Output the discoveried box, which user must free it.
 | 
			
		||||
| 
						 | 
				
			
			@ -252,6 +264,9 @@ protected:
 | 
			
		|||
    virtual int decode_header(SrsBuffer* buf);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class SrsMp4TrackBox;
 | 
			
		||||
class SrsMp4MovieHeaderBox;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 8.2.1 Movie Box (moov)
 | 
			
		||||
 * ISO_IEC_14496-12-base-format-2012.pdf, page 30
 | 
			
		||||
| 
						 | 
				
			
			@ -263,6 +278,13 @@ class SrsMp4MovieBox : public SrsMp4Box
 | 
			
		|||
public:
 | 
			
		||||
    SrsMp4MovieBox();
 | 
			
		||||
    virtual ~SrsMp4MovieBox();
 | 
			
		||||
public:
 | 
			
		||||
    // Get the header of moov.
 | 
			
		||||
    virtual SrsMp4MovieHeaderBox* mvhd();
 | 
			
		||||
    // Get the first video track.
 | 
			
		||||
    virtual SrsMp4TrackBox* video();
 | 
			
		||||
    // Get the first audio track.
 | 
			
		||||
    virtual SrsMp4TrackBox* audio();
 | 
			
		||||
protected:
 | 
			
		||||
    virtual int nb_header();
 | 
			
		||||
    virtual int encode_header(SrsBuffer* buf);
 | 
			
		||||
| 
						 | 
				
			
			@ -282,6 +304,7 @@ public:
 | 
			
		|||
    // an integer that declares the most recent time the presentation was modified (in
 | 
			
		||||
    // seconds since midnight, Jan. 1, 1904, in UTC time)
 | 
			
		||||
    uint64_t modification_time;
 | 
			
		||||
private:
 | 
			
		||||
    // an integer that specifies the time-scale for the entire presentation; this is the number of
 | 
			
		||||
    // time units that pass in one second. For example, a time coordinate system that measures time in
 | 
			
		||||
    // sixtieths of a second has a time scale of 60.
 | 
			
		||||
| 
						 | 
				
			
			@ -289,7 +312,7 @@ public:
 | 
			
		|||
    // an integer that declares length of the presentation (in the indicated timescale). This property
 | 
			
		||||
    // is derived from the presentation’s tracks: the value of this field corresponds to the duration of the
 | 
			
		||||
    // longest track in the presentation. If the duration cannot be determined then duration is set to all 1s.
 | 
			
		||||
    uint64_t duration;
 | 
			
		||||
    uint64_t duration_in_tbn;
 | 
			
		||||
public:
 | 
			
		||||
    // a fixed point 16.16 number that indicates the preferred rate to play the presentation; 1.0
 | 
			
		||||
    // (0x00010000) is normal forward playback
 | 
			
		||||
| 
						 | 
				
			
			@ -309,12 +332,23 @@ public:
 | 
			
		|||
public:
 | 
			
		||||
    SrsMp4MovieHeaderBox();
 | 
			
		||||
    virtual ~SrsMp4MovieHeaderBox();
 | 
			
		||||
public:
 | 
			
		||||
    // Get the duration in ms.
 | 
			
		||||
    virtual uint64_t duration();
 | 
			
		||||
protected:
 | 
			
		||||
    virtual int nb_header();
 | 
			
		||||
    virtual int encode_header(SrsBuffer* buf);
 | 
			
		||||
    virtual int decode_header(SrsBuffer* buf);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// The type of track, maybe combine of types.
 | 
			
		||||
enum SrsMp4TrackType
 | 
			
		||||
{
 | 
			
		||||
    SrsMp4TrackTypeForbidden = 0x00,
 | 
			
		||||
    SrsMp4TrackTypeAudio = 0x01,
 | 
			
		||||
    SrsMp4TrackTypeVideo = 0x02,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 8.3.1 Track Box (trak)
 | 
			
		||||
 * ISO_IEC_14496-12-base-format-2012.pdf, page 32
 | 
			
		||||
| 
						 | 
				
			
			@ -327,6 +361,11 @@ class SrsMp4TrackBox : public SrsMp4Box
 | 
			
		|||
public:
 | 
			
		||||
    SrsMp4TrackBox();
 | 
			
		||||
    virtual ~SrsMp4TrackBox();
 | 
			
		||||
public:
 | 
			
		||||
    // Get the type of track, maybe combine of track type,
 | 
			
		||||
    // for example, it maybe Audio|Video when contains both.
 | 
			
		||||
    // Generally, only single type, no combination.
 | 
			
		||||
    virtual SrsMp4TrackType track_type();
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
| 
						 | 
				
			
			@ -458,6 +497,11 @@ class SrsMp4MediaBox : public SrsMp4Box
 | 
			
		|||
public:
 | 
			
		||||
    SrsMp4MediaBox();
 | 
			
		||||
    virtual ~SrsMp4MediaBox();
 | 
			
		||||
public:
 | 
			
		||||
    // Get the type of track, maybe combine of track type,
 | 
			
		||||
    // for example, it maybe Audio|Video when contains both.
 | 
			
		||||
    // Generally, only single type, no combination.
 | 
			
		||||
    virtual SrsMp4TrackType track_type();
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
| 
						 | 
				
			
			@ -521,7 +565,7 @@ public:
 | 
			
		|||
    // an integer containing one of the following values, or a value from a derived specification:
 | 
			
		||||
    //      ‘vide’, Video track
 | 
			
		||||
    //      ‘soun’, Audio track
 | 
			
		||||
    uint32_t handler_type;
 | 
			
		||||
    SrsMp4HandlerType handler_type;
 | 
			
		||||
    uint32_t reserved[3];
 | 
			
		||||
    // a null-terminated string in UTF-8 characters which gives a human-readable name for the track
 | 
			
		||||
    // type (for debugging and inspection purposes).
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue