1
0
Fork 0
mirror of https://github.com/ossrs/srs.git synced 2025-02-15 04:42:04 +00:00

for #738, implements boxes codec

This commit is contained in:
winlin 2017-02-01 21:57:32 +08:00
parent b6bb3f2446
commit 2ad265bd5a
6 changed files with 1864 additions and 61 deletions

View file

@ -69,6 +69,7 @@ public:
/**
* get the number of bytes to code to.
*/
// TODO: FIXME: change to uint64_t.
virtual int nb_bytes() = 0;
/**
* encode object to bytes in SrsBuffer.

View file

@ -242,6 +242,11 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define ERROR_REQUEST_DATA 3066
#define ERROR_EDGE_PORT_INVALID 3067
#define ERROR_EXPECT_FILE_IO 3068
#define ERROR_MP4_BOX_OVERFLOW 3069
#define ERROR_MP4_BOX_REQUIRE_SPACE 3070
#define ERROR_MP4_BOX_ILLEGAL_TYPE 3071
#define ERROR_MP4_BOX_ILLEGAL_SCHEMA 3072
#define ERROR_MP4_BOX_STRING 3073
///////////////////////////////////////////////////////
// HTTP/StreamCaster/KAFKA protocol error.

View file

@ -721,6 +721,7 @@ int SrsFlvDecoder::read_header(char header[9])
srs_assert(header);
// TODO: FIXME: Should use readfully.
if ((ret = reader->read(header, 9, NULL)) != ERROR_SUCCESS) {
return ret;
}
@ -746,6 +747,7 @@ int SrsFlvDecoder::read_tag_header(char* ptype, int32_t* pdata_size, uint32_t* p
char th[11]; // tag header
// read tag header
// TODO: FIXME: Should use readfully.
if ((ret = reader->read(th, 11, NULL)) != ERROR_SUCCESS) {
if (ret != ERROR_SYSTEM_FILE_EOF) {
srs_error("read flv tag header failed. ret=%d", ret);
@ -783,6 +785,7 @@ int SrsFlvDecoder::read_tag_data(char* data, int32_t size)
srs_assert(data);
// TODO: FIXME: Should use readfully.
if ((ret = reader->read(data, size, NULL)) != ERROR_SUCCESS) {
if (ret != ERROR_SYSTEM_FILE_EOF) {
srs_error("read flv tag header failed. ret=%d", ret);
@ -801,6 +804,7 @@ int SrsFlvDecoder::read_previous_tag_size(char previous_tag_size[4])
srs_assert(previous_tag_size);
// ignore 4bytes tag size.
// TODO: FIXME: Should use readfully.
if ((ret = reader->read(previous_tag_size, 4, NULL)) != ERROR_SUCCESS) {
if (ret != ERROR_SYSTEM_FILE_EOF) {
srs_error("read flv previous tag size failed. ret=%d", ret);

View file

@ -44,6 +44,10 @@ public:
ISrsReader();
virtual ~ISrsReader();
public:
/**
* Read bytes from reader.
* @param nread How many bytes read from channel. NULL to ignore.
*/
virtual int read(void* buf, size_t size, ssize_t* nread) = 0;
};

File diff suppressed because it is too large Load diff

View file

@ -29,30 +29,77 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include <srs_core.hpp>
#include <srs_kernel_buffer.hpp>
#include <string>
#include <vector>
class ISrsReader;
class SrsSimpleStream;
/**
* 4.2 Object Structure
* ISO_IEC_14496-12-base-format-2012.pdf, page 16
*/
class SrsMp4Box
class SrsMp4Box : public ISrsCodec
{
public:
private:
// The size is the entire size of the box, including the size and type header, fields,
// and all contained boxes. This facilitates general parsing of the file.
//
// if size is 1 then the actual size is in the field largesize;
// if size is 0, then this box is the last one in the file, and its contents
// extend to the end of the file (normally only used for a Media Data Box)
uint32_t size;
uint32_t smallsize;
uint64_t largesize;
public:
// identifies the box type; standard boxes use a compact type, which is normally four printable
// characters, to permit ease of identification, and is shown so in the boxes below. User extensions use
// an extended type; in this case, the type field is set to uuid.
uint32_t type;
// For box 'uuid'.
uint8_t* usertype;
private:
std::vector<SrsMp4Box*> boxes;
private:
// The position at buffer to start demux the box.
int start_pos;
public:
SrsMp4Box();
virtual ~SrsMp4Box();
public:
// Get the size of box, whatever small or large size.
virtual uint64_t sz();
// Get the left space of box, for decoder.
virtual int left_space(SrsBuffer* buf);
/**
* Discovery the box from buffer.
* @param ppbox Output the discoveried box, which user must free it.
*/
static int discovery(SrsBuffer* buf, SrsMp4Box** ppbox);
// Interface ISrsCodec
public:
virtual int nb_bytes();
virtual int encode(SrsBuffer* buf);
virtual int decode(SrsBuffer* buf);
protected:
virtual int encode_boxes(SrsBuffer* buf);
virtual int decode_boxes(SrsBuffer* buf);
// Sub classes can override these functions for special codec.
protected:
// The size of header, not including the contained boxes.
virtual int nb_header();
// It's not necessary to check the buffer, because we already know the size in parent function,
// so we have checked the buffer is ok to write.
virtual int encode_header(SrsBuffer* buf);
// It's not necessary to check the buffer, unless the box is not only determined by the verson.
// Generally, it's not necessary, that is, all boxes is determinated by version.
virtual int decode_header(SrsBuffer* buf);
};
/**
* 4.2 Object Structure
* ISO_IEC_14496-12-base-format-2012.pdf, page 16
* ISO_IEC_14496-12-base-format-2012.pdf, page 17
*/
class SrsMp4FullBox : public SrsMp4Box
{
@ -64,6 +111,10 @@ public:
public:
SrsMp4FullBox();
virtual ~SrsMp4FullBox();
protected:
virtual int nb_header();
virtual int encode_header(SrsBuffer* buf);
virtual int decode_header(SrsBuffer* buf);
};
/**
@ -88,6 +139,10 @@ private:
public:
SrsMp4FileTypeBox();
virtual ~SrsMp4FileTypeBox();
protected:
virtual int nb_header();
virtual int encode_header(SrsBuffer* buf);
virtual int decode_header(SrsBuffer* buf);
};
/**
@ -101,11 +156,16 @@ public:
class SrsMp4MediaDataBox : public SrsMp4Box
{
private:
// the contained media data
int nb_data;
uint8_t* data;
public:
SrsMp4MediaDataBox();
virtual ~SrsMp4MediaDataBox();
protected:
virtual int nb_header();
virtual int encode_header(SrsBuffer* buf);
virtual int decode_header(SrsBuffer* buf);
};
/**
@ -114,9 +174,16 @@ public:
*/
class SrsMp4FreeSpaceBox : public SrsMp4Box
{
private:
int nb_data;
uint8_t* data;
public:
SrsMp4FreeSpaceBox();
virtual ~SrsMp4FreeSpaceBox();
protected:
virtual int nb_header();
virtual int encode_header(SrsBuffer* buf);
virtual int decode_header(SrsBuffer* buf);
};
/**
@ -172,6 +239,10 @@ public:
public:
SrsMp4MovieHeaderBox();
virtual ~SrsMp4MovieHeaderBox();
protected:
virtual int nb_header();
virtual int encode_header(SrsBuffer* buf);
virtual int decode_header(SrsBuffer* buf);
};
/**
@ -201,10 +272,6 @@ 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;
// 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.
uint32_t timescale;
// an integer that uniquely identifies this track over the entire life-time of this presentation.
// Track IDs are never re-used and cannot be zero.
uint32_t track_ID;
@ -244,6 +311,10 @@ public:
public:
SrsMp4TrackHeaderBox();
virtual ~SrsMp4TrackHeaderBox();
protected:
virtual int nb_header();
virtual int encode_header(SrsBuffer* buf);
virtual int decode_header(SrsBuffer* buf);
};
/**
@ -282,6 +353,10 @@ public:
int16_t media_rate_fraction;
public:
SrsMp4ElstEntry();
public:
virtual int nb_header(uint32_t version);
virtual int encode_header(SrsBuffer* buf, uint32_t version);
virtual int decode_header(SrsBuffer* buf, uint32_t version);
};
/**
@ -300,6 +375,10 @@ public:
public:
SrsMp4EditListBox();
virtual ~SrsMp4EditListBox();
protected:
virtual int nb_header();
virtual int encode_header(SrsBuffer* buf);
virtual int decode_header(SrsBuffer* buf);
};
/**
@ -338,16 +417,29 @@ public:
// is derived from the presentations 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;
public:
uint8_t pad:1;
private:
// the language code for this media. See ISO 639-2/T for the set of three character
// codes. Each character is packed as the difference between its ASCII value and 0x60. Since the code
// is confined to being three lower-case letters, these values are strictly positive.
uint16_t language:15;
uint16_t language;
uint16_t pre_defined;
public:
SrsMp4MediaHeaderBox();
virtual ~SrsMp4MediaHeaderBox();
public:
// the language code for this media. See ISO 639-2/T for the set of three character
// codes. Each character is packed as the difference between its ASCII value and 0x60. Since the code
// is confined to being three lower-case letters, these values are strictly positive.
virtual uint8_t language0();
virtual void set_language0(uint8_t v);
virtual uint8_t language1();
virtual void set_language1(uint8_t v);
virtual uint8_t language2();
virtual void set_language2(uint8_t v);
protected:
virtual int nb_header();
virtual int encode_header(SrsBuffer* buf);
virtual int decode_header(SrsBuffer* buf);
};
/**
@ -371,6 +463,10 @@ public:
public:
SrsMp4HandlerReferenceBox();
virtual ~SrsMp4HandlerReferenceBox();
protected:
virtual int nb_header();
virtual int encode_header(SrsBuffer* buf);
virtual int decode_header(SrsBuffer* buf);
};
/**
@ -403,6 +499,10 @@ public:
public:
SrsMp4VideoMeidaHeaderBox();
virtual ~SrsMp4VideoMeidaHeaderBox();
protected:
virtual int nb_header();
virtual int encode_header(SrsBuffer* buf);
virtual int decode_header(SrsBuffer* buf);
};
/**
@ -421,6 +521,10 @@ public:
public:
SrsMp4SoundMeidaHeaderBox();
virtual ~SrsMp4SoundMeidaHeaderBox();
protected:
virtual int nb_header();
virtual int encode_header(SrsBuffer* buf);
virtual int decode_header(SrsBuffer* buf);
};
/**
@ -445,6 +549,11 @@ public:
std::string location;
public:
SrsMp4DataEntryBox();
virtual ~SrsMp4DataEntryBox();
protected:
virtual int nb_header();
virtual int encode_header(SrsBuffer* buf);
virtual int decode_header(SrsBuffer* buf);
};
/**
@ -455,6 +564,7 @@ class SrsMp4DataEntryUrlBox : public SrsMp4DataEntryBox
{
public:
SrsMp4DataEntryUrlBox();
virtual ~SrsMp4DataEntryUrlBox();
};
/**
@ -467,6 +577,11 @@ public:
std::string name;
public:
SrsMp4DataEntryUrnBox();
virtual ~SrsMp4DataEntryUrnBox();
protected:
virtual int nb_header();
virtual int encode_header(SrsBuffer* buf);
virtual int decode_header(SrsBuffer* buf);
};
/**
@ -478,13 +593,18 @@ public:
*/
class SrsMp4DataReferenceBox : public SrsMp4FullBox
{
public:
// an integer that counts the actual entries
uint32_t entry_count;
SrsMp4DataEntryBox* entries;
private:
std::vector<SrsMp4DataEntryBox*> entries;
public:
SrsMp4DataReferenceBox();
virtual ~SrsMp4DataReferenceBox();
public:
virtual uint32_t entry_count();
virtual SrsMp4DataEntryBox* entry_at(int index);
protected:
virtual int nb_header();
virtual int encode_header(SrsBuffer* buf);
virtual int decode_header(SrsBuffer* buf);
};
/**
@ -516,6 +636,10 @@ public:
public:
SrsMp4SampleEntry();
virtual ~SrsMp4SampleEntry();
protected:
virtual int nb_header();
virtual int encode_header(SrsBuffer* buf);
virtual int decode_header(SrsBuffer* buf);
};
/**
@ -549,6 +673,10 @@ public:
public:
SrsMp4VisualSampleEntry();
virtual ~SrsMp4VisualSampleEntry();
protected:
virtual int nb_header();
virtual int encode_header(SrsBuffer* buf);
virtual int decode_header(SrsBuffer* buf);
};
/**
@ -558,7 +686,7 @@ public:
class SrsMp4AudioSampleEntry : public SrsMp4SampleEntry
{
public:
uint32_t reserved0[2];
uint64_t reserved0;
uint16_t channelcount;
uint16_t samplesize;
uint16_t pre_defined0;
@ -567,6 +695,10 @@ public:
public:
SrsMp4AudioSampleEntry();
virtual ~SrsMp4AudioSampleEntry();
protected:
virtual int nb_header();
virtual int encode_header(SrsBuffer* buf);
virtual int decode_header(SrsBuffer* buf);
};
/**
@ -577,13 +709,18 @@ public:
*/
class SrsMp4SampleDescriptionBox : public SrsMp4FullBox
{
public:
// an integer that gives the number of entries in the following table
uint32_t entry_count;
SrsMp4SampleEntry* entries;
private:
std::vector<SrsMp4SampleEntry*> entries;
public:
SrsMp4SampleDescriptionBox();
virtual ~SrsMp4SampleDescriptionBox();
public:
virtual uint32_t entry_count();
virtual SrsMp4SampleEntry* entrie_at(int index);
protected:
virtual int nb_header();
virtual int encode_header(SrsBuffer* buf);
virtual int decode_header(SrsBuffer* buf);
};
/**
@ -618,6 +755,10 @@ public:
public:
SrsMp4DecodingTime2SampleBox();
virtual ~SrsMp4DecodingTime2SampleBox();
protected:
virtual int nb_header();
virtual int encode_header(SrsBuffer* buf);
virtual int decode_header(SrsBuffer* buf);
};
@ -657,6 +798,10 @@ public:
public:
SrsMp4CompositionTime2SampleBox();
virtual ~SrsMp4CompositionTime2SampleBox();
protected:
virtual int nb_header();
virtual int encode_header(SrsBuffer* buf);
virtual int decode_header(SrsBuffer* buf);
};
/**
@ -676,6 +821,10 @@ public:
public:
SrsMp4SyncSampleBox();
virtual ~SrsMp4SyncSampleBox();
protected:
virtual int nb_header();
virtual int encode_header(SrsBuffer* buf);
virtual int decode_header(SrsBuffer* buf);
};
/**
@ -716,6 +865,10 @@ public:
public:
SrsMp4Sample2ChunkBox();
virtual ~SrsMp4Sample2ChunkBox();
protected:
virtual int nb_header();
virtual int encode_header(SrsBuffer* buf);
virtual int decode_header(SrsBuffer* buf);
};
/**
@ -736,6 +889,10 @@ public:
public:
SrsMp4ChunkOffsetBox();
virtual ~SrsMp4ChunkOffsetBox();
protected:
virtual int nb_header();
virtual int encode_header(SrsBuffer* buf);
virtual int decode_header(SrsBuffer* buf);
};
/**
@ -760,6 +917,10 @@ public:
public:
SrsMp4SampleSizeBox();
virtual ~SrsMp4SampleSizeBox();
protected:
virtual int nb_header();
virtual int encode_header(SrsBuffer* buf);
virtual int decode_header(SrsBuffer* buf);
};
/**
@ -768,7 +929,13 @@ public:
class SrsMp4Decoder
{
private:
// Underlayer reader.
ISrsReader* reader;
// The stream used to demux the boxes.
// TODO: FIXME: refine for performance issue.
SrsSimpleStream* stream;
// Always load next box.
SrsMp4Box* next;
public:
SrsMp4Decoder();
virtual ~SrsMp4Decoder();
@ -779,6 +946,8 @@ public:
* the decoder just read data from the reader.
*/
virtual int initialize(ISrsReader* r);
private:
virtual int load_next_box(SrsMp4Box** ppbox);
};
#endif