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. * get the number of bytes to code to.
*/ */
// TODO: FIXME: change to uint64_t.
virtual int nb_bytes() = 0; virtual int nb_bytes() = 0;
/** /**
* encode object to bytes in SrsBuffer. * 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_REQUEST_DATA 3066
#define ERROR_EDGE_PORT_INVALID 3067 #define ERROR_EDGE_PORT_INVALID 3067
#define ERROR_EXPECT_FILE_IO 3068 #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. // HTTP/StreamCaster/KAFKA protocol error.

View file

@ -721,6 +721,7 @@ int SrsFlvDecoder::read_header(char header[9])
srs_assert(header); srs_assert(header);
// TODO: FIXME: Should use readfully.
if ((ret = reader->read(header, 9, NULL)) != ERROR_SUCCESS) { if ((ret = reader->read(header, 9, NULL)) != ERROR_SUCCESS) {
return ret; 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 char th[11]; // tag header
// read tag header // read tag header
// TODO: FIXME: Should use readfully.
if ((ret = reader->read(th, 11, NULL)) != ERROR_SUCCESS) { if ((ret = reader->read(th, 11, NULL)) != ERROR_SUCCESS) {
if (ret != ERROR_SYSTEM_FILE_EOF) { if (ret != ERROR_SYSTEM_FILE_EOF) {
srs_error("read flv tag header failed. ret=%d", ret); 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); srs_assert(data);
// TODO: FIXME: Should use readfully.
if ((ret = reader->read(data, size, NULL)) != ERROR_SUCCESS) { if ((ret = reader->read(data, size, NULL)) != ERROR_SUCCESS) {
if (ret != ERROR_SYSTEM_FILE_EOF) { if (ret != ERROR_SYSTEM_FILE_EOF) {
srs_error("read flv tag header failed. ret=%d", ret); 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); srs_assert(previous_tag_size);
// ignore 4bytes tag size. // ignore 4bytes tag size.
// TODO: FIXME: Should use readfully.
if ((ret = reader->read(previous_tag_size, 4, NULL)) != ERROR_SUCCESS) { if ((ret = reader->read(previous_tag_size, 4, NULL)) != ERROR_SUCCESS) {
if (ret != ERROR_SYSTEM_FILE_EOF) { if (ret != ERROR_SYSTEM_FILE_EOF) {
srs_error("read flv previous tag size failed. ret=%d", ret); srs_error("read flv previous tag size failed. ret=%d", ret);

View file

@ -44,6 +44,10 @@ public:
ISrsReader(); ISrsReader();
virtual ~ISrsReader(); virtual ~ISrsReader();
public: 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; 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_core.hpp>
#include <srs_kernel_buffer.hpp>
#include <string> #include <string>
#include <vector>
class ISrsReader; class ISrsReader;
class SrsSimpleStream;
/** /**
* 4.2 Object Structure * 4.2 Object Structure
* ISO_IEC_14496-12-base-format-2012.pdf, page 16 * 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 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 // 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) // 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; 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: public:
SrsMp4Box(); SrsMp4Box();
virtual ~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 * 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 class SrsMp4FullBox : public SrsMp4Box
{ {
@ -64,6 +111,10 @@ public:
public: public:
SrsMp4FullBox(); SrsMp4FullBox();
virtual ~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: public:
SrsMp4FileTypeBox(); SrsMp4FileTypeBox();
virtual ~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 class SrsMp4MediaDataBox : public SrsMp4Box
{ {
private: private:
// the contained media data
int nb_data; int nb_data;
uint8_t* data; uint8_t* data;
public: public:
SrsMp4MediaDataBox(); SrsMp4MediaDataBox();
virtual ~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 class SrsMp4FreeSpaceBox : public SrsMp4Box
{ {
private:
int nb_data;
uint8_t* data;
public: public:
SrsMp4FreeSpaceBox(); SrsMp4FreeSpaceBox();
virtual ~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: public:
SrsMp4MovieHeaderBox(); SrsMp4MovieHeaderBox();
virtual ~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 // an integer that declares the most recent time the presentation was modified (in
// seconds since midnight, Jan. 1, 1904, in UTC time) // seconds since midnight, Jan. 1, 1904, in UTC time)
uint64_t modification_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. // 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. // Track IDs are never re-used and cannot be zero.
uint32_t track_ID; uint32_t track_ID;
@ -244,6 +311,10 @@ public:
public: public:
SrsMp4TrackHeaderBox(); SrsMp4TrackHeaderBox();
virtual ~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; int16_t media_rate_fraction;
public: public:
SrsMp4ElstEntry(); 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: public:
SrsMp4EditListBox(); SrsMp4EditListBox();
virtual ~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 // 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. // longest track in the presentation. If the duration cannot be determined then duration is set to all 1s.
uint64_t duration; uint64_t duration;
public: private:
uint8_t pad:1;
// the language code for this media. See ISO 639-2/T for the set of three character // 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 // 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. // is confined to being three lower-case letters, these values are strictly positive.
uint16_t language:15; uint16_t language;
uint16_t pre_defined; uint16_t pre_defined;
public: public:
SrsMp4MediaHeaderBox(); SrsMp4MediaHeaderBox();
virtual ~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: public:
SrsMp4HandlerReferenceBox(); SrsMp4HandlerReferenceBox();
virtual ~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: public:
SrsMp4VideoMeidaHeaderBox(); SrsMp4VideoMeidaHeaderBox();
virtual ~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: public:
SrsMp4SoundMeidaHeaderBox(); SrsMp4SoundMeidaHeaderBox();
virtual ~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; std::string location;
public: public:
SrsMp4DataEntryBox(); 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: public:
SrsMp4DataEntryUrlBox(); SrsMp4DataEntryUrlBox();
virtual ~SrsMp4DataEntryUrlBox();
}; };
/** /**
@ -467,6 +577,11 @@ public:
std::string name; std::string name;
public: public:
SrsMp4DataEntryUrnBox(); 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 class SrsMp4DataReferenceBox : public SrsMp4FullBox
{ {
public: private:
// an integer that counts the actual entries std::vector<SrsMp4DataEntryBox*> entries;
uint32_t entry_count;
SrsMp4DataEntryBox* entries;
public: public:
SrsMp4DataReferenceBox(); SrsMp4DataReferenceBox();
virtual ~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: public:
SrsMp4SampleEntry(); SrsMp4SampleEntry();
virtual ~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: public:
SrsMp4VisualSampleEntry(); SrsMp4VisualSampleEntry();
virtual ~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 class SrsMp4AudioSampleEntry : public SrsMp4SampleEntry
{ {
public: public:
uint32_t reserved0[2]; uint64_t reserved0;
uint16_t channelcount; uint16_t channelcount;
uint16_t samplesize; uint16_t samplesize;
uint16_t pre_defined0; uint16_t pre_defined0;
@ -567,6 +695,10 @@ public:
public: public:
SrsMp4AudioSampleEntry(); SrsMp4AudioSampleEntry();
virtual ~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 class SrsMp4SampleDescriptionBox : public SrsMp4FullBox
{ {
public: private:
// an integer that gives the number of entries in the following table std::vector<SrsMp4SampleEntry*> entries;
uint32_t entry_count;
SrsMp4SampleEntry* entries;
public: public:
SrsMp4SampleDescriptionBox(); SrsMp4SampleDescriptionBox();
virtual ~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: public:
SrsMp4DecodingTime2SampleBox(); SrsMp4DecodingTime2SampleBox();
virtual ~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: public:
SrsMp4CompositionTime2SampleBox(); SrsMp4CompositionTime2SampleBox();
virtual ~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: public:
SrsMp4SyncSampleBox(); SrsMp4SyncSampleBox();
virtual ~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: public:
SrsMp4Sample2ChunkBox(); SrsMp4Sample2ChunkBox();
virtual ~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: public:
SrsMp4ChunkOffsetBox(); SrsMp4ChunkOffsetBox();
virtual ~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: public:
SrsMp4SampleSizeBox(); SrsMp4SampleSizeBox();
virtual ~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 class SrsMp4Decoder
{ {
private: private:
// Underlayer reader.
ISrsReader* 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: public:
SrsMp4Decoder(); SrsMp4Decoder();
virtual ~SrsMp4Decoder(); virtual ~SrsMp4Decoder();
@ -779,6 +946,8 @@ public:
* the decoder just read data from the reader. * the decoder just read data from the reader.
*/ */
virtual int initialize(ISrsReader* r); virtual int initialize(ISrsReader* r);
private:
virtual int load_next_box(SrsMp4Box** ppbox);
}; };
#endif #endif