正在显示
6 个修改的文件
包含
1926 行增加
和
123 行删除
| @@ -69,6 +69,7 @@ public: | @@ -69,6 +69,7 @@ public: | ||
| 69 | /** | 69 | /** |
| 70 | * get the number of bytes to code to. | 70 | * get the number of bytes to code to. |
| 71 | */ | 71 | */ |
| 72 | + // TODO: FIXME: change to uint64_t. | ||
| 72 | virtual int nb_bytes() = 0; | 73 | virtual int nb_bytes() = 0; |
| 73 | /** | 74 | /** |
| 74 | * encode object to bytes in SrsBuffer. | 75 | * encode object to bytes in SrsBuffer. |
| @@ -242,6 +242,11 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | @@ -242,6 +242,11 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
| 242 | #define ERROR_REQUEST_DATA 3066 | 242 | #define ERROR_REQUEST_DATA 3066 |
| 243 | #define ERROR_EDGE_PORT_INVALID 3067 | 243 | #define ERROR_EDGE_PORT_INVALID 3067 |
| 244 | #define ERROR_EXPECT_FILE_IO 3068 | 244 | #define ERROR_EXPECT_FILE_IO 3068 |
| 245 | +#define ERROR_MP4_BOX_OVERFLOW 3069 | ||
| 246 | +#define ERROR_MP4_BOX_REQUIRE_SPACE 3070 | ||
| 247 | +#define ERROR_MP4_BOX_ILLEGAL_TYPE 3071 | ||
| 248 | +#define ERROR_MP4_BOX_ILLEGAL_SCHEMA 3072 | ||
| 249 | +#define ERROR_MP4_BOX_STRING 3073 | ||
| 245 | 250 | ||
| 246 | /////////////////////////////////////////////////////// | 251 | /////////////////////////////////////////////////////// |
| 247 | // HTTP/StreamCaster/KAFKA protocol error. | 252 | // HTTP/StreamCaster/KAFKA protocol error. |
| @@ -721,6 +721,7 @@ int SrsFlvDecoder::read_header(char header[9]) | @@ -721,6 +721,7 @@ int SrsFlvDecoder::read_header(char header[9]) | ||
| 721 | 721 | ||
| 722 | srs_assert(header); | 722 | srs_assert(header); |
| 723 | 723 | ||
| 724 | + // TODO: FIXME: Should use readfully. | ||
| 724 | if ((ret = reader->read(header, 9, NULL)) != ERROR_SUCCESS) { | 725 | if ((ret = reader->read(header, 9, NULL)) != ERROR_SUCCESS) { |
| 725 | return ret; | 726 | return ret; |
| 726 | } | 727 | } |
| @@ -746,6 +747,7 @@ int SrsFlvDecoder::read_tag_header(char* ptype, int32_t* pdata_size, uint32_t* p | @@ -746,6 +747,7 @@ int SrsFlvDecoder::read_tag_header(char* ptype, int32_t* pdata_size, uint32_t* p | ||
| 746 | char th[11]; // tag header | 747 | char th[11]; // tag header |
| 747 | 748 | ||
| 748 | // read tag header | 749 | // read tag header |
| 750 | + // TODO: FIXME: Should use readfully. | ||
| 749 | if ((ret = reader->read(th, 11, NULL)) != ERROR_SUCCESS) { | 751 | if ((ret = reader->read(th, 11, NULL)) != ERROR_SUCCESS) { |
| 750 | if (ret != ERROR_SYSTEM_FILE_EOF) { | 752 | if (ret != ERROR_SYSTEM_FILE_EOF) { |
| 751 | srs_error("read flv tag header failed. ret=%d", ret); | 753 | srs_error("read flv tag header failed. ret=%d", ret); |
| @@ -783,6 +785,7 @@ int SrsFlvDecoder::read_tag_data(char* data, int32_t size) | @@ -783,6 +785,7 @@ int SrsFlvDecoder::read_tag_data(char* data, int32_t size) | ||
| 783 | 785 | ||
| 784 | srs_assert(data); | 786 | srs_assert(data); |
| 785 | 787 | ||
| 788 | + // TODO: FIXME: Should use readfully. | ||
| 786 | if ((ret = reader->read(data, size, NULL)) != ERROR_SUCCESS) { | 789 | if ((ret = reader->read(data, size, NULL)) != ERROR_SUCCESS) { |
| 787 | if (ret != ERROR_SYSTEM_FILE_EOF) { | 790 | if (ret != ERROR_SYSTEM_FILE_EOF) { |
| 788 | srs_error("read flv tag header failed. ret=%d", ret); | 791 | 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]) | @@ -801,6 +804,7 @@ int SrsFlvDecoder::read_previous_tag_size(char previous_tag_size[4]) | ||
| 801 | srs_assert(previous_tag_size); | 804 | srs_assert(previous_tag_size); |
| 802 | 805 | ||
| 803 | // ignore 4bytes tag size. | 806 | // ignore 4bytes tag size. |
| 807 | + // TODO: FIXME: Should use readfully. | ||
| 804 | if ((ret = reader->read(previous_tag_size, 4, NULL)) != ERROR_SUCCESS) { | 808 | if ((ret = reader->read(previous_tag_size, 4, NULL)) != ERROR_SUCCESS) { |
| 805 | if (ret != ERROR_SYSTEM_FILE_EOF) { | 809 | if (ret != ERROR_SYSTEM_FILE_EOF) { |
| 806 | srs_error("read flv previous tag size failed. ret=%d", ret); | 810 | srs_error("read flv previous tag size failed. ret=%d", ret); |
| @@ -44,6 +44,10 @@ public: | @@ -44,6 +44,10 @@ public: | ||
| 44 | ISrsReader(); | 44 | ISrsReader(); |
| 45 | virtual ~ISrsReader(); | 45 | virtual ~ISrsReader(); |
| 46 | public: | 46 | public: |
| 47 | + /** | ||
| 48 | + * Read bytes from reader. | ||
| 49 | + * @param nread How many bytes read from channel. NULL to ignore. | ||
| 50 | + */ | ||
| 47 | virtual int read(void* buf, size_t size, ssize_t* nread) = 0; | 51 | virtual int read(void* buf, size_t size, ssize_t* nread) = 0; |
| 48 | }; | 52 | }; |
| 49 | 53 |
| @@ -23,19 +23,380 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | @@ -23,19 +23,380 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
| 23 | 23 | ||
| 24 | #include <srs_kernel_mp4.hpp> | 24 | #include <srs_kernel_mp4.hpp> |
| 25 | 25 | ||
| 26 | -#include <string.h> | ||
| 27 | - | ||
| 28 | #include <srs_kernel_log.hpp> | 26 | #include <srs_kernel_log.hpp> |
| 29 | #include <srs_kernel_error.hpp> | 27 | #include <srs_kernel_error.hpp> |
| 28 | +#include <srs_kernel_stream.hpp> | ||
| 29 | +#include <srs_core_autofree.hpp> | ||
| 30 | +#include <srs_kernel_io.hpp> | ||
| 31 | +#include <srs_kernel_buffer.hpp> | ||
| 32 | + | ||
| 33 | +#include <string.h> | ||
| 34 | +using namespace std; | ||
| 35 | + | ||
| 36 | +#define SRS_MP4_BOX_UUID 0x75756964 // 'uuid' | ||
| 37 | +#define SRS_MP4_BOX_FTYP 0x66747970 // 'ftyp' | ||
| 38 | +#define SRS_MP4_BOX_MDAT 0x6d646174 // 'mdat' | ||
| 39 | +#define SRS_MP4_BOX_FREE 0x66726565 // 'free' | ||
| 40 | +#define SRS_MP4_BOX_SKIP 0x736b6970 // 'skip' | ||
| 41 | +#define SRS_MP4_BOX_MOOV 0x6d6f6f76 // 'moov' | ||
| 42 | +#define SRS_MP4_BOX_MVHD 0x6d766864 // 'mvhd' | ||
| 43 | +#define SRS_MP4_BOX_TRAK 0x7472616b // 'trak' | ||
| 44 | +#define SRS_MP4_BOX_TKHD 0x746b6864 // 'tkhd' | ||
| 45 | +#define SRS_MP4_BOX_EDTS 0x65647473 // 'edts' | ||
| 46 | +#define SRS_MP4_BOX_ELST 0x656c7374 // 'elst' | ||
| 47 | +#define SRS_MP4_BOX_MDIA 0x6d646961 // 'mdia' | ||
| 48 | +#define SRS_MP4_BOX_MDHD 0x6d646864 // 'mdhd' | ||
| 49 | +#define SRS_MP4_BOX_HDLR 0x68646c72 // 'hdlr' | ||
| 50 | +#define SRS_MP4_BOX_MINF 0x6d696e66 // 'minf' | ||
| 51 | +#define SRS_MP4_BOX_VMHD 0x766d6864 // 'vmhd' | ||
| 52 | +#define SRS_MP4_BOX_SMHD 0x736d6864 // 'smhd' | ||
| 53 | +#define SRS_MP4_BOX_DINF 0x64696e66 // 'dinf' | ||
| 54 | +#define SRS_MP4_BOX_URL 0x75726c20 // 'url ' | ||
| 55 | +#define SRS_MP4_BOX_URN 0x75726e20 // 'urn ' | ||
| 56 | +#define SRS_MP4_BOX_DREF 0x64726566 // 'dref' | ||
| 57 | +#define SRS_MP4_BOX_STBL 0x7374626c // 'stbl' | ||
| 58 | +#define SRS_MP4_BOX_STSD 0x73747364 // 'stsd' | ||
| 59 | +#define SRS_MP4_BOX_STTS 0x73747473 // 'stts' | ||
| 60 | +#define SRS_MP4_BOX_CTTS 0x63747473 // 'ctts' | ||
| 61 | +#define SRS_MP4_BOX_STSS 0x73747373 // 'stss' | ||
| 62 | +#define SRS_MP4_BOX_STSC 0x73747363 // 'stsc' | ||
| 63 | +#define SRS_MP4_BOX_STCO 0x7374636f // 'stco' | ||
| 64 | +#define SRS_MP4_BOX_STSZ 0x7374737a // 'stsz' | ||
| 65 | + | ||
| 66 | +#define SRS_MP4_EOF_SIZE 0 | ||
| 67 | +#define SRS_MP4_USE_LARGE_SIZE 1 | ||
| 68 | + | ||
| 69 | +int srs_mp4_string_length(const string& v) | ||
| 70 | +{ | ||
| 71 | + return (int)v.length()+1; | ||
| 72 | +} | ||
| 73 | + | ||
| 74 | +void srs_mp4_string_write(SrsBuffer* buf, const string& v) | ||
| 75 | +{ | ||
| 76 | + if (!v.empty()) { | ||
| 77 | + buf->write_bytes((char*)v.data(), (int)v.length()); | ||
| 78 | + } | ||
| 79 | + buf->write_1bytes(0x00); | ||
| 80 | +} | ||
| 81 | + | ||
| 82 | +int srs_mp4_string_read(SrsBuffer* buf, string& v, int left) | ||
| 83 | +{ | ||
| 84 | + int ret = ERROR_SUCCESS; | ||
| 85 | + | ||
| 86 | + char* p = buf->data() + buf->pos(); | ||
| 87 | + | ||
| 88 | + char* start = p; | ||
| 89 | + while (p < start + left) { | ||
| 90 | + if (*p == 0x00) { | ||
| 91 | + v.append(start, p - start); | ||
| 92 | + buf->skip((int)(p - start)); | ||
| 93 | + return ret; | ||
| 94 | + } | ||
| 95 | + } | ||
| 96 | + | ||
| 97 | + ret = ERROR_MP4_BOX_STRING; | ||
| 98 | + srs_error("MP4 string corrupt, left=%d. ret=%d", left, ret); | ||
| 99 | + return ret; | ||
| 100 | +} | ||
| 30 | 101 | ||
| 31 | SrsMp4Box::SrsMp4Box() | 102 | SrsMp4Box::SrsMp4Box() |
| 32 | { | 103 | { |
| 33 | - size = 0; | 104 | + smallsize = 0; |
| 105 | + largesize = 0; | ||
| 106 | + usertype = NULL; | ||
| 107 | + start_pos = 0; | ||
| 34 | type = 0; | 108 | type = 0; |
| 35 | } | 109 | } |
| 36 | 110 | ||
| 37 | SrsMp4Box::~SrsMp4Box() | 111 | SrsMp4Box::~SrsMp4Box() |
| 38 | { | 112 | { |
| 113 | + vector<SrsMp4Box*>::iterator it; | ||
| 114 | + for (it = boxes.begin(); it != boxes.end(); ++it) { | ||
| 115 | + SrsMp4Box* box = *it; | ||
| 116 | + srs_freep(box); | ||
| 117 | + } | ||
| 118 | + boxes.clear(); | ||
| 119 | + | ||
| 120 | + srs_freepa(usertype); | ||
| 121 | +} | ||
| 122 | + | ||
| 123 | +uint64_t SrsMp4Box::sz() | ||
| 124 | +{ | ||
| 125 | + return smallsize == SRS_MP4_USE_LARGE_SIZE? largesize:smallsize; | ||
| 126 | +} | ||
| 127 | + | ||
| 128 | +int SrsMp4Box::left_space(SrsBuffer* buf) | ||
| 129 | +{ | ||
| 130 | + return (int)sz() - (buf->pos() - start_pos); | ||
| 131 | +} | ||
| 132 | + | ||
| 133 | +int SrsMp4Box::discovery(SrsBuffer* buf, SrsMp4Box** ppbox) | ||
| 134 | +{ | ||
| 135 | + *ppbox = NULL; | ||
| 136 | + | ||
| 137 | + int ret = ERROR_SUCCESS; | ||
| 138 | + | ||
| 139 | + if (!buf->require(8)) { | ||
| 140 | + ret = ERROR_MP4_BOX_REQUIRE_SPACE; | ||
| 141 | + srs_error("MP4 discovery require 8 bytes space. ret=%d", ret); | ||
| 142 | + return ret; | ||
| 143 | + } | ||
| 144 | + | ||
| 145 | + // Discovery the size and type. | ||
| 146 | + uint64_t largesize = 0; | ||
| 147 | + uint32_t smallsize = (uint32_t)buf->read_4bytes(); | ||
| 148 | + uint32_t type = (uint32_t)buf->read_4bytes(); | ||
| 149 | + if (smallsize == SRS_MP4_USE_LARGE_SIZE) { | ||
| 150 | + if (!buf->require(8)) { | ||
| 151 | + ret = ERROR_MP4_BOX_REQUIRE_SPACE; | ||
| 152 | + srs_error("MP4 discovery require 16 bytes space. ret=%d", ret); | ||
| 153 | + return ret; | ||
| 154 | + } | ||
| 155 | + largesize = (uint64_t)buf->read_8bytes(); | ||
| 156 | + buf->skip(-8); | ||
| 157 | + } | ||
| 158 | + buf->skip(-8); | ||
| 159 | + | ||
| 160 | + // Only support 31bits size. | ||
| 161 | + if (largesize > 0x7fffffff) { | ||
| 162 | + ret = ERROR_MP4_BOX_OVERFLOW; | ||
| 163 | + srs_error("MP4 discovery overflow 31bits, size=%"PRId64". ret=%d", largesize, ret); | ||
| 164 | + return ret; | ||
| 165 | + } | ||
| 166 | + | ||
| 167 | + SrsMp4Box* box = NULL; | ||
| 168 | + switch(type) { | ||
| 169 | + case SRS_MP4_BOX_FTYP: box = new SrsMp4FileTypeBox(); break; | ||
| 170 | + case SRS_MP4_BOX_MDAT: box = new SrsMp4MediaDataBox(); break; | ||
| 171 | + case SRS_MP4_BOX_FREE: case SRS_MP4_BOX_SKIP: box = new SrsMp4FreeSpaceBox(); break; | ||
| 172 | + case SRS_MP4_BOX_MOOV: box = new SrsMp4MovieBox(); break; | ||
| 173 | + case SRS_MP4_BOX_MVHD: box = new SrsMp4MovieHeaderBox(); break; | ||
| 174 | + case SRS_MP4_BOX_TRAK: box = new SrsMp4TrackBox(); break; | ||
| 175 | + case SRS_MP4_BOX_TKHD: box = new SrsMp4TrackHeaderBox(); break; | ||
| 176 | + case SRS_MP4_BOX_EDTS: box = new SrsMp4EditBox(); break; | ||
| 177 | + case SRS_MP4_BOX_ELST: box = new SrsMp4EditListBox(); break; | ||
| 178 | + case SRS_MP4_BOX_MDIA: box = new SrsMp4MediaBox(); break; | ||
| 179 | + case SRS_MP4_BOX_MDHD: box = new SrsMp4MediaHeaderBox(); break; | ||
| 180 | + case SRS_MP4_BOX_HDLR: box = new SrsMp4HandlerReferenceBox(); break; | ||
| 181 | + case SRS_MP4_BOX_MINF: box = new SrsMp4MediaInformationBox(); break; | ||
| 182 | + case SRS_MP4_BOX_VMHD: box = new SrsMp4VideoMeidaHeaderBox(); break; | ||
| 183 | + case SRS_MP4_BOX_SMHD: box = new SrsMp4SoundMeidaHeaderBox(); break; | ||
| 184 | + case SRS_MP4_BOX_DINF: box = new SrsMp4DataInformationBox(); break; | ||
| 185 | + case SRS_MP4_BOX_URL: box = new SrsMp4DataEntryUrlBox(); break; | ||
| 186 | + case SRS_MP4_BOX_URN: box = new SrsMp4DataEntryUrnBox(); break; | ||
| 187 | + case SRS_MP4_BOX_DREF: box = new SrsMp4DataReferenceBox(); break; | ||
| 188 | + case SRS_MP4_BOX_STBL: box = new SrsMp4SampleTableBox(); break; | ||
| 189 | + case SRS_MP4_BOX_STSD: box = new SrsMp4SampleDescriptionBox(); break; | ||
| 190 | + case SRS_MP4_BOX_STTS: box = new SrsMp4DecodingTime2SampleBox(); break; | ||
| 191 | + case SRS_MP4_BOX_CTTS: box = new SrsMp4CompositionTime2SampleBox(); break; | ||
| 192 | + case SRS_MP4_BOX_STSS: box = new SrsMp4SyncSampleBox(); break; | ||
| 193 | + case SRS_MP4_BOX_STSC: box = new SrsMp4Sample2ChunkBox(); break; | ||
| 194 | + case SRS_MP4_BOX_STCO: box = new SrsMp4ChunkOffsetBox(); break; | ||
| 195 | + case SRS_MP4_BOX_STSZ: box = new SrsMp4SampleSizeBox(); break; | ||
| 196 | + default: | ||
| 197 | + ret = ERROR_MP4_BOX_ILLEGAL_TYPE; | ||
| 198 | + srs_error("MP4 illegal box type=%d. ret=%d", type, ret); | ||
| 199 | + break; | ||
| 200 | + } | ||
| 201 | + | ||
| 202 | + if (box) { | ||
| 203 | + box->smallsize = smallsize; | ||
| 204 | + box->largesize = largesize; | ||
| 205 | + box->type = type; | ||
| 206 | + *ppbox = box; | ||
| 207 | + } | ||
| 208 | + | ||
| 209 | + return ret; | ||
| 210 | +} | ||
| 211 | + | ||
| 212 | +int SrsMp4Box::nb_bytes() | ||
| 213 | +{ | ||
| 214 | + int sz = nb_header(); | ||
| 215 | + | ||
| 216 | + vector<SrsMp4Box*>::iterator it; | ||
| 217 | + for (it = boxes.begin(); it != boxes.end(); ++it) { | ||
| 218 | + SrsMp4Box* box = *it; | ||
| 219 | + sz += box->nb_bytes(); | ||
| 220 | + } | ||
| 221 | + | ||
| 222 | + return sz; | ||
| 223 | +} | ||
| 224 | + | ||
| 225 | +int SrsMp4Box::encode(SrsBuffer* buf) | ||
| 226 | +{ | ||
| 227 | + int ret = ERROR_SUCCESS; | ||
| 228 | + | ||
| 229 | + if ((ret = encode_header(buf)) != ERROR_SUCCESS) { | ||
| 230 | + srs_error("MP4 encode box header failed. ret=%d", ret); | ||
| 231 | + return ret; | ||
| 232 | + } | ||
| 233 | + | ||
| 234 | + if ((ret = encode_boxes(buf)) != ERROR_SUCCESS) { | ||
| 235 | + srs_error("MP4 encode contained boxes failed. ret=%d", ret); | ||
| 236 | + return ret; | ||
| 237 | + } | ||
| 238 | + | ||
| 239 | + return ret; | ||
| 240 | +} | ||
| 241 | + | ||
| 242 | +int SrsMp4Box::decode(SrsBuffer* buf) | ||
| 243 | +{ | ||
| 244 | + int ret = ERROR_SUCCESS; | ||
| 245 | + | ||
| 246 | + start_pos = buf->pos(); | ||
| 247 | + | ||
| 248 | + if ((ret = decode_header(buf)) != ERROR_SUCCESS) { | ||
| 249 | + srs_error("MP4 decode box header failed. ret=%d", ret); | ||
| 250 | + return ret; | ||
| 251 | + } | ||
| 252 | + | ||
| 253 | + if ((ret = decode_boxes(buf)) != ERROR_SUCCESS) { | ||
| 254 | + srs_error("MP4 decode contained boxes failed. ret=%d", ret); | ||
| 255 | + return ret; | ||
| 256 | + } | ||
| 257 | + | ||
| 258 | + return ret; | ||
| 259 | +} | ||
| 260 | + | ||
| 261 | +int SrsMp4Box::encode_boxes(SrsBuffer* buf) | ||
| 262 | +{ | ||
| 263 | + int ret = ERROR_SUCCESS; | ||
| 264 | + | ||
| 265 | + vector<SrsMp4Box*>::iterator it; | ||
| 266 | + for (it = boxes.begin(); it != boxes.end(); ++it) { | ||
| 267 | + SrsMp4Box* box = *it; | ||
| 268 | + if ((ret = box->encode(buf)) != ERROR_SUCCESS) { | ||
| 269 | + srs_error("MP4 encode contained box failed. ret=%d", ret); | ||
| 270 | + return ret; | ||
| 271 | + } | ||
| 272 | + } | ||
| 273 | + | ||
| 274 | + return ret; | ||
| 275 | +} | ||
| 276 | + | ||
| 277 | +int SrsMp4Box::decode_boxes(SrsBuffer* buf) | ||
| 278 | +{ | ||
| 279 | + int ret = ERROR_SUCCESS; | ||
| 280 | + | ||
| 281 | + int left = left_space(buf); | ||
| 282 | + while (left > 0) { | ||
| 283 | + SrsMp4Box* box = NULL; | ||
| 284 | + if ((ret = discovery(buf, &box)) != ERROR_SUCCESS) { | ||
| 285 | + srs_error("MP4 discovery contained box failed. ret=%d", ret); | ||
| 286 | + return ret; | ||
| 287 | + } | ||
| 288 | + | ||
| 289 | + srs_assert(box); | ||
| 290 | + if ((ret = box->decode(buf)) != ERROR_SUCCESS) { | ||
| 291 | + srs_freep(box); | ||
| 292 | + srs_error("MP4 decode contained box failed. ret=%d", ret); | ||
| 293 | + return ret; | ||
| 294 | + } | ||
| 295 | + | ||
| 296 | + boxes.push_back(box); | ||
| 297 | + left -= box->sz(); | ||
| 298 | + } | ||
| 299 | + | ||
| 300 | + return ret; | ||
| 301 | +} | ||
| 302 | + | ||
| 303 | +int SrsMp4Box::nb_header() | ||
| 304 | +{ | ||
| 305 | + int size = 8; | ||
| 306 | + if (smallsize == SRS_MP4_USE_LARGE_SIZE) { | ||
| 307 | + size += 8; | ||
| 308 | + } | ||
| 309 | + | ||
| 310 | + if (type == SRS_MP4_BOX_UUID) { | ||
| 311 | + size += 16; | ||
| 312 | + } | ||
| 313 | + | ||
| 314 | + return size; | ||
| 315 | +} | ||
| 316 | + | ||
| 317 | +int SrsMp4Box::encode_header(SrsBuffer* buf) | ||
| 318 | +{ | ||
| 319 | + int ret = ERROR_SUCCESS; | ||
| 320 | + | ||
| 321 | + // Only support 31bits size. | ||
| 322 | + if (sz() > 0x7fffffff) { | ||
| 323 | + ret = ERROR_MP4_BOX_OVERFLOW; | ||
| 324 | + srs_error("MP4 box size overflow 31bits, size=%"PRId64". ret=%d", sz(), ret); | ||
| 325 | + return ret; | ||
| 326 | + } | ||
| 327 | + | ||
| 328 | + int size = nb_header(); | ||
| 329 | + if (!buf->require(size)) { | ||
| 330 | + ret = ERROR_MP4_BOX_REQUIRE_SPACE; | ||
| 331 | + srs_error("MP4 box require %d bytes space. ret=%d", size, ret); | ||
| 332 | + return ret; | ||
| 333 | + } | ||
| 334 | + | ||
| 335 | + buf->write_4bytes(smallsize); | ||
| 336 | + if (smallsize == SRS_MP4_USE_LARGE_SIZE) { | ||
| 337 | + buf->write_8bytes(largesize); | ||
| 338 | + } | ||
| 339 | + buf->write_4bytes(type); | ||
| 340 | + | ||
| 341 | + if (type == SRS_MP4_BOX_UUID) { | ||
| 342 | + buf->write_bytes((char*)usertype, 16); | ||
| 343 | + } | ||
| 344 | + | ||
| 345 | + return ret; | ||
| 346 | +} | ||
| 347 | + | ||
| 348 | +int SrsMp4Box::decode_header(SrsBuffer* buf) | ||
| 349 | +{ | ||
| 350 | + int ret = ERROR_SUCCESS; | ||
| 351 | + | ||
| 352 | + if (!buf->require(8)) { | ||
| 353 | + ret = ERROR_MP4_BOX_REQUIRE_SPACE; | ||
| 354 | + srs_error("MP4 box require 8 bytes space. ret=%d", ret); | ||
| 355 | + return ret; | ||
| 356 | + } | ||
| 357 | + smallsize = (uint32_t)buf->read_4bytes(); | ||
| 358 | + type = (uint32_t)buf->read_4bytes(); | ||
| 359 | + | ||
| 360 | + if (smallsize == SRS_MP4_EOF_SIZE) { | ||
| 361 | + srs_warn("MP4 box EOF."); | ||
| 362 | + return ret; | ||
| 363 | + } | ||
| 364 | + | ||
| 365 | + if (smallsize == SRS_MP4_USE_LARGE_SIZE) { | ||
| 366 | + if (!buf->require(8)) { | ||
| 367 | + ret = ERROR_MP4_BOX_REQUIRE_SPACE; | ||
| 368 | + srs_error("MP4 box require 8 bytes space. ret=%d", ret); | ||
| 369 | + return ret; | ||
| 370 | + } | ||
| 371 | + largesize = (uint64_t)buf->read_8bytes(); | ||
| 372 | + } | ||
| 373 | + | ||
| 374 | + // Only support 31bits size. | ||
| 375 | + if (sz() > 0x7fffffff) { | ||
| 376 | + ret = ERROR_MP4_BOX_OVERFLOW; | ||
| 377 | + srs_error("MP4 box size overflow 31bits, size=%"PRId64". ret=%d", sz(), ret); | ||
| 378 | + return ret; | ||
| 379 | + } | ||
| 380 | + | ||
| 381 | + if (type == SRS_MP4_BOX_UUID) { | ||
| 382 | + if (!buf->require(16)) { | ||
| 383 | + ret = ERROR_MP4_BOX_REQUIRE_SPACE; | ||
| 384 | + srs_error("MP4 box requires 16 bytes space. ret=%d", ret); | ||
| 385 | + return ret; | ||
| 386 | + } | ||
| 387 | + usertype = new uint8_t[16]; | ||
| 388 | + buf->read_bytes((char*)usertype, 16); | ||
| 389 | + } | ||
| 390 | + | ||
| 391 | + // The left required size, determined by the default version(0). | ||
| 392 | + int lrsz = nb_header() - SrsMp4Box::nb_header(); | ||
| 393 | + if (!buf->require(lrsz)) { | ||
| 394 | + ret = ERROR_MP4_BOX_REQUIRE_SPACE; | ||
| 395 | + srs_error("MP4 box requires %d bytes space. ret=%d", lrsz, ret); | ||
| 396 | + return ret; | ||
| 397 | + } | ||
| 398 | + | ||
| 399 | + return ret; | ||
| 39 | } | 400 | } |
| 40 | 401 | ||
| 41 | SrsMp4FullBox::SrsMp4FullBox() | 402 | SrsMp4FullBox::SrsMp4FullBox() |
| @@ -48,9 +409,58 @@ SrsMp4FullBox::~SrsMp4FullBox() | @@ -48,9 +409,58 @@ SrsMp4FullBox::~SrsMp4FullBox() | ||
| 48 | { | 409 | { |
| 49 | } | 410 | } |
| 50 | 411 | ||
| 412 | +int SrsMp4FullBox::nb_header() | ||
| 413 | +{ | ||
| 414 | + return SrsMp4Box::nb_header() + 1 + 3; | ||
| 415 | +} | ||
| 416 | + | ||
| 417 | +int SrsMp4FullBox::encode_header(SrsBuffer* buf) | ||
| 418 | +{ | ||
| 419 | + int ret = ERROR_SUCCESS; | ||
| 420 | + | ||
| 421 | + if ((ret = SrsMp4Box::encode_header(buf)) != ERROR_SUCCESS) { | ||
| 422 | + return ret; | ||
| 423 | + } | ||
| 424 | + | ||
| 425 | + buf->write_1bytes(version); | ||
| 426 | + buf->write_3bytes(flags); | ||
| 427 | + | ||
| 428 | + return ret; | ||
| 429 | +} | ||
| 430 | + | ||
| 431 | +int SrsMp4FullBox::decode_header(SrsBuffer* buf) | ||
| 432 | +{ | ||
| 433 | + int ret = ERROR_SUCCESS; | ||
| 434 | + | ||
| 435 | + if ((ret = SrsMp4Box::decode_header(buf)) != ERROR_SUCCESS) { | ||
| 436 | + return ret; | ||
| 437 | + } | ||
| 438 | + | ||
| 439 | + if (!buf->require(4)) { | ||
| 440 | + ret = ERROR_MP4_BOX_REQUIRE_SPACE; | ||
| 441 | + srs_error("MP4 full box requires 4 bytes space. ret=%d", ret); | ||
| 442 | + return ret; | ||
| 443 | + } | ||
| 444 | + | ||
| 445 | + flags = (uint32_t)buf->read_4bytes(); | ||
| 446 | + | ||
| 447 | + version = (uint8_t)((flags >> 24) & 0xff); | ||
| 448 | + flags &= 0x00ffffff; | ||
| 449 | + | ||
| 450 | + // The left required size, determined by the version. | ||
| 451 | + int lrsz = nb_header() - SrsMp4FullBox::nb_header(); | ||
| 452 | + if (!buf->require(lrsz)) { | ||
| 453 | + ret = ERROR_MP4_BOX_REQUIRE_SPACE; | ||
| 454 | + srs_error("MP4 full box requires %d bytes space. ret=%d", lrsz, ret); | ||
| 455 | + return ret; | ||
| 456 | + } | ||
| 457 | + | ||
| 458 | + return ret; | ||
| 459 | +} | ||
| 460 | + | ||
| 51 | SrsMp4FileTypeBox::SrsMp4FileTypeBox() | 461 | SrsMp4FileTypeBox::SrsMp4FileTypeBox() |
| 52 | { | 462 | { |
| 53 | - type = 0x66747970; // 'ftyp' | 463 | + type = SRS_MP4_BOX_FTYP; |
| 54 | nb_compatible_brands = 0; | 464 | nb_compatible_brands = 0; |
| 55 | compatible_brands = NULL; | 465 | compatible_brands = NULL; |
| 56 | major_brand = minor_version = 0; | 466 | major_brand = minor_version = 0; |
| @@ -61,9 +471,60 @@ SrsMp4FileTypeBox::~SrsMp4FileTypeBox() | @@ -61,9 +471,60 @@ SrsMp4FileTypeBox::~SrsMp4FileTypeBox() | ||
| 61 | srs_freepa(compatible_brands); | 471 | srs_freepa(compatible_brands); |
| 62 | } | 472 | } |
| 63 | 473 | ||
| 474 | +int SrsMp4FileTypeBox::nb_header() | ||
| 475 | +{ | ||
| 476 | + return SrsMp4Box::nb_header() + 8 + nb_compatible_brands * 4; | ||
| 477 | +} | ||
| 478 | + | ||
| 479 | +int SrsMp4FileTypeBox::encode_header(SrsBuffer* buf) | ||
| 480 | +{ | ||
| 481 | + int ret = ERROR_SUCCESS; | ||
| 482 | + | ||
| 483 | + if ((ret = SrsMp4Box::encode_header(buf)) != ERROR_SUCCESS) { | ||
| 484 | + return ret; | ||
| 485 | + } | ||
| 486 | + | ||
| 487 | + buf->write_4bytes(major_brand); | ||
| 488 | + buf->write_4bytes(minor_version); | ||
| 489 | + | ||
| 490 | + for (int i = 0; i < nb_compatible_brands; i++) { | ||
| 491 | + uint32_t& cb = compatible_brands[i]; | ||
| 492 | + buf->write_4bytes(cb); | ||
| 493 | + } | ||
| 494 | + | ||
| 495 | + return ret; | ||
| 496 | +} | ||
| 497 | + | ||
| 498 | +int SrsMp4FileTypeBox::decode_header(SrsBuffer* buf) | ||
| 499 | +{ | ||
| 500 | + int ret = ERROR_SUCCESS; | ||
| 501 | + | ||
| 502 | + if ((ret = SrsMp4Box::decode_header(buf)) != ERROR_SUCCESS) { | ||
| 503 | + return ret; | ||
| 504 | + } | ||
| 505 | + | ||
| 506 | + major_brand = buf->read_4bytes(); | ||
| 507 | + minor_version = buf->read_4bytes(); | ||
| 508 | + | ||
| 509 | + // Compatible brands to the end of the box. | ||
| 510 | + int left = left_space(buf); | ||
| 511 | + | ||
| 512 | + if (left > 0) { | ||
| 513 | + nb_compatible_brands = left / 4; | ||
| 514 | + compatible_brands = new uint32_t[nb_compatible_brands]; | ||
| 515 | + } | ||
| 516 | + | ||
| 517 | + for (int i = 0; left > 0; i++, left -= 4){ | ||
| 518 | + uint32_t cb = buf->read_4bytes(); | ||
| 519 | + compatible_brands[i] = cb; | ||
| 520 | + } | ||
| 521 | + | ||
| 522 | + return ret; | ||
| 523 | +} | ||
| 524 | + | ||
| 64 | SrsMp4MediaDataBox::SrsMp4MediaDataBox() | 525 | SrsMp4MediaDataBox::SrsMp4MediaDataBox() |
| 65 | { | 526 | { |
| 66 | - type = 0x6d646174; // 'mdat' | 527 | + type = SRS_MP4_BOX_MDAT; |
| 67 | data = NULL; | 528 | data = NULL; |
| 68 | nb_data = 0; | 529 | nb_data = 0; |
| 69 | } | 530 | } |
| @@ -73,18 +534,95 @@ SrsMp4MediaDataBox::~SrsMp4MediaDataBox() | @@ -73,18 +534,95 @@ SrsMp4MediaDataBox::~SrsMp4MediaDataBox() | ||
| 73 | srs_freepa(data); | 534 | srs_freepa(data); |
| 74 | } | 535 | } |
| 75 | 536 | ||
| 537 | +int SrsMp4MediaDataBox::nb_header() | ||
| 538 | +{ | ||
| 539 | + return SrsMp4Box::nb_header() + nb_data; | ||
| 540 | +} | ||
| 541 | + | ||
| 542 | +int SrsMp4MediaDataBox::encode_header(SrsBuffer* buf) | ||
| 543 | +{ | ||
| 544 | + int ret = ERROR_SUCCESS; | ||
| 545 | + | ||
| 546 | + if ((ret = SrsMp4Box::encode_header(buf)) != ERROR_SUCCESS) { | ||
| 547 | + return ret; | ||
| 548 | + } | ||
| 549 | + | ||
| 550 | + if (nb_data) { | ||
| 551 | + buf->write_bytes((char*)data, nb_data); | ||
| 552 | + } | ||
| 553 | + | ||
| 554 | + return ret; | ||
| 555 | +} | ||
| 556 | + | ||
| 557 | +int SrsMp4MediaDataBox::decode_header(SrsBuffer* buf) | ||
| 558 | +{ | ||
| 559 | + int ret = ERROR_SUCCESS; | ||
| 560 | + | ||
| 561 | + if ((ret = SrsMp4Box::decode_header(buf)) != ERROR_SUCCESS) { | ||
| 562 | + return ret; | ||
| 563 | + } | ||
| 564 | + | ||
| 565 | + int left = left_space(buf); | ||
| 566 | + if (left) { | ||
| 567 | + data = new uint8_t[left]; | ||
| 568 | + buf->read_bytes((char*)data, left); | ||
| 569 | + } | ||
| 570 | + | ||
| 571 | + return ret; | ||
| 572 | +} | ||
| 573 | + | ||
| 76 | SrsMp4FreeSpaceBox::SrsMp4FreeSpaceBox() | 574 | SrsMp4FreeSpaceBox::SrsMp4FreeSpaceBox() |
| 77 | { | 575 | { |
| 78 | - type = 0x66726565; // ‘free’ or ‘skip’ | 576 | + type = SRS_MP4_BOX_FREE; // 'free' or 'skip' |
| 577 | + data = NULL; | ||
| 578 | + nb_data = 0; | ||
| 79 | } | 579 | } |
| 80 | 580 | ||
| 81 | SrsMp4FreeSpaceBox::~SrsMp4FreeSpaceBox() | 581 | SrsMp4FreeSpaceBox::~SrsMp4FreeSpaceBox() |
| 82 | { | 582 | { |
| 583 | + srs_freepa(data); | ||
| 584 | +} | ||
| 585 | + | ||
| 586 | +int SrsMp4FreeSpaceBox::nb_header() | ||
| 587 | +{ | ||
| 588 | + return SrsMp4Box::nb_header() + nb_data; | ||
| 589 | +} | ||
| 590 | + | ||
| 591 | +int SrsMp4FreeSpaceBox::encode_header(SrsBuffer* buf) | ||
| 592 | +{ | ||
| 593 | + int ret = ERROR_SUCCESS; | ||
| 594 | + | ||
| 595 | + if ((ret = SrsMp4Box::encode_header(buf)) != ERROR_SUCCESS) { | ||
| 596 | + return ret; | ||
| 597 | + } | ||
| 598 | + | ||
| 599 | + if (nb_data) { | ||
| 600 | + buf->write_bytes((char*)data, nb_data); | ||
| 601 | + } | ||
| 602 | + | ||
| 603 | + return ret; | ||
| 604 | +} | ||
| 605 | + | ||
| 606 | +int SrsMp4FreeSpaceBox::decode_header(SrsBuffer* buf) | ||
| 607 | +{ | ||
| 608 | + int ret = ERROR_SUCCESS; | ||
| 609 | + | ||
| 610 | + if ((ret = SrsMp4Box::decode_header(buf)) != ERROR_SUCCESS) { | ||
| 611 | + return ret; | ||
| 612 | + } | ||
| 613 | + | ||
| 614 | + int left = left_space(buf); | ||
| 615 | + if (left) { | ||
| 616 | + data = new uint8_t[left]; | ||
| 617 | + buf->read_bytes((char*)data, left); | ||
| 618 | + } | ||
| 619 | + | ||
| 620 | + return ret; | ||
| 83 | } | 621 | } |
| 84 | 622 | ||
| 85 | SrsMp4MovieBox::SrsMp4MovieBox() | 623 | SrsMp4MovieBox::SrsMp4MovieBox() |
| 86 | { | 624 | { |
| 87 | - type = 0x6d6f6f76; // 'moov' | 625 | + type = SRS_MP4_BOX_MOOV; |
| 88 | } | 626 | } |
| 89 | 627 | ||
| 90 | SrsMp4MovieBox::~SrsMp4MovieBox() | 628 | SrsMp4MovieBox::~SrsMp4MovieBox() |
| @@ -93,7 +631,7 @@ SrsMp4MovieBox::~SrsMp4MovieBox() | @@ -93,7 +631,7 @@ SrsMp4MovieBox::~SrsMp4MovieBox() | ||
| 93 | 631 | ||
| 94 | SrsMp4MovieHeaderBox::SrsMp4MovieHeaderBox() | 632 | SrsMp4MovieHeaderBox::SrsMp4MovieHeaderBox() |
| 95 | { | 633 | { |
| 96 | - type = 0x6d766864; // 'mvhd' | 634 | + type = SRS_MP4_BOX_MVHD; |
| 97 | 635 | ||
| 98 | rate = 0x00010000; // typically 1.0 | 636 | rate = 0x00010000; // typically 1.0 |
| 99 | volume = 0x0100; // typically, full volume | 637 | volume = 0x0100; // typically, full volume |
| @@ -110,9 +648,92 @@ SrsMp4MovieHeaderBox::~SrsMp4MovieHeaderBox() | @@ -110,9 +648,92 @@ SrsMp4MovieHeaderBox::~SrsMp4MovieHeaderBox() | ||
| 110 | { | 648 | { |
| 111 | } | 649 | } |
| 112 | 650 | ||
| 651 | +int SrsMp4MovieHeaderBox::nb_header() | ||
| 652 | +{ | ||
| 653 | + int size = SrsMp4FullBox::nb_header(); | ||
| 654 | + | ||
| 655 | + if (version == 1) { | ||
| 656 | + size += 8+8+4+8; | ||
| 657 | + } else { | ||
| 658 | + size += 4+4+4+4; | ||
| 659 | + } | ||
| 660 | + | ||
| 661 | + size += 4+2+2+8+36+24+4; | ||
| 662 | + | ||
| 663 | + return size; | ||
| 664 | +} | ||
| 665 | + | ||
| 666 | +int SrsMp4MovieHeaderBox::encode_header(SrsBuffer* buf) | ||
| 667 | +{ | ||
| 668 | + int ret = ERROR_SUCCESS; | ||
| 669 | + | ||
| 670 | + if ((ret = SrsMp4FullBox::encode_header(buf)) != ERROR_SUCCESS) { | ||
| 671 | + return ret; | ||
| 672 | + } | ||
| 673 | + | ||
| 674 | + if (version == 1) { | ||
| 675 | + buf->write_8bytes(creation_time); | ||
| 676 | + buf->write_8bytes(modification_time); | ||
| 677 | + buf->write_4bytes(timescale); | ||
| 678 | + buf->write_8bytes(duration); | ||
| 679 | + } else { | ||
| 680 | + buf->write_4bytes((uint32_t)creation_time); | ||
| 681 | + buf->write_4bytes((uint32_t)modification_time); | ||
| 682 | + buf->write_4bytes(timescale); | ||
| 683 | + buf->write_4bytes((uint32_t)duration); | ||
| 684 | + } | ||
| 685 | + | ||
| 686 | + buf->write_4bytes(rate); | ||
| 687 | + buf->write_2bytes(volume); | ||
| 688 | + buf->write_2bytes(reserved0); | ||
| 689 | + buf->write_8bytes(reserved1); | ||
| 690 | + for (int i = 0; i < 9; i++) { | ||
| 691 | + buf->write_4bytes(matrix[i]); | ||
| 692 | + } | ||
| 693 | + for (int i = 0; i < 6; i++) { | ||
| 694 | + buf->write_4bytes(pre_defined[i]); | ||
| 695 | + } | ||
| 696 | + buf->write_4bytes(next_track_ID); | ||
| 697 | + | ||
| 698 | + return ret; | ||
| 699 | +} | ||
| 700 | + | ||
| 701 | +int SrsMp4MovieHeaderBox::decode_header(SrsBuffer* buf) | ||
| 702 | +{ | ||
| 703 | + int ret = ERROR_SUCCESS; | ||
| 704 | + | ||
| 705 | + if ((ret = SrsMp4FullBox::decode_header(buf)) != ERROR_SUCCESS) { | ||
| 706 | + return ret; | ||
| 707 | + } | ||
| 708 | + | ||
| 709 | + if (version == 1) { | ||
| 710 | + creation_time = buf->read_8bytes(); | ||
| 711 | + modification_time = buf->read_8bytes(); | ||
| 712 | + timescale = buf->read_4bytes(); | ||
| 713 | + duration = buf->read_8bytes(); | ||
| 714 | + } else { | ||
| 715 | + creation_time = buf->read_4bytes(); | ||
| 716 | + modification_time = buf->read_4bytes(); | ||
| 717 | + timescale = buf->read_4bytes(); | ||
| 718 | + duration = buf->read_4bytes(); | ||
| 719 | + } | ||
| 720 | + | ||
| 721 | + rate = buf->read_4bytes(); | ||
| 722 | + volume = buf->read_4bytes(); | ||
| 723 | + buf->skip(2); | ||
| 724 | + buf->skip(8); | ||
| 725 | + for (int i = 0; i < 9; i++) { | ||
| 726 | + matrix[i] = buf->read_4bytes(); | ||
| 727 | + } | ||
| 728 | + buf->skip(24); | ||
| 729 | + next_track_ID = buf->read_4bytes(); | ||
| 730 | + | ||
| 731 | + return ret; | ||
| 732 | +} | ||
| 733 | + | ||
| 113 | SrsMp4TrackBox::SrsMp4TrackBox() | 734 | SrsMp4TrackBox::SrsMp4TrackBox() |
| 114 | { | 735 | { |
| 115 | - type = 0x7472616b; // 'trak' | 736 | + type = SRS_MP4_BOX_TRAK; |
| 116 | } | 737 | } |
| 117 | 738 | ||
| 118 | SrsMp4TrackBox::~SrsMp4TrackBox() | 739 | SrsMp4TrackBox::~SrsMp4TrackBox() |
| @@ -121,13 +742,13 @@ SrsMp4TrackBox::~SrsMp4TrackBox() | @@ -121,13 +742,13 @@ SrsMp4TrackBox::~SrsMp4TrackBox() | ||
| 121 | 742 | ||
| 122 | SrsMp4TrackHeaderBox::SrsMp4TrackHeaderBox() | 743 | SrsMp4TrackHeaderBox::SrsMp4TrackHeaderBox() |
| 123 | { | 744 | { |
| 124 | - type = 0x746b6864; // 'tkhd' | 745 | + type = SRS_MP4_BOX_TKHD; |
| 125 | 746 | ||
| 126 | reserved0 = 0; | 747 | reserved0 = 0; |
| 127 | reserved1 = 0; | 748 | reserved1 = 0; |
| 128 | reserved2 = 0; | 749 | reserved2 = 0; |
| 129 | layer = alternate_group = 0; | 750 | layer = alternate_group = 0; |
| 130 | - volume = 0x0100; // if track_is_audio 0x0100 else 0 | 751 | + volume = 0; // if track_is_audio 0x0100 else 0 |
| 131 | 752 | ||
| 132 | int32_t v[] = {0x00010000, 0, 0, 0, 0x00010000, 0, 0, 0, 0x40000000}; | 753 | int32_t v[] = {0x00010000, 0, 0, 0, 0x00010000, 0, 0, 0, 0x40000000}; |
| 133 | memcpy(matrix, v, 36); | 754 | memcpy(matrix, v, 36); |
| @@ -137,214 +758,1012 @@ SrsMp4TrackHeaderBox::~SrsMp4TrackHeaderBox() | @@ -137,214 +758,1012 @@ SrsMp4TrackHeaderBox::~SrsMp4TrackHeaderBox() | ||
| 137 | { | 758 | { |
| 138 | } | 759 | } |
| 139 | 760 | ||
| 140 | -SrsMp4EditBox::SrsMp4EditBox() | 761 | +int SrsMp4TrackHeaderBox::nb_header() |
| 141 | { | 762 | { |
| 142 | - type = 0x65647473; // 'edts' | ||
| 143 | -} | 763 | + int size = SrsMp4FullBox::nb_header(); |
| 144 | 764 | ||
| 145 | -SrsMp4EditBox::~SrsMp4EditBox() | ||
| 146 | -{ | 765 | + if (version == 1) { |
| 766 | + size += 8+8+4+4+8; | ||
| 767 | + } else { | ||
| 768 | + size += 4+4+4+4+4; | ||
| 769 | + } | ||
| 770 | + | ||
| 771 | + size += 8+2+2+2+2+36+4+4; | ||
| 772 | + | ||
| 773 | + return size; | ||
| 147 | } | 774 | } |
| 148 | 775 | ||
| 149 | -SrsMp4ElstEntry::SrsMp4ElstEntry() | 776 | +int SrsMp4TrackHeaderBox::encode_header(SrsBuffer* buf) |
| 150 | { | 777 | { |
| 151 | - media_rate_fraction = 0; | 778 | + int ret = ERROR_SUCCESS; |
| 779 | + | ||
| 780 | + if ((ret = SrsMp4FullBox::encode_header(buf)) != ERROR_SUCCESS) { | ||
| 781 | + return ret; | ||
| 782 | + } | ||
| 783 | + | ||
| 784 | + if (version == 1) { | ||
| 785 | + buf->write_8bytes(creation_time); | ||
| 786 | + buf->write_8bytes(modification_time); | ||
| 787 | + buf->write_4bytes(track_ID); | ||
| 788 | + buf->write_4bytes(reserved0); | ||
| 789 | + buf->write_8bytes(duration); | ||
| 790 | + } else { | ||
| 791 | + buf->write_4bytes((uint32_t)creation_time); | ||
| 792 | + buf->write_4bytes((uint32_t)modification_time); | ||
| 793 | + buf->write_4bytes(track_ID); | ||
| 794 | + buf->write_4bytes(reserved0); | ||
| 795 | + buf->write_4bytes((uint32_t)duration); | ||
| 796 | + } | ||
| 797 | + | ||
| 798 | + buf->write_8bytes(reserved1); | ||
| 799 | + buf->write_2bytes(layer); | ||
| 800 | + buf->write_2bytes(alternate_group); | ||
| 801 | + buf->write_2bytes(volume); | ||
| 802 | + buf->write_2bytes(reserved2); | ||
| 803 | + for (int i = 0; i < 9; i++) { | ||
| 804 | + buf->write_4bytes(matrix[i]); | ||
| 805 | + } | ||
| 806 | + buf->write_4bytes(width); | ||
| 807 | + buf->write_4bytes(height); | ||
| 808 | + | ||
| 809 | + return ret; | ||
| 152 | } | 810 | } |
| 153 | 811 | ||
| 154 | -SrsMp4EditListBox::SrsMp4EditListBox() | 812 | +int SrsMp4TrackHeaderBox::decode_header(SrsBuffer* buf) |
| 155 | { | 813 | { |
| 156 | - type = 0x656c7374; // 'elst' | 814 | + int ret = ERROR_SUCCESS; |
| 157 | 815 | ||
| 158 | - entry_count = 0; | ||
| 159 | - entries = NULL; | 816 | + if ((ret = SrsMp4FullBox::decode_header(buf)) != ERROR_SUCCESS) { |
| 817 | + return ret; | ||
| 818 | + } | ||
| 819 | + | ||
| 820 | + if (version == 1) { | ||
| 821 | + creation_time = buf->read_8bytes(); | ||
| 822 | + modification_time = buf->read_8bytes(); | ||
| 823 | + track_ID = buf->read_4bytes(); | ||
| 824 | + buf->skip(4); | ||
| 825 | + duration = buf->read_8bytes(); | ||
| 826 | + } else { | ||
| 827 | + creation_time = buf->read_4bytes(); | ||
| 828 | + modification_time = buf->read_4bytes(); | ||
| 829 | + track_ID = buf->read_4bytes(); | ||
| 830 | + buf->skip(4); | ||
| 831 | + duration = buf->read_4bytes(); | ||
| 832 | + } | ||
| 833 | + | ||
| 834 | + buf->skip(8); | ||
| 835 | + layer = buf->read_2bytes(); | ||
| 836 | + alternate_group = buf->read_2bytes(); | ||
| 837 | + volume = buf->read_2bytes(); | ||
| 838 | + buf->skip(2); | ||
| 839 | + for (int i = 0; i < 9; i++) { | ||
| 840 | + matrix[i] = buf->read_4bytes(); | ||
| 841 | + } | ||
| 842 | + width = buf->read_4bytes(); | ||
| 843 | + height = buf->read_4bytes(); | ||
| 844 | + | ||
| 845 | + return ret; | ||
| 160 | } | 846 | } |
| 161 | 847 | ||
| 162 | -SrsMp4EditListBox::~SrsMp4EditListBox() | 848 | +SrsMp4EditBox::SrsMp4EditBox() |
| 163 | { | 849 | { |
| 164 | - srs_freepa(entries); | 850 | + type = SRS_MP4_BOX_EDTS; |
| 165 | } | 851 | } |
| 166 | 852 | ||
| 167 | -SrsMp4MediaBox::SrsMp4MediaBox() | 853 | +SrsMp4EditBox::~SrsMp4EditBox() |
| 168 | { | 854 | { |
| 169 | - type = 0x6d646961; // 'mdia' | ||
| 170 | } | 855 | } |
| 171 | 856 | ||
| 172 | -SrsMp4MediaBox::~SrsMp4MediaBox() | 857 | +SrsMp4ElstEntry::SrsMp4ElstEntry() |
| 173 | { | 858 | { |
| 859 | + media_rate_fraction = 0; | ||
| 174 | } | 860 | } |
| 175 | 861 | ||
| 176 | -SrsMp4MediaHeaderBox::SrsMp4MediaHeaderBox() | 862 | +int SrsMp4ElstEntry::nb_header(uint32_t version) |
| 177 | { | 863 | { |
| 178 | - type = 0x6d646864; // 'mdhd' | 864 | + int size = 0; |
| 179 | 865 | ||
| 180 | - pad = 0; | ||
| 181 | - pre_defined = 0; | 866 | + if (version == 1) { |
| 867 | + size += 8+8; | ||
| 868 | + } else { | ||
| 869 | + size += 4+4; | ||
| 870 | + } | ||
| 871 | + | ||
| 872 | + size += 2+2; | ||
| 873 | + | ||
| 874 | + return size; | ||
| 875 | +} | ||
| 876 | + | ||
| 877 | +int SrsMp4ElstEntry::encode_header(SrsBuffer* buf, uint32_t version) | ||
| 878 | +{ | ||
| 879 | + if (version == 1) { | ||
| 880 | + buf->write_8bytes(segment_duration); | ||
| 881 | + buf->write_8bytes(media_time); | ||
| 882 | + } else { | ||
| 883 | + buf->write_4bytes((uint32_t)segment_duration); | ||
| 884 | + buf->write_4bytes((int32_t)media_time); | ||
| 885 | + } | ||
| 886 | + | ||
| 887 | + buf->write_2bytes(media_rate_integer); | ||
| 888 | + buf->write_2bytes(media_rate_fraction); | ||
| 889 | + | ||
| 890 | + return ERROR_SUCCESS; | ||
| 891 | +} | ||
| 892 | + | ||
| 893 | +int SrsMp4ElstEntry::decode_header(SrsBuffer* buf, uint32_t version) | ||
| 894 | +{ | ||
| 895 | + if (version == 1) { | ||
| 896 | + segment_duration = buf->read_8bytes(); | ||
| 897 | + media_time = buf->read_8bytes(); | ||
| 898 | + } else { | ||
| 899 | + segment_duration = buf->read_4bytes(); | ||
| 900 | + media_time = buf->read_4bytes(); | ||
| 901 | + } | ||
| 902 | + | ||
| 903 | + media_rate_integer = buf->read_2bytes(); | ||
| 904 | + media_rate_fraction = buf->read_2bytes(); | ||
| 905 | + | ||
| 906 | + return ERROR_SUCCESS; | ||
| 907 | +} | ||
| 908 | + | ||
| 909 | +SrsMp4EditListBox::SrsMp4EditListBox() | ||
| 910 | +{ | ||
| 911 | + type = SRS_MP4_BOX_ELST; | ||
| 912 | + | ||
| 913 | + entry_count = 0; | ||
| 914 | + entries = NULL; | ||
| 915 | +} | ||
| 916 | + | ||
| 917 | +SrsMp4EditListBox::~SrsMp4EditListBox() | ||
| 918 | +{ | ||
| 919 | + srs_freepa(entries); | ||
| 920 | +} | ||
| 921 | + | ||
| 922 | +int SrsMp4EditListBox::nb_header() | ||
| 923 | +{ | ||
| 924 | + int size = SrsMp4FullBox::nb_header(); | ||
| 925 | + | ||
| 926 | + for (uint32_t i = 0; i < entry_count; i++) { | ||
| 927 | + SrsMp4ElstEntry& entry = entries[i]; | ||
| 928 | + size += entry.nb_header(version); | ||
| 929 | + } | ||
| 930 | + | ||
| 931 | + return size; | ||
| 932 | +} | ||
| 933 | + | ||
| 934 | +int SrsMp4EditListBox::encode_header(SrsBuffer* buf) | ||
| 935 | +{ | ||
| 936 | + int ret = ERROR_SUCCESS; | ||
| 937 | + | ||
| 938 | + if ((ret = SrsMp4FullBox::encode_header(buf)) != ERROR_SUCCESS) { | ||
| 939 | + return ret; | ||
| 940 | + } | ||
| 941 | + | ||
| 942 | + for (uint32_t i = 0; i < entry_count; i++) { | ||
| 943 | + SrsMp4ElstEntry& entry = entries[i]; | ||
| 944 | + if ((ret = entry.encode_header(buf, version)) != ERROR_SUCCESS) { | ||
| 945 | + return ret; | ||
| 946 | + } | ||
| 947 | + } | ||
| 948 | + | ||
| 949 | + return ret; | ||
| 950 | +} | ||
| 951 | + | ||
| 952 | +int SrsMp4EditListBox::decode_header(SrsBuffer* buf) | ||
| 953 | +{ | ||
| 954 | + int ret = ERROR_SUCCESS; | ||
| 955 | + | ||
| 956 | + if ((ret = SrsMp4FullBox::decode_header(buf)) != ERROR_SUCCESS) { | ||
| 957 | + return ret; | ||
| 958 | + } | ||
| 959 | + | ||
| 960 | + int left = left_space(buf); | ||
| 961 | + entry_count = left / SrsMp4ElstEntry().nb_header(version); | ||
| 962 | + if (entry_count > 0) { | ||
| 963 | + entries = new SrsMp4ElstEntry[entry_count]; | ||
| 964 | + } | ||
| 965 | + for (int i = 0; i < entry_count; i++) { | ||
| 966 | + SrsMp4ElstEntry& entry = entries[i]; | ||
| 967 | + if ((ret = entry.decode_header(buf, version)) != ERROR_SUCCESS) { | ||
| 968 | + return ret; | ||
| 969 | + } | ||
| 970 | + } | ||
| 971 | + | ||
| 972 | + return ret; | ||
| 973 | +} | ||
| 974 | + | ||
| 975 | +SrsMp4MediaBox::SrsMp4MediaBox() | ||
| 976 | +{ | ||
| 977 | + type = SRS_MP4_BOX_MDIA; | ||
| 978 | +} | ||
| 979 | + | ||
| 980 | +SrsMp4MediaBox::~SrsMp4MediaBox() | ||
| 981 | +{ | ||
| 982 | +} | ||
| 983 | + | ||
| 984 | +SrsMp4MediaHeaderBox::SrsMp4MediaHeaderBox() | ||
| 985 | +{ | ||
| 986 | + type = SRS_MP4_BOX_MDHD; | ||
| 987 | + language = 0; | ||
| 988 | + pre_defined = 0; | ||
| 182 | } | 989 | } |
| 183 | 990 | ||
| 184 | SrsMp4MediaHeaderBox::~SrsMp4MediaHeaderBox() | 991 | SrsMp4MediaHeaderBox::~SrsMp4MediaHeaderBox() |
| 185 | { | 992 | { |
| 186 | } | 993 | } |
| 187 | 994 | ||
| 995 | +uint8_t SrsMp4MediaHeaderBox::language0() | ||
| 996 | +{ | ||
| 997 | + return (language >> 10) & 0x1f; | ||
| 998 | +} | ||
| 999 | + | ||
| 1000 | +void SrsMp4MediaHeaderBox::set_language0(uint8_t v) | ||
| 1001 | +{ | ||
| 1002 | + language |= uint16_t(v & 0x1f) << 10; | ||
| 1003 | +} | ||
| 1004 | + | ||
| 1005 | +uint8_t SrsMp4MediaHeaderBox::language1() | ||
| 1006 | +{ | ||
| 1007 | + return (language >> 5) & 0x1f; | ||
| 1008 | +} | ||
| 1009 | + | ||
| 1010 | +void SrsMp4MediaHeaderBox::set_language1(uint8_t v) | ||
| 1011 | +{ | ||
| 1012 | + language |= uint16_t(v & 0x1f) << 5; | ||
| 1013 | +} | ||
| 1014 | + | ||
| 1015 | +uint8_t SrsMp4MediaHeaderBox::language2() | ||
| 1016 | +{ | ||
| 1017 | + return language & 0x1f; | ||
| 1018 | +} | ||
| 1019 | + | ||
| 1020 | +void SrsMp4MediaHeaderBox::set_language2(uint8_t v) | ||
| 1021 | +{ | ||
| 1022 | + language |= uint16_t(v & 0x1f); | ||
| 1023 | +} | ||
| 1024 | + | ||
| 1025 | +int SrsMp4MediaHeaderBox::nb_header() | ||
| 1026 | +{ | ||
| 1027 | + int size = SrsMp4FullBox::nb_header(); | ||
| 1028 | + | ||
| 1029 | + if (version == 1) { | ||
| 1030 | + size += 8+8+4+8; | ||
| 1031 | + } else { | ||
| 1032 | + size += 4+4+4+4; | ||
| 1033 | + } | ||
| 1034 | + | ||
| 1035 | + size += 2+2; | ||
| 1036 | + | ||
| 1037 | + return size; | ||
| 1038 | +} | ||
| 1039 | + | ||
| 1040 | +int SrsMp4MediaHeaderBox::encode_header(SrsBuffer* buf) | ||
| 1041 | +{ | ||
| 1042 | + int ret = ERROR_SUCCESS; | ||
| 1043 | + | ||
| 1044 | + if ((ret = SrsMp4FullBox::encode_header(buf)) != ERROR_SUCCESS) { | ||
| 1045 | + return ret; | ||
| 1046 | + } | ||
| 1047 | + | ||
| 1048 | + if (version == 1) { | ||
| 1049 | + buf->write_8bytes(creation_time); | ||
| 1050 | + buf->write_8bytes(modification_time); | ||
| 1051 | + buf->write_4bytes(timescale); | ||
| 1052 | + buf->write_8bytes(duration); | ||
| 1053 | + } else { | ||
| 1054 | + buf->write_4bytes((uint32_t)creation_time); | ||
| 1055 | + buf->write_4bytes((uint32_t)modification_time); | ||
| 1056 | + buf->write_4bytes(timescale); | ||
| 1057 | + buf->write_4bytes((uint32_t)duration); | ||
| 1058 | + } | ||
| 1059 | + | ||
| 1060 | + buf->write_2bytes(language); | ||
| 1061 | + buf->write_2bytes(pre_defined); | ||
| 1062 | + | ||
| 1063 | + return ret; | ||
| 1064 | +} | ||
| 1065 | + | ||
| 1066 | +int SrsMp4MediaHeaderBox::decode_header(SrsBuffer* buf) | ||
| 1067 | +{ | ||
| 1068 | + int ret = ERROR_SUCCESS; | ||
| 1069 | + | ||
| 1070 | + if ((ret = SrsMp4FullBox::decode_header(buf)) != ERROR_SUCCESS) { | ||
| 1071 | + return ret; | ||
| 1072 | + } | ||
| 1073 | + | ||
| 1074 | + if (version == 1) { | ||
| 1075 | + creation_time = buf->read_8bytes(); | ||
| 1076 | + modification_time = buf->read_8bytes(); | ||
| 1077 | + timescale = buf->read_4bytes(); | ||
| 1078 | + duration = buf->read_8bytes(); | ||
| 1079 | + } else { | ||
| 1080 | + creation_time = buf->read_4bytes(); | ||
| 1081 | + modification_time = buf->read_4bytes(); | ||
| 1082 | + timescale = buf->read_4bytes(); | ||
| 1083 | + duration = buf->read_4bytes(); | ||
| 1084 | + } | ||
| 1085 | + | ||
| 1086 | + language = buf->read_2bytes(); | ||
| 1087 | + buf->skip(2); | ||
| 1088 | + | ||
| 1089 | + return ret; | ||
| 1090 | +} | ||
| 1091 | + | ||
| 188 | SrsMp4HandlerReferenceBox::SrsMp4HandlerReferenceBox() | 1092 | SrsMp4HandlerReferenceBox::SrsMp4HandlerReferenceBox() |
| 189 | { | 1093 | { |
| 190 | - type = 0x68646c72; // 'hdlr' | 1094 | + type = SRS_MP4_BOX_HDLR; |
| 191 | 1095 | ||
| 192 | pre_defined = 0; | 1096 | pre_defined = 0; |
| 193 | memset(reserved, 0, 12); | 1097 | memset(reserved, 0, 12); |
| 194 | } | 1098 | } |
| 195 | 1099 | ||
| 196 | -SrsMp4HandlerReferenceBox::~SrsMp4HandlerReferenceBox() | 1100 | +SrsMp4HandlerReferenceBox::~SrsMp4HandlerReferenceBox() |
| 1101 | +{ | ||
| 1102 | +} | ||
| 1103 | + | ||
| 1104 | +int SrsMp4HandlerReferenceBox::nb_header() | ||
| 1105 | +{ | ||
| 1106 | + return SrsMp4FullBox::nb_header()+4+4+12+srs_mp4_string_length(name); | ||
| 1107 | +} | ||
| 1108 | + | ||
| 1109 | +int SrsMp4HandlerReferenceBox::encode_header(SrsBuffer* buf) | ||
| 1110 | +{ | ||
| 1111 | + int ret = ERROR_SUCCESS; | ||
| 1112 | + | ||
| 1113 | + if ((ret = SrsMp4FullBox::encode_header(buf)) != ERROR_SUCCESS) { | ||
| 1114 | + return ret; | ||
| 1115 | + } | ||
| 1116 | + | ||
| 1117 | + buf->write_4bytes(pre_defined); | ||
| 1118 | + buf->write_4bytes(handler_type); | ||
| 1119 | + buf->write_4bytes(reserved[0]); | ||
| 1120 | + buf->write_4bytes(reserved[1]); | ||
| 1121 | + buf->write_4bytes(reserved[2]); | ||
| 1122 | + srs_mp4_string_write(buf, name); | ||
| 1123 | + | ||
| 1124 | + return ret; | ||
| 1125 | +} | ||
| 1126 | + | ||
| 1127 | +int SrsMp4HandlerReferenceBox::decode_header(SrsBuffer* buf) | ||
| 1128 | +{ | ||
| 1129 | + int ret = ERROR_SUCCESS; | ||
| 1130 | + | ||
| 1131 | + if ((ret = SrsMp4FullBox::decode_header(buf)) != ERROR_SUCCESS) { | ||
| 1132 | + return ret; | ||
| 1133 | + } | ||
| 1134 | + | ||
| 1135 | + buf->skip(4); | ||
| 1136 | + handler_type = buf->read_4bytes(); | ||
| 1137 | + buf->skip(12); | ||
| 1138 | + | ||
| 1139 | + if ((ret = srs_mp4_string_read(buf, name, left_space(buf))) != ERROR_SUCCESS) { | ||
| 1140 | + srs_error("MP4 hdlr read string failed. ret=%d", ret); | ||
| 1141 | + return ret; | ||
| 1142 | + } | ||
| 1143 | + | ||
| 1144 | + return ret; | ||
| 1145 | +} | ||
| 1146 | + | ||
| 1147 | +SrsMp4MediaInformationBox::SrsMp4MediaInformationBox() | ||
| 1148 | +{ | ||
| 1149 | + type = SRS_MP4_BOX_MINF; | ||
| 1150 | +} | ||
| 1151 | + | ||
| 1152 | +SrsMp4MediaInformationBox::~SrsMp4MediaInformationBox() | ||
| 1153 | +{ | ||
| 1154 | +} | ||
| 1155 | + | ||
| 1156 | +SrsMp4VideoMeidaHeaderBox::SrsMp4VideoMeidaHeaderBox() | ||
| 1157 | +{ | ||
| 1158 | + type = SRS_MP4_BOX_VMHD; | ||
| 1159 | + version = 0; | ||
| 1160 | + flags = 1; | ||
| 1161 | + | ||
| 1162 | + graphicsmode = 0; | ||
| 1163 | + memset(opcolor, 0, 6); | ||
| 1164 | +} | ||
| 1165 | + | ||
| 1166 | +SrsMp4VideoMeidaHeaderBox::~SrsMp4VideoMeidaHeaderBox() | ||
| 1167 | +{ | ||
| 1168 | +} | ||
| 1169 | + | ||
| 1170 | +int SrsMp4VideoMeidaHeaderBox::nb_header() | ||
| 1171 | +{ | ||
| 1172 | + return SrsMp4FullBox::nb_header()+2+6; | ||
| 1173 | +} | ||
| 1174 | + | ||
| 1175 | +int SrsMp4VideoMeidaHeaderBox::encode_header(SrsBuffer* buf) | ||
| 1176 | +{ | ||
| 1177 | + int ret = ERROR_SUCCESS; | ||
| 1178 | + | ||
| 1179 | + if ((ret = SrsMp4FullBox::encode_header(buf)) != ERROR_SUCCESS) { | ||
| 1180 | + return ret; | ||
| 1181 | + } | ||
| 1182 | + | ||
| 1183 | + buf->write_2bytes(graphicsmode); | ||
| 1184 | + buf->write_2bytes(opcolor[0]); | ||
| 1185 | + buf->write_2bytes(opcolor[1]); | ||
| 1186 | + buf->write_2bytes(opcolor[2]); | ||
| 1187 | + | ||
| 1188 | + return ret; | ||
| 1189 | +} | ||
| 1190 | + | ||
| 1191 | +int SrsMp4VideoMeidaHeaderBox::decode_header(SrsBuffer* buf) | ||
| 1192 | +{ | ||
| 1193 | + int ret = ERROR_SUCCESS; | ||
| 1194 | + | ||
| 1195 | + if ((ret = SrsMp4FullBox::decode_header(buf)) != ERROR_SUCCESS) { | ||
| 1196 | + return ret; | ||
| 1197 | + } | ||
| 1198 | + | ||
| 1199 | + graphicsmode = buf->read_2bytes(); | ||
| 1200 | + opcolor[0] = buf->read_2bytes(); | ||
| 1201 | + opcolor[1] = buf->read_2bytes(); | ||
| 1202 | + opcolor[2] = buf->read_2bytes(); | ||
| 1203 | + | ||
| 1204 | + return ret; | ||
| 1205 | +} | ||
| 1206 | + | ||
| 1207 | +SrsMp4SoundMeidaHeaderBox::SrsMp4SoundMeidaHeaderBox() | ||
| 1208 | +{ | ||
| 1209 | + type = SRS_MP4_BOX_SMHD; | ||
| 1210 | + | ||
| 1211 | + reserved = balance = 0; | ||
| 1212 | +} | ||
| 1213 | + | ||
| 1214 | +SrsMp4SoundMeidaHeaderBox::~SrsMp4SoundMeidaHeaderBox() | ||
| 1215 | +{ | ||
| 1216 | +} | ||
| 1217 | + | ||
| 1218 | +int SrsMp4SoundMeidaHeaderBox::nb_header() | ||
| 1219 | +{ | ||
| 1220 | + return SrsMp4FullBox::nb_header()+2+2; | ||
| 1221 | +} | ||
| 1222 | + | ||
| 1223 | +int SrsMp4SoundMeidaHeaderBox::encode_header(SrsBuffer* buf) | ||
| 1224 | +{ | ||
| 1225 | + int ret = ERROR_SUCCESS; | ||
| 1226 | + | ||
| 1227 | + if ((ret = SrsMp4FullBox::encode_header(buf)) != ERROR_SUCCESS) { | ||
| 1228 | + return ret; | ||
| 1229 | + } | ||
| 1230 | + | ||
| 1231 | + buf->write_2bytes(balance); | ||
| 1232 | + buf->write_2bytes(reserved); | ||
| 1233 | + | ||
| 1234 | + return ret; | ||
| 1235 | +} | ||
| 1236 | + | ||
| 1237 | +int SrsMp4SoundMeidaHeaderBox::decode_header(SrsBuffer* buf) | ||
| 1238 | +{ | ||
| 1239 | + int ret = ERROR_SUCCESS; | ||
| 1240 | + | ||
| 1241 | + if ((ret = SrsMp4FullBox::decode_header(buf)) != ERROR_SUCCESS) { | ||
| 1242 | + return ret; | ||
| 1243 | + } | ||
| 1244 | + | ||
| 1245 | + balance = buf->read_2bytes(); | ||
| 1246 | + buf->skip(2); | ||
| 1247 | + | ||
| 1248 | + return ret; | ||
| 1249 | +} | ||
| 1250 | + | ||
| 1251 | +SrsMp4DataInformationBox::SrsMp4DataInformationBox() | ||
| 1252 | +{ | ||
| 1253 | + type = SRS_MP4_BOX_DINF; | ||
| 1254 | +} | ||
| 1255 | + | ||
| 1256 | +SrsMp4DataInformationBox::~SrsMp4DataInformationBox() | ||
| 1257 | +{ | ||
| 1258 | +} | ||
| 1259 | + | ||
| 1260 | +SrsMp4DataEntryBox::SrsMp4DataEntryBox() | ||
| 1261 | +{ | ||
| 1262 | +} | ||
| 1263 | + | ||
| 1264 | +SrsMp4DataEntryBox::~SrsMp4DataEntryBox() | ||
| 1265 | +{ | ||
| 1266 | +} | ||
| 1267 | + | ||
| 1268 | +int SrsMp4DataEntryBox::nb_header() | ||
| 1269 | +{ | ||
| 1270 | + return SrsMp4FullBox::nb_header()+srs_mp4_string_length(location); | ||
| 1271 | +} | ||
| 1272 | + | ||
| 1273 | +int SrsMp4DataEntryBox::encode_header(SrsBuffer* buf) | ||
| 1274 | +{ | ||
| 1275 | + int ret = ERROR_SUCCESS; | ||
| 1276 | + | ||
| 1277 | + if ((ret = SrsMp4FullBox::encode_header(buf)) != ERROR_SUCCESS) { | ||
| 1278 | + return ret; | ||
| 1279 | + } | ||
| 1280 | + | ||
| 1281 | + srs_mp4_string_write(buf, location); | ||
| 1282 | + | ||
| 1283 | + return ret; | ||
| 1284 | +} | ||
| 1285 | + | ||
| 1286 | +int SrsMp4DataEntryBox::decode_header(SrsBuffer* buf) | ||
| 1287 | +{ | ||
| 1288 | + int ret = ERROR_SUCCESS; | ||
| 1289 | + | ||
| 1290 | + if ((ret = SrsMp4FullBox::decode_header(buf)) != ERROR_SUCCESS) { | ||
| 1291 | + return ret; | ||
| 1292 | + } | ||
| 1293 | + | ||
| 1294 | + if ((ret = srs_mp4_string_read(buf, location, left_space(buf))) != ERROR_SUCCESS) { | ||
| 1295 | + srs_error("MP4 urx read string failed. ret=%d", ret); | ||
| 1296 | + return ret; | ||
| 1297 | + } | ||
| 1298 | + | ||
| 1299 | + return ret; | ||
| 1300 | +} | ||
| 1301 | + | ||
| 1302 | +SrsMp4DataEntryUrlBox::SrsMp4DataEntryUrlBox() | ||
| 1303 | +{ | ||
| 1304 | + type = SRS_MP4_BOX_URL; | ||
| 1305 | +} | ||
| 1306 | + | ||
| 1307 | +SrsMp4DataEntryUrlBox::~SrsMp4DataEntryUrlBox() | ||
| 1308 | +{ | ||
| 1309 | +} | ||
| 1310 | + | ||
| 1311 | +SrsMp4DataEntryUrnBox::SrsMp4DataEntryUrnBox() | ||
| 1312 | +{ | ||
| 1313 | + type = SRS_MP4_BOX_URN; | ||
| 1314 | +} | ||
| 1315 | + | ||
| 1316 | +SrsMp4DataEntryUrnBox::~SrsMp4DataEntryUrnBox() | ||
| 1317 | +{ | ||
| 1318 | +} | ||
| 1319 | + | ||
| 1320 | +int SrsMp4DataEntryUrnBox::nb_header() | ||
| 1321 | +{ | ||
| 1322 | + return SrsMp4DataEntryBox::nb_header()+srs_mp4_string_length(name); | ||
| 1323 | +} | ||
| 1324 | + | ||
| 1325 | +int SrsMp4DataEntryUrnBox::encode_header(SrsBuffer* buf) | ||
| 1326 | +{ | ||
| 1327 | + int ret = ERROR_SUCCESS; | ||
| 1328 | + | ||
| 1329 | + if ((ret = SrsMp4DataEntryBox::encode_header(buf)) != ERROR_SUCCESS) { | ||
| 1330 | + return ret; | ||
| 1331 | + } | ||
| 1332 | + | ||
| 1333 | + srs_mp4_string_write(buf, name); | ||
| 1334 | + | ||
| 1335 | + return ret; | ||
| 1336 | +} | ||
| 1337 | + | ||
| 1338 | +int SrsMp4DataEntryUrnBox::decode_header(SrsBuffer* buf) | ||
| 1339 | +{ | ||
| 1340 | + int ret = ERROR_SUCCESS; | ||
| 1341 | + | ||
| 1342 | + if ((ret = SrsMp4DataEntryBox::decode_header(buf)) != ERROR_SUCCESS) { | ||
| 1343 | + return ret; | ||
| 1344 | + } | ||
| 1345 | + | ||
| 1346 | + if ((ret = srs_mp4_string_read(buf, name, left_space(buf))) != ERROR_SUCCESS) { | ||
| 1347 | + srs_error("MP4 urn read string failed. ret=%d", ret); | ||
| 1348 | + return ret; | ||
| 1349 | + } | ||
| 1350 | + | ||
| 1351 | + return ret; | ||
| 1352 | +} | ||
| 1353 | + | ||
| 1354 | +SrsMp4DataReferenceBox::SrsMp4DataReferenceBox() | ||
| 1355 | +{ | ||
| 1356 | + type = SRS_MP4_BOX_DREF; | ||
| 1357 | +} | ||
| 1358 | + | ||
| 1359 | +SrsMp4DataReferenceBox::~SrsMp4DataReferenceBox() | ||
| 1360 | +{ | ||
| 1361 | + vector<SrsMp4DataEntryBox*>::iterator it; | ||
| 1362 | + for (it = entries.begin(); it != entries.end(); ++it) { | ||
| 1363 | + SrsMp4DataEntryBox* entry = *it; | ||
| 1364 | + srs_freep(entry); | ||
| 1365 | + } | ||
| 1366 | + entries.clear(); | ||
| 1367 | +} | ||
| 1368 | + | ||
| 1369 | +uint32_t SrsMp4DataReferenceBox::entry_count() | ||
| 1370 | +{ | ||
| 1371 | + return (uint32_t)entries.size(); | ||
| 1372 | +} | ||
| 1373 | + | ||
| 1374 | +SrsMp4DataEntryBox* SrsMp4DataReferenceBox::entry_at(int index) | ||
| 1375 | +{ | ||
| 1376 | + return entries.at(index); | ||
| 1377 | +} | ||
| 1378 | + | ||
| 1379 | +int SrsMp4DataReferenceBox::nb_header() | ||
| 1380 | +{ | ||
| 1381 | + int size = SrsMp4FullBox::nb_header(); | ||
| 1382 | + | ||
| 1383 | + size += 4; | ||
| 1384 | + | ||
| 1385 | + vector<SrsMp4DataEntryBox*>::iterator it; | ||
| 1386 | + for (it = entries.begin(); it != entries.end(); ++it) { | ||
| 1387 | + SrsMp4DataEntryBox* entry = *it; | ||
| 1388 | + size += entry->nb_bytes(); | ||
| 1389 | + } | ||
| 1390 | + | ||
| 1391 | + return size; | ||
| 1392 | +} | ||
| 1393 | + | ||
| 1394 | +int SrsMp4DataReferenceBox::encode_header(SrsBuffer* buf) | ||
| 1395 | +{ | ||
| 1396 | + int ret = ERROR_SUCCESS; | ||
| 1397 | + | ||
| 1398 | + if ((ret = SrsMp4FullBox::encode_header(buf)) != ERROR_SUCCESS) { | ||
| 1399 | + return ret; | ||
| 1400 | + } | ||
| 1401 | + | ||
| 1402 | + buf->write_4bytes((int32_t)entries.size()); | ||
| 1403 | + | ||
| 1404 | + vector<SrsMp4DataEntryBox*>::iterator it; | ||
| 1405 | + for (it = entries.begin(); it != entries.end(); ++it) { | ||
| 1406 | + SrsMp4DataEntryBox* entry = *it; | ||
| 1407 | + if ((ret = entry->encode(buf)) != ERROR_SUCCESS) { | ||
| 1408 | + return ret; | ||
| 1409 | + } | ||
| 1410 | + } | ||
| 1411 | + | ||
| 1412 | + return ret; | ||
| 1413 | +} | ||
| 1414 | + | ||
| 1415 | +int SrsMp4DataReferenceBox::decode_header(SrsBuffer* buf) | ||
| 1416 | +{ | ||
| 1417 | + int ret = ERROR_SUCCESS; | ||
| 1418 | + | ||
| 1419 | + if ((ret = SrsMp4FullBox::decode_header(buf)) != ERROR_SUCCESS) { | ||
| 1420 | + return ret; | ||
| 1421 | + } | ||
| 1422 | + | ||
| 1423 | + int left = left_space(buf); | ||
| 1424 | + while (left > 0) { | ||
| 1425 | + SrsMp4Box* box = NULL; | ||
| 1426 | + if ((ret = SrsMp4Box::discovery(buf, &box)) != ERROR_SUCCESS) { | ||
| 1427 | + return ret; | ||
| 1428 | + } | ||
| 1429 | + | ||
| 1430 | + int pos = buf->pos(); | ||
| 1431 | + if ((ret = box->decode(buf)) != ERROR_SUCCESS) { | ||
| 1432 | + return ret; | ||
| 1433 | + } | ||
| 1434 | + left -= buf->pos() - pos; | ||
| 1435 | + | ||
| 1436 | + SrsMp4FullBox* fbox = dynamic_cast<SrsMp4FullBox*>(box); | ||
| 1437 | + if (fbox) { | ||
| 1438 | + fbox->version = version; | ||
| 1439 | + fbox->flags = flags; | ||
| 1440 | + } | ||
| 1441 | + | ||
| 1442 | + if (box->type == SRS_MP4_BOX_URL) { | ||
| 1443 | + entries.push_back(dynamic_cast<SrsMp4DataEntryUrlBox*>(box)); | ||
| 1444 | + } else if (box->type == SRS_MP4_BOX_URN) { | ||
| 1445 | + entries.push_back(dynamic_cast<SrsMp4DataEntryUrnBox*>(box)); | ||
| 1446 | + } else { | ||
| 1447 | + srs_freep(box); | ||
| 1448 | + } | ||
| 1449 | + } | ||
| 1450 | + | ||
| 1451 | + return ret; | ||
| 1452 | +} | ||
| 1453 | + | ||
| 1454 | +SrsMp4SampleTableBox::SrsMp4SampleTableBox() | ||
| 1455 | +{ | ||
| 1456 | + type = SRS_MP4_BOX_STBL; | ||
| 1457 | +} | ||
| 1458 | + | ||
| 1459 | +SrsMp4SampleTableBox::~SrsMp4SampleTableBox() | ||
| 1460 | +{ | ||
| 1461 | +} | ||
| 1462 | + | ||
| 1463 | +SrsMp4SampleEntry::SrsMp4SampleEntry() | ||
| 1464 | +{ | ||
| 1465 | + memset(reserved, 0, 6); | ||
| 1466 | +} | ||
| 1467 | + | ||
| 1468 | +SrsMp4SampleEntry::~SrsMp4SampleEntry() | ||
| 197 | { | 1469 | { |
| 198 | } | 1470 | } |
| 199 | 1471 | ||
| 200 | -SrsMp4MediaInformationBox::SrsMp4MediaInformationBox() | 1472 | +int SrsMp4SampleEntry::nb_header() |
| 201 | { | 1473 | { |
| 202 | - type = 0x6d696e66; // 'minf' | 1474 | + return SrsMp4Box::nb_header()+6+2; |
| 203 | } | 1475 | } |
| 204 | 1476 | ||
| 205 | -SrsMp4MediaInformationBox::~SrsMp4MediaInformationBox() | 1477 | +int SrsMp4SampleEntry::encode_header(SrsBuffer* buf) |
| 206 | { | 1478 | { |
| 1479 | + int ret = ERROR_SUCCESS; | ||
| 1480 | + | ||
| 1481 | + if ((ret = SrsMp4Box::encode_header(buf)) != ERROR_SUCCESS) { | ||
| 1482 | + return ret; | ||
| 1483 | + } | ||
| 1484 | + | ||
| 1485 | + for (int i = 0; i < 6; i++) { | ||
| 1486 | + buf->write_1bytes(reserved[i]); | ||
| 1487 | + } | ||
| 1488 | + buf->write_2bytes(data_reference_index); | ||
| 1489 | + | ||
| 1490 | + return ret; | ||
| 207 | } | 1491 | } |
| 208 | 1492 | ||
| 209 | -SrsMp4VideoMeidaHeaderBox::SrsMp4VideoMeidaHeaderBox() | 1493 | +int SrsMp4SampleEntry::decode_header(SrsBuffer* buf) |
| 210 | { | 1494 | { |
| 211 | - type = 0x766d6864; // 'vmhd' | ||
| 212 | - version = 0; | ||
| 213 | - flags = 1; | 1495 | + int ret = ERROR_SUCCESS; |
| 214 | 1496 | ||
| 215 | - graphicsmode = 0; | ||
| 216 | - memset(opcolor, 0, 6); | 1497 | + if ((ret = SrsMp4Box::decode_header(buf)) != ERROR_SUCCESS) { |
| 1498 | + return ret; | ||
| 1499 | + } | ||
| 1500 | + | ||
| 1501 | + buf->skip(6); | ||
| 1502 | + data_reference_index = buf->read_2bytes(); | ||
| 1503 | + | ||
| 1504 | + return ret; | ||
| 217 | } | 1505 | } |
| 218 | 1506 | ||
| 219 | -SrsMp4VideoMeidaHeaderBox::~SrsMp4VideoMeidaHeaderBox() | 1507 | +SrsMp4VisualSampleEntry::SrsMp4VisualSampleEntry() |
| 220 | { | 1508 | { |
| 1509 | + pre_defined0 = 0; | ||
| 1510 | + reserved0 = 0; | ||
| 1511 | + reserved1 = 0; | ||
| 1512 | + memset(pre_defined1, 0, 12); | ||
| 1513 | + memset(compressorname, 0, 32); | ||
| 1514 | + frame_count = 1; | ||
| 1515 | + horizresolution = 0x00480000; // 72 dpi | ||
| 1516 | + vertresolution = 0x00480000; // 72 dpi | ||
| 1517 | + depth = 0x0018; | ||
| 1518 | + pre_defined2 = -1; | ||
| 221 | } | 1519 | } |
| 222 | 1520 | ||
| 223 | -SrsMp4SoundMeidaHeaderBox::SrsMp4SoundMeidaHeaderBox() | 1521 | +SrsMp4VisualSampleEntry::~SrsMp4VisualSampleEntry() |
| 224 | { | 1522 | { |
| 225 | - type = 0x736d6864; // 'smhd' | ||
| 226 | - | ||
| 227 | - reserved = balance = 0; | ||
| 228 | } | 1523 | } |
| 229 | 1524 | ||
| 230 | -SrsMp4SoundMeidaHeaderBox::~SrsMp4SoundMeidaHeaderBox() | 1525 | +int SrsMp4VisualSampleEntry::nb_header() |
| 231 | { | 1526 | { |
| 1527 | + return SrsMp4SampleEntry::nb_header()+2+2+12+2+2+4+4+4+2+32+2+2; | ||
| 232 | } | 1528 | } |
| 233 | 1529 | ||
| 234 | -SrsMp4DataInformationBox::SrsMp4DataInformationBox() | 1530 | +int SrsMp4VisualSampleEntry::encode_header(SrsBuffer* buf) |
| 235 | { | 1531 | { |
| 236 | - type = 0x64696e66; // 'dinf' | 1532 | + int ret = ERROR_SUCCESS; |
| 1533 | + | ||
| 1534 | + if ((ret = SrsMp4SampleEntry::encode_header(buf)) != ERROR_SUCCESS) { | ||
| 1535 | + return ret; | ||
| 1536 | + } | ||
| 1537 | + | ||
| 1538 | + buf->write_2bytes(pre_defined0); | ||
| 1539 | + buf->write_2bytes(reserved0); | ||
| 1540 | + buf->write_4bytes(pre_defined1[0]); | ||
| 1541 | + buf->write_4bytes(pre_defined1[1]); | ||
| 1542 | + buf->write_4bytes(pre_defined1[2]); | ||
| 1543 | + buf->write_2bytes(width); | ||
| 1544 | + buf->write_2bytes(height); | ||
| 1545 | + buf->write_4bytes(horizresolution); | ||
| 1546 | + buf->write_4bytes(vertresolution); | ||
| 1547 | + buf->write_4bytes(reserved1); | ||
| 1548 | + buf->write_2bytes(frame_count); | ||
| 1549 | + buf->write_bytes(compressorname, 32); | ||
| 1550 | + buf->write_2bytes(depth); | ||
| 1551 | + buf->write_2bytes(pre_defined2); | ||
| 1552 | + | ||
| 1553 | + return ret; | ||
| 237 | } | 1554 | } |
| 238 | 1555 | ||
| 239 | -SrsMp4DataInformationBox::~SrsMp4DataInformationBox() | 1556 | +int SrsMp4VisualSampleEntry::decode_header(SrsBuffer* buf) |
| 240 | { | 1557 | { |
| 1558 | + int ret = ERROR_SUCCESS; | ||
| 1559 | + | ||
| 1560 | + if ((ret = SrsMp4SampleEntry::decode_header(buf)) != ERROR_SUCCESS) { | ||
| 1561 | + return ret; | ||
| 1562 | + } | ||
| 1563 | + | ||
| 1564 | + buf->skip(2); | ||
| 1565 | + buf->skip(2); | ||
| 1566 | + buf->skip(12); | ||
| 1567 | + width = buf->read_2bytes(); | ||
| 1568 | + height = buf->read_2bytes(); | ||
| 1569 | + horizresolution = buf->read_4bytes(); | ||
| 1570 | + vertresolution = buf->read_4bytes(); | ||
| 1571 | + buf->skip(4); | ||
| 1572 | + frame_count = buf->read_2bytes(); | ||
| 1573 | + buf->read_bytes(compressorname, 32); | ||
| 1574 | + depth = buf->read_2bytes(); | ||
| 1575 | + buf->skip(2); | ||
| 1576 | + | ||
| 1577 | + return ret; | ||
| 241 | } | 1578 | } |
| 242 | 1579 | ||
| 243 | -SrsMp4DataEntryBox::SrsMp4DataEntryBox() | 1580 | +SrsMp4AudioSampleEntry::SrsMp4AudioSampleEntry() |
| 244 | { | 1581 | { |
| 1582 | + reserved0 = 0; | ||
| 1583 | + pre_defined0 = 0; | ||
| 1584 | + reserved1 = 0; | ||
| 1585 | + channelcount = 2; | ||
| 1586 | + samplesize = 16; | ||
| 245 | } | 1587 | } |
| 246 | 1588 | ||
| 247 | -SrsMp4DataEntryUrlBox::SrsMp4DataEntryUrlBox() | 1589 | +SrsMp4AudioSampleEntry::~SrsMp4AudioSampleEntry() |
| 248 | { | 1590 | { |
| 249 | - type = 0x75726c20; // 'url ' | ||
| 250 | } | 1591 | } |
| 251 | 1592 | ||
| 252 | -SrsMp4DataEntryUrnBox::SrsMp4DataEntryUrnBox() | 1593 | +int SrsMp4AudioSampleEntry::nb_header() |
| 253 | { | 1594 | { |
| 254 | - type = 0x75726e20; // 'urn ' | 1595 | + return SrsMp4SampleEntry::nb_header()+8+2+2+2+2+4; |
| 255 | } | 1596 | } |
| 256 | 1597 | ||
| 257 | -SrsMp4DataReferenceBox::SrsMp4DataReferenceBox() | 1598 | +int SrsMp4AudioSampleEntry::encode_header(SrsBuffer* buf) |
| 258 | { | 1599 | { |
| 259 | - type = 0x64726566; // 'dref' | 1600 | + int ret = ERROR_SUCCESS; |
| 260 | 1601 | ||
| 261 | - entry_count = 0; | ||
| 262 | - entries = NULL; | 1602 | + if ((ret = SrsMp4SampleEntry::encode_header(buf)) != ERROR_SUCCESS) { |
| 1603 | + return ret; | ||
| 1604 | + } | ||
| 1605 | + | ||
| 1606 | + buf->write_8bytes(reserved0); | ||
| 1607 | + buf->write_2bytes(channelcount); | ||
| 1608 | + buf->write_2bytes(samplesize); | ||
| 1609 | + buf->write_2bytes(pre_defined0); | ||
| 1610 | + buf->write_2bytes(reserved1); | ||
| 1611 | + buf->write_4bytes(samplerate); | ||
| 1612 | + | ||
| 1613 | + return ret; | ||
| 263 | } | 1614 | } |
| 264 | 1615 | ||
| 265 | -SrsMp4DataReferenceBox::~SrsMp4DataReferenceBox() | 1616 | +int SrsMp4AudioSampleEntry::decode_header(SrsBuffer* buf) |
| 266 | { | 1617 | { |
| 1618 | + int ret = ERROR_SUCCESS; | ||
| 1619 | + | ||
| 1620 | + if ((ret = SrsMp4SampleEntry::decode_header(buf)) != ERROR_SUCCESS) { | ||
| 1621 | + return ret; | ||
| 1622 | + } | ||
| 1623 | + | ||
| 1624 | + buf->skip(8); | ||
| 1625 | + channelcount = buf->read_2bytes(); | ||
| 1626 | + samplesize = buf->read_2bytes(); | ||
| 1627 | + buf->skip(2); | ||
| 1628 | + buf->skip(2); | ||
| 1629 | + samplerate = buf->read_4bytes(); | ||
| 1630 | + | ||
| 1631 | + return ret; | ||
| 267 | } | 1632 | } |
| 268 | 1633 | ||
| 269 | -SrsMp4SampleTableBox::SrsMp4SampleTableBox() | 1634 | +SrsMp4SampleDescriptionBox::SrsMp4SampleDescriptionBox() |
| 270 | { | 1635 | { |
| 271 | - type = 0x7374626c; // 'stbl' | 1636 | + type = SRS_MP4_BOX_STSD; |
| 272 | } | 1637 | } |
| 273 | 1638 | ||
| 274 | -SrsMp4SampleTableBox::~SrsMp4SampleTableBox() | 1639 | +SrsMp4SampleDescriptionBox::~SrsMp4SampleDescriptionBox() |
| 275 | { | 1640 | { |
| 1641 | + vector<SrsMp4SampleEntry*>::iterator it; | ||
| 1642 | + for (it = entries.begin(); it != entries.end(); ++it) { | ||
| 1643 | + SrsMp4SampleEntry* entry = *it; | ||
| 1644 | + srs_freep(entry); | ||
| 1645 | + } | ||
| 1646 | + entries.clear(); | ||
| 276 | } | 1647 | } |
| 277 | 1648 | ||
| 278 | -SrsMp4SampleEntry::SrsMp4SampleEntry() | 1649 | +uint32_t SrsMp4SampleDescriptionBox::entry_count() |
| 279 | { | 1650 | { |
| 280 | - memset(reserved, 0, 6); | 1651 | + return (uint32_t)entries.size(); |
| 281 | } | 1652 | } |
| 282 | 1653 | ||
| 283 | -SrsMp4SampleEntry::~SrsMp4SampleEntry() | 1654 | +SrsMp4SampleEntry* SrsMp4SampleDescriptionBox::entrie_at(int index) |
| 284 | { | 1655 | { |
| 1656 | + return entries.at(index); | ||
| 285 | } | 1657 | } |
| 286 | 1658 | ||
| 287 | -SrsMp4VisualSampleEntry::SrsMp4VisualSampleEntry() | 1659 | +int SrsMp4SampleDescriptionBox::nb_header() |
| 288 | { | 1660 | { |
| 289 | - pre_defined0 = 0; | ||
| 290 | - reserved0 = 0; | ||
| 291 | - reserved1 = 0; | ||
| 292 | - memset(pre_defined1, 0, 12); | ||
| 293 | - memset(compressorname, 0, 32); | ||
| 294 | - frame_count = 1; | ||
| 295 | - horizresolution = 0x00480000; // 72 dpi | ||
| 296 | - vertresolution = 0x00480000; // 72 dpi | ||
| 297 | - depth = 0x0018; | ||
| 298 | - pre_defined2 = -1; | 1661 | + int size = SrsMp4FullBox::nb_header(); |
| 1662 | + | ||
| 1663 | + vector<SrsMp4SampleEntry*>::iterator it; | ||
| 1664 | + for (it = entries.begin(); it != entries.end(); ++it) { | ||
| 1665 | + SrsMp4SampleEntry* entry = *it; | ||
| 1666 | + size += entry->nb_bytes(); | ||
| 1667 | + } | ||
| 1668 | + | ||
| 1669 | + return size; | ||
| 299 | } | 1670 | } |
| 300 | 1671 | ||
| 301 | -SrsMp4VisualSampleEntry::~SrsMp4VisualSampleEntry() | 1672 | +int SrsMp4SampleDescriptionBox::encode_header(SrsBuffer* buf) |
| 302 | { | 1673 | { |
| 1674 | + int ret = ERROR_SUCCESS; | ||
| 1675 | + | ||
| 1676 | + if ((ret = SrsMp4FullBox::encode_header(buf)) != ERROR_SUCCESS) { | ||
| 1677 | + return ret; | ||
| 1678 | + } | ||
| 1679 | + | ||
| 1680 | + vector<SrsMp4SampleEntry*>::iterator it; | ||
| 1681 | + for (it = entries.begin(); it != entries.end(); ++it) { | ||
| 1682 | + SrsMp4SampleEntry* entry = *it; | ||
| 1683 | + if ((ret = entry->encode(buf)) != ERROR_SUCCESS) { | ||
| 1684 | + return ret; | ||
| 1685 | + } | ||
| 1686 | + } | ||
| 1687 | + | ||
| 1688 | + return ret; | ||
| 303 | } | 1689 | } |
| 304 | 1690 | ||
| 305 | -SrsMp4AudioSampleEntry::SrsMp4AudioSampleEntry() | 1691 | +int SrsMp4SampleDescriptionBox::decode_header(SrsBuffer* buf) |
| 306 | { | 1692 | { |
| 307 | - memset(reserved0, 0, 8); | ||
| 308 | - pre_defined0 = 0; | ||
| 309 | - reserved1 = 0; | ||
| 310 | - channelcount = 2; | ||
| 311 | - samplesize = 16; | 1693 | + int ret = ERROR_SUCCESS; |
| 1694 | + | ||
| 1695 | + if ((ret = SrsMp4FullBox::decode_header(buf)) != ERROR_SUCCESS) { | ||
| 1696 | + return ret; | ||
| 1697 | + } | ||
| 1698 | + | ||
| 1699 | + int left = left_space(buf); | ||
| 1700 | + while (left > 0) { | ||
| 1701 | + SrsMp4Box* box = NULL; | ||
| 1702 | + if ((ret = SrsMp4Box::discovery(buf, &box)) != ERROR_SUCCESS) { | ||
| 1703 | + return ret; | ||
| 1704 | + } | ||
| 1705 | + | ||
| 1706 | + int pos = buf->pos(); | ||
| 1707 | + if ((ret = box->decode(buf)) != ERROR_SUCCESS) { | ||
| 1708 | + return ret; | ||
| 1709 | + } | ||
| 1710 | + left -= buf->pos() - pos; | ||
| 1711 | + | ||
| 1712 | + SrsMp4SampleEntry* entry = dynamic_cast<SrsMp4SampleEntry*>(box); | ||
| 1713 | + if (entry) { | ||
| 1714 | + entries.push_back(entry); | ||
| 1715 | + } else { | ||
| 1716 | + srs_freep(box); | ||
| 1717 | + } | ||
| 1718 | + } | ||
| 1719 | + | ||
| 1720 | + return ret; | ||
| 312 | } | 1721 | } |
| 313 | 1722 | ||
| 314 | -SrsMp4AudioSampleEntry::~SrsMp4AudioSampleEntry() | 1723 | +SrsMp4SttsEntry::SrsMp4SttsEntry() |
| 315 | { | 1724 | { |
| 1725 | + sample_count = 0; | ||
| 1726 | + sample_delta = 0; | ||
| 316 | } | 1727 | } |
| 317 | 1728 | ||
| 318 | -SrsMp4SampleDescriptionBox::SrsMp4SampleDescriptionBox() | 1729 | +SrsMp4DecodingTime2SampleBox::SrsMp4DecodingTime2SampleBox() |
| 319 | { | 1730 | { |
| 320 | - type = 0x73747364; // 'stsd' | 1731 | + type = SRS_MP4_BOX_STTS; |
| 321 | 1732 | ||
| 322 | entry_count = 0; | 1733 | entry_count = 0; |
| 323 | entries = NULL; | 1734 | entries = NULL; |
| 324 | } | 1735 | } |
| 325 | 1736 | ||
| 326 | -SrsMp4SampleDescriptionBox::~SrsMp4SampleDescriptionBox() | 1737 | +SrsMp4DecodingTime2SampleBox::~SrsMp4DecodingTime2SampleBox() |
| 327 | { | 1738 | { |
| 328 | srs_freepa(entries); | 1739 | srs_freepa(entries); |
| 329 | } | 1740 | } |
| 330 | 1741 | ||
| 331 | -SrsMp4SttsEntry::SrsMp4SttsEntry() | 1742 | +int SrsMp4DecodingTime2SampleBox::nb_header() |
| 332 | { | 1743 | { |
| 333 | - sample_count = 0; | ||
| 334 | - sample_delta = 0; | 1744 | + return SrsMp4FullBox::nb_header(); |
| 335 | } | 1745 | } |
| 336 | 1746 | ||
| 337 | -SrsMp4DecodingTime2SampleBox::SrsMp4DecodingTime2SampleBox() | 1747 | +int SrsMp4DecodingTime2SampleBox::encode_header(SrsBuffer* buf) |
| 338 | { | 1748 | { |
| 339 | - type = 0x73747473; // 'stts' | 1749 | + int ret = ERROR_SUCCESS; |
| 340 | 1750 | ||
| 341 | - entry_count = 0; | ||
| 342 | - entries = NULL; | 1751 | + if ((ret = SrsMp4FullBox::encode_header(buf)) != ERROR_SUCCESS) { |
| 1752 | + return ret; | ||
| 1753 | + } | ||
| 1754 | + | ||
| 1755 | + return ret; | ||
| 343 | } | 1756 | } |
| 344 | 1757 | ||
| 345 | -SrsMp4DecodingTime2SampleBox::~SrsMp4DecodingTime2SampleBox() | 1758 | +int SrsMp4DecodingTime2SampleBox::decode_header(SrsBuffer* buf) |
| 346 | { | 1759 | { |
| 347 | - srs_freepa(entries); | 1760 | + int ret = ERROR_SUCCESS; |
| 1761 | + | ||
| 1762 | + if ((ret = SrsMp4FullBox::decode_header(buf)) != ERROR_SUCCESS) { | ||
| 1763 | + return ret; | ||
| 1764 | + } | ||
| 1765 | + | ||
| 1766 | + return ret; | ||
| 348 | } | 1767 | } |
| 349 | 1768 | ||
| 350 | SrsMp4CttsEntry::SrsMp4CttsEntry() | 1769 | SrsMp4CttsEntry::SrsMp4CttsEntry() |
| @@ -355,7 +1774,7 @@ SrsMp4CttsEntry::SrsMp4CttsEntry() | @@ -355,7 +1774,7 @@ SrsMp4CttsEntry::SrsMp4CttsEntry() | ||
| 355 | 1774 | ||
| 356 | SrsMp4CompositionTime2SampleBox::SrsMp4CompositionTime2SampleBox() | 1775 | SrsMp4CompositionTime2SampleBox::SrsMp4CompositionTime2SampleBox() |
| 357 | { | 1776 | { |
| 358 | - type = 0x63747473; // 'ctts' | 1777 | + type = SRS_MP4_BOX_CTTS; |
| 359 | 1778 | ||
| 360 | entry_count = 0; | 1779 | entry_count = 0; |
| 361 | entries = NULL; | 1780 | entries = NULL; |
| @@ -366,9 +1785,36 @@ SrsMp4CompositionTime2SampleBox::~SrsMp4CompositionTime2SampleBox() | @@ -366,9 +1785,36 @@ SrsMp4CompositionTime2SampleBox::~SrsMp4CompositionTime2SampleBox() | ||
| 366 | srs_freepa(entries); | 1785 | srs_freepa(entries); |
| 367 | } | 1786 | } |
| 368 | 1787 | ||
| 1788 | +int SrsMp4CompositionTime2SampleBox::nb_header() | ||
| 1789 | +{ | ||
| 1790 | + return SrsMp4FullBox::nb_header(); | ||
| 1791 | +} | ||
| 1792 | + | ||
| 1793 | +int SrsMp4CompositionTime2SampleBox::encode_header(SrsBuffer* buf) | ||
| 1794 | +{ | ||
| 1795 | + int ret = ERROR_SUCCESS; | ||
| 1796 | + | ||
| 1797 | + if ((ret = SrsMp4FullBox::encode_header(buf)) != ERROR_SUCCESS) { | ||
| 1798 | + return ret; | ||
| 1799 | + } | ||
| 1800 | + | ||
| 1801 | + return ret; | ||
| 1802 | +} | ||
| 1803 | + | ||
| 1804 | +int SrsMp4CompositionTime2SampleBox::decode_header(SrsBuffer* buf) | ||
| 1805 | +{ | ||
| 1806 | + int ret = ERROR_SUCCESS; | ||
| 1807 | + | ||
| 1808 | + if ((ret = SrsMp4FullBox::decode_header(buf)) != ERROR_SUCCESS) { | ||
| 1809 | + return ret; | ||
| 1810 | + } | ||
| 1811 | + | ||
| 1812 | + return ret; | ||
| 1813 | +} | ||
| 1814 | + | ||
| 369 | SrsMp4SyncSampleBox::SrsMp4SyncSampleBox() | 1815 | SrsMp4SyncSampleBox::SrsMp4SyncSampleBox() |
| 370 | { | 1816 | { |
| 371 | - type = 0x73747373; // 'stss' | 1817 | + type = SRS_MP4_BOX_STSS; |
| 372 | 1818 | ||
| 373 | entry_count = 0; | 1819 | entry_count = 0; |
| 374 | sample_numbers = NULL; | 1820 | sample_numbers = NULL; |
| @@ -379,6 +1825,33 @@ SrsMp4SyncSampleBox::~SrsMp4SyncSampleBox() | @@ -379,6 +1825,33 @@ SrsMp4SyncSampleBox::~SrsMp4SyncSampleBox() | ||
| 379 | srs_freepa(sample_numbers); | 1825 | srs_freepa(sample_numbers); |
| 380 | } | 1826 | } |
| 381 | 1827 | ||
| 1828 | +int SrsMp4SyncSampleBox::nb_header() | ||
| 1829 | +{ | ||
| 1830 | + return SrsMp4FullBox::nb_header(); | ||
| 1831 | +} | ||
| 1832 | + | ||
| 1833 | +int SrsMp4SyncSampleBox::encode_header(SrsBuffer* buf) | ||
| 1834 | +{ | ||
| 1835 | + int ret = ERROR_SUCCESS; | ||
| 1836 | + | ||
| 1837 | + if ((ret = SrsMp4FullBox::encode_header(buf)) != ERROR_SUCCESS) { | ||
| 1838 | + return ret; | ||
| 1839 | + } | ||
| 1840 | + | ||
| 1841 | + return ret; | ||
| 1842 | +} | ||
| 1843 | + | ||
| 1844 | +int SrsMp4SyncSampleBox::decode_header(SrsBuffer* buf) | ||
| 1845 | +{ | ||
| 1846 | + int ret = ERROR_SUCCESS; | ||
| 1847 | + | ||
| 1848 | + if ((ret = SrsMp4FullBox::decode_header(buf)) != ERROR_SUCCESS) { | ||
| 1849 | + return ret; | ||
| 1850 | + } | ||
| 1851 | + | ||
| 1852 | + return ret; | ||
| 1853 | +} | ||
| 1854 | + | ||
| 382 | SrsMp4StscEntry::SrsMp4StscEntry() | 1855 | SrsMp4StscEntry::SrsMp4StscEntry() |
| 383 | { | 1856 | { |
| 384 | first_chunk = 0; | 1857 | first_chunk = 0; |
| @@ -388,7 +1861,7 @@ SrsMp4StscEntry::SrsMp4StscEntry() | @@ -388,7 +1861,7 @@ SrsMp4StscEntry::SrsMp4StscEntry() | ||
| 388 | 1861 | ||
| 389 | SrsMp4Sample2ChunkBox::SrsMp4Sample2ChunkBox() | 1862 | SrsMp4Sample2ChunkBox::SrsMp4Sample2ChunkBox() |
| 390 | { | 1863 | { |
| 391 | - type = 0x73747363; // 'stsc' | 1864 | + type = SRS_MP4_BOX_STSC; |
| 392 | 1865 | ||
| 393 | entry_count = 0; | 1866 | entry_count = 0; |
| 394 | entries = NULL; | 1867 | entries = NULL; |
| @@ -399,9 +1872,36 @@ SrsMp4Sample2ChunkBox::~SrsMp4Sample2ChunkBox() | @@ -399,9 +1872,36 @@ SrsMp4Sample2ChunkBox::~SrsMp4Sample2ChunkBox() | ||
| 399 | srs_freepa(entries); | 1872 | srs_freepa(entries); |
| 400 | } | 1873 | } |
| 401 | 1874 | ||
| 1875 | +int SrsMp4Sample2ChunkBox::nb_header() | ||
| 1876 | +{ | ||
| 1877 | + return SrsMp4FullBox::nb_header(); | ||
| 1878 | +} | ||
| 1879 | + | ||
| 1880 | +int SrsMp4Sample2ChunkBox::encode_header(SrsBuffer* buf) | ||
| 1881 | +{ | ||
| 1882 | + int ret = ERROR_SUCCESS; | ||
| 1883 | + | ||
| 1884 | + if ((ret = SrsMp4FullBox::encode_header(buf)) != ERROR_SUCCESS) { | ||
| 1885 | + return ret; | ||
| 1886 | + } | ||
| 1887 | + | ||
| 1888 | + return ret; | ||
| 1889 | +} | ||
| 1890 | + | ||
| 1891 | +int SrsMp4Sample2ChunkBox::decode_header(SrsBuffer* buf) | ||
| 1892 | +{ | ||
| 1893 | + int ret = ERROR_SUCCESS; | ||
| 1894 | + | ||
| 1895 | + if ((ret = SrsMp4FullBox::decode_header(buf)) != ERROR_SUCCESS) { | ||
| 1896 | + return ret; | ||
| 1897 | + } | ||
| 1898 | + | ||
| 1899 | + return ret; | ||
| 1900 | +} | ||
| 1901 | + | ||
| 402 | SrsMp4ChunkOffsetBox::SrsMp4ChunkOffsetBox() | 1902 | SrsMp4ChunkOffsetBox::SrsMp4ChunkOffsetBox() |
| 403 | { | 1903 | { |
| 404 | - type = 0x7374636f; // 'stco' | 1904 | + type = SRS_MP4_BOX_STCO; |
| 405 | 1905 | ||
| 406 | entry_count = 0; | 1906 | entry_count = 0; |
| 407 | entries = NULL; | 1907 | entries = NULL; |
| @@ -412,9 +1912,36 @@ SrsMp4ChunkOffsetBox::~SrsMp4ChunkOffsetBox() | @@ -412,9 +1912,36 @@ SrsMp4ChunkOffsetBox::~SrsMp4ChunkOffsetBox() | ||
| 412 | srs_freepa(entries); | 1912 | srs_freepa(entries); |
| 413 | } | 1913 | } |
| 414 | 1914 | ||
| 1915 | +int SrsMp4ChunkOffsetBox::nb_header() | ||
| 1916 | +{ | ||
| 1917 | + return SrsMp4FullBox::nb_header(); | ||
| 1918 | +} | ||
| 1919 | + | ||
| 1920 | +int SrsMp4ChunkOffsetBox::encode_header(SrsBuffer* buf) | ||
| 1921 | +{ | ||
| 1922 | + int ret = ERROR_SUCCESS; | ||
| 1923 | + | ||
| 1924 | + if ((ret = SrsMp4FullBox::encode_header(buf)) != ERROR_SUCCESS) { | ||
| 1925 | + return ret; | ||
| 1926 | + } | ||
| 1927 | + | ||
| 1928 | + return ret; | ||
| 1929 | +} | ||
| 1930 | + | ||
| 1931 | +int SrsMp4ChunkOffsetBox::decode_header(SrsBuffer* buf) | ||
| 1932 | +{ | ||
| 1933 | + int ret = ERROR_SUCCESS; | ||
| 1934 | + | ||
| 1935 | + if ((ret = SrsMp4FullBox::decode_header(buf)) != ERROR_SUCCESS) { | ||
| 1936 | + return ret; | ||
| 1937 | + } | ||
| 1938 | + | ||
| 1939 | + return ret; | ||
| 1940 | +} | ||
| 1941 | + | ||
| 415 | SrsMp4SampleSizeBox::SrsMp4SampleSizeBox() | 1942 | SrsMp4SampleSizeBox::SrsMp4SampleSizeBox() |
| 416 | { | 1943 | { |
| 417 | - type = 0x7374737a; // 'stsz' | 1944 | + type = SRS_MP4_BOX_STSZ; |
| 418 | 1945 | ||
| 419 | sample_size = sample_count = 0; | 1946 | sample_size = sample_count = 0; |
| 420 | entry_sizes = NULL; | 1947 | entry_sizes = NULL; |
| @@ -425,12 +1952,44 @@ SrsMp4SampleSizeBox::~SrsMp4SampleSizeBox() | @@ -425,12 +1952,44 @@ SrsMp4SampleSizeBox::~SrsMp4SampleSizeBox() | ||
| 425 | srs_freepa(entry_sizes); | 1952 | srs_freepa(entry_sizes); |
| 426 | } | 1953 | } |
| 427 | 1954 | ||
| 1955 | +int SrsMp4SampleSizeBox::nb_header() | ||
| 1956 | +{ | ||
| 1957 | + return SrsMp4FullBox::nb_header(); | ||
| 1958 | +} | ||
| 1959 | + | ||
| 1960 | +int SrsMp4SampleSizeBox::encode_header(SrsBuffer* buf) | ||
| 1961 | +{ | ||
| 1962 | + int ret = ERROR_SUCCESS; | ||
| 1963 | + | ||
| 1964 | + if ((ret = SrsMp4FullBox::encode_header(buf)) != ERROR_SUCCESS) { | ||
| 1965 | + return ret; | ||
| 1966 | + } | ||
| 1967 | + | ||
| 1968 | + return ret; | ||
| 1969 | +} | ||
| 1970 | + | ||
| 1971 | +int SrsMp4SampleSizeBox::decode_header(SrsBuffer* buf) | ||
| 1972 | +{ | ||
| 1973 | + int ret = ERROR_SUCCESS; | ||
| 1974 | + | ||
| 1975 | + if ((ret = SrsMp4FullBox::decode_header(buf)) != ERROR_SUCCESS) { | ||
| 1976 | + return ret; | ||
| 1977 | + } | ||
| 1978 | + | ||
| 1979 | + return ret; | ||
| 1980 | +} | ||
| 1981 | + | ||
| 428 | SrsMp4Decoder::SrsMp4Decoder() | 1982 | SrsMp4Decoder::SrsMp4Decoder() |
| 429 | { | 1983 | { |
| 1984 | + reader = NULL; | ||
| 1985 | + next = NULL; | ||
| 1986 | + stream = new SrsSimpleStream(); | ||
| 430 | } | 1987 | } |
| 431 | 1988 | ||
| 432 | SrsMp4Decoder::~SrsMp4Decoder() | 1989 | SrsMp4Decoder::~SrsMp4Decoder() |
| 433 | { | 1990 | { |
| 1991 | + srs_freep(next); | ||
| 1992 | + srs_freep(stream); | ||
| 434 | } | 1993 | } |
| 435 | 1994 | ||
| 436 | int SrsMp4Decoder::initialize(ISrsReader* r) | 1995 | int SrsMp4Decoder::initialize(ISrsReader* r) |
| @@ -440,6 +1999,67 @@ int SrsMp4Decoder::initialize(ISrsReader* r) | @@ -440,6 +1999,67 @@ int SrsMp4Decoder::initialize(ISrsReader* r) | ||
| 440 | srs_assert(r); | 1999 | srs_assert(r); |
| 441 | reader = r; | 2000 | reader = r; |
| 442 | 2001 | ||
| 2002 | + if ((ret = load_next_box(&next)) != ERROR_SUCCESS) { | ||
| 2003 | + return ret; | ||
| 2004 | + } | ||
| 2005 | + | ||
| 2006 | + if (next->type != SRS_MP4_BOX_FTYP) { | ||
| 2007 | + ret = ERROR_MP4_BOX_ILLEGAL_SCHEMA; | ||
| 2008 | + srs_error("MP4 first box must be FTYP, not %d. ret=%d", next->type, ret); | ||
| 2009 | + return ret; | ||
| 2010 | + } | ||
| 2011 | + | ||
| 2012 | + return ret; | ||
| 2013 | +} | ||
| 2014 | + | ||
| 2015 | +int SrsMp4Decoder::load_next_box(SrsMp4Box** ppbox) | ||
| 2016 | +{ | ||
| 2017 | + int ret = ERROR_SUCCESS; | ||
| 2018 | + | ||
| 2019 | + // Ignore for already loaded. | ||
| 2020 | + if (next) { | ||
| 2021 | + return ret; | ||
| 2022 | + } | ||
| 2023 | + | ||
| 2024 | + char* buf = new char[4096]; | ||
| 2025 | + SrsAutoFreeA(char, buf); | ||
| 2026 | + | ||
| 2027 | + while (true) { | ||
| 2028 | + uint64_t required = next? next->sz():4; | ||
| 2029 | + while (stream->length() < required) { | ||
| 2030 | + ssize_t nread; | ||
| 2031 | + if ((ret = reader->read(buf, 4096, &nread)) != ERROR_SUCCESS) { | ||
| 2032 | + srs_error("MP4 load failed, nread=%d, required=%d. ret=%d", nread, required, ret); | ||
| 2033 | + return ret; | ||
| 2034 | + } | ||
| 2035 | + | ||
| 2036 | + srs_assert(nread > 0); | ||
| 2037 | + stream->append(buf, (int)nread); | ||
| 2038 | + } | ||
| 2039 | + | ||
| 2040 | + SrsBuffer* buffer = new SrsBuffer(stream->bytes(), stream->length()); | ||
| 2041 | + SrsAutoFree(SrsBuffer, buffer); | ||
| 2042 | + | ||
| 2043 | + // Discovery the box with basic header. | ||
| 2044 | + if (!next && (ret = SrsMp4Box::discovery(buffer, ppbox)) != ERROR_SUCCESS) { | ||
| 2045 | + if (ret == ERROR_MP4_BOX_REQUIRE_SPACE) { | ||
| 2046 | + continue; | ||
| 2047 | + } | ||
| 2048 | + srs_error("MP4 load box failed. ret=%d", ret); | ||
| 2049 | + return ret; | ||
| 2050 | + } | ||
| 2051 | + | ||
| 2052 | + // Decode util we can demux the whole box. | ||
| 2053 | + if (!buffer->require((int)next->sz())) { | ||
| 2054 | + continue; | ||
| 2055 | + } | ||
| 2056 | + ret = next->decode(buffer); | ||
| 2057 | + | ||
| 2058 | + // Remove the consumed bytes. | ||
| 2059 | + stream->erase((int)next->sz()); | ||
| 2060 | + break; | ||
| 2061 | + } | ||
| 2062 | + | ||
| 443 | return ret; | 2063 | return ret; |
| 444 | } | 2064 | } |
| 445 | 2065 |
| @@ -29,30 +29,77 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | @@ -29,30 +29,77 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
| 29 | */ | 29 | */ |
| 30 | #include <srs_core.hpp> | 30 | #include <srs_core.hpp> |
| 31 | 31 | ||
| 32 | +#include <srs_kernel_buffer.hpp> | ||
| 33 | + | ||
| 32 | #include <string> | 34 | #include <string> |
| 35 | +#include <vector> | ||
| 33 | 36 | ||
| 34 | class ISrsReader; | 37 | class ISrsReader; |
| 38 | +class SrsSimpleStream; | ||
| 35 | 39 | ||
| 36 | /** | 40 | /** |
| 37 | * 4.2 Object Structure | 41 | * 4.2 Object Structure |
| 38 | * ISO_IEC_14496-12-base-format-2012.pdf, page 16 | 42 | * ISO_IEC_14496-12-base-format-2012.pdf, page 16 |
| 39 | */ | 43 | */ |
| 40 | -class SrsMp4Box | 44 | +class SrsMp4Box : public ISrsCodec |
| 41 | { | 45 | { |
| 42 | -public: | 46 | +private: |
| 47 | + // The size is the entire size of the box, including the size and type header, fields, | ||
| 48 | + // and all contained boxes. This facilitates general parsing of the file. | ||
| 49 | + // | ||
| 43 | // if size is 1 then the actual size is in the field largesize; | 50 | // if size is 1 then the actual size is in the field largesize; |
| 44 | // if size is 0, then this box is the last one in the file, and its contents | 51 | // if size is 0, then this box is the last one in the file, and its contents |
| 45 | // extend to the end of the file (normally only used for a Media Data Box) | 52 | // extend to the end of the file (normally only used for a Media Data Box) |
| 46 | - uint32_t size; | 53 | + uint32_t smallsize; |
| 54 | + uint64_t largesize; | ||
| 55 | +public: | ||
| 56 | + // identifies the box type; standard boxes use a compact type, which is normally four printable | ||
| 57 | + // characters, to permit ease of identification, and is shown so in the boxes below. User extensions use | ||
| 58 | + // an extended type; in this case, the type field is set to ‘uuid’. | ||
| 47 | uint32_t type; | 59 | uint32_t type; |
| 60 | + // For box 'uuid'. | ||
| 61 | + uint8_t* usertype; | ||
| 62 | +private: | ||
| 63 | + std::vector<SrsMp4Box*> boxes; | ||
| 64 | +private: | ||
| 65 | + // The position at buffer to start demux the box. | ||
| 66 | + int start_pos; | ||
| 48 | public: | 67 | public: |
| 49 | SrsMp4Box(); | 68 | SrsMp4Box(); |
| 50 | virtual ~SrsMp4Box(); | 69 | virtual ~SrsMp4Box(); |
| 70 | +public: | ||
| 71 | + // Get the size of box, whatever small or large size. | ||
| 72 | + virtual uint64_t sz(); | ||
| 73 | + // Get the left space of box, for decoder. | ||
| 74 | + virtual int left_space(SrsBuffer* buf); | ||
| 75 | + /** | ||
| 76 | + * Discovery the box from buffer. | ||
| 77 | + * @param ppbox Output the discoveried box, which user must free it. | ||
| 78 | + */ | ||
| 79 | + static int discovery(SrsBuffer* buf, SrsMp4Box** ppbox); | ||
| 80 | +// Interface ISrsCodec | ||
| 81 | +public: | ||
| 82 | + virtual int nb_bytes(); | ||
| 83 | + virtual int encode(SrsBuffer* buf); | ||
| 84 | + virtual int decode(SrsBuffer* buf); | ||
| 85 | +protected: | ||
| 86 | + virtual int encode_boxes(SrsBuffer* buf); | ||
| 87 | + virtual int decode_boxes(SrsBuffer* buf); | ||
| 88 | +// Sub classes can override these functions for special codec. | ||
| 89 | +protected: | ||
| 90 | + // The size of header, not including the contained boxes. | ||
| 91 | + virtual int nb_header(); | ||
| 92 | + // It's not necessary to check the buffer, because we already know the size in parent function, | ||
| 93 | + // so we have checked the buffer is ok to write. | ||
| 94 | + virtual int encode_header(SrsBuffer* buf); | ||
| 95 | + // It's not necessary to check the buffer, unless the box is not only determined by the verson. | ||
| 96 | + // Generally, it's not necessary, that is, all boxes is determinated by version. | ||
| 97 | + virtual int decode_header(SrsBuffer* buf); | ||
| 51 | }; | 98 | }; |
| 52 | 99 | ||
| 53 | /** | 100 | /** |
| 54 | * 4.2 Object Structure | 101 | * 4.2 Object Structure |
| 55 | - * ISO_IEC_14496-12-base-format-2012.pdf, page 16 | 102 | + * ISO_IEC_14496-12-base-format-2012.pdf, page 17 |
| 56 | */ | 103 | */ |
| 57 | class SrsMp4FullBox : public SrsMp4Box | 104 | class SrsMp4FullBox : public SrsMp4Box |
| 58 | { | 105 | { |
| @@ -64,6 +111,10 @@ public: | @@ -64,6 +111,10 @@ public: | ||
| 64 | public: | 111 | public: |
| 65 | SrsMp4FullBox(); | 112 | SrsMp4FullBox(); |
| 66 | virtual ~SrsMp4FullBox(); | 113 | virtual ~SrsMp4FullBox(); |
| 114 | +protected: | ||
| 115 | + virtual int nb_header(); | ||
| 116 | + virtual int encode_header(SrsBuffer* buf); | ||
| 117 | + virtual int decode_header(SrsBuffer* buf); | ||
| 67 | }; | 118 | }; |
| 68 | 119 | ||
| 69 | /** | 120 | /** |
| @@ -88,6 +139,10 @@ private: | @@ -88,6 +139,10 @@ private: | ||
| 88 | public: | 139 | public: |
| 89 | SrsMp4FileTypeBox(); | 140 | SrsMp4FileTypeBox(); |
| 90 | virtual ~SrsMp4FileTypeBox(); | 141 | virtual ~SrsMp4FileTypeBox(); |
| 142 | +protected: | ||
| 143 | + virtual int nb_header(); | ||
| 144 | + virtual int encode_header(SrsBuffer* buf); | ||
| 145 | + virtual int decode_header(SrsBuffer* buf); | ||
| 91 | }; | 146 | }; |
| 92 | 147 | ||
| 93 | /** | 148 | /** |
| @@ -101,11 +156,16 @@ public: | @@ -101,11 +156,16 @@ public: | ||
| 101 | class SrsMp4MediaDataBox : public SrsMp4Box | 156 | class SrsMp4MediaDataBox : public SrsMp4Box |
| 102 | { | 157 | { |
| 103 | private: | 158 | private: |
| 159 | + // the contained media data | ||
| 104 | int nb_data; | 160 | int nb_data; |
| 105 | uint8_t* data; | 161 | uint8_t* data; |
| 106 | public: | 162 | public: |
| 107 | SrsMp4MediaDataBox(); | 163 | SrsMp4MediaDataBox(); |
| 108 | virtual ~SrsMp4MediaDataBox(); | 164 | virtual ~SrsMp4MediaDataBox(); |
| 165 | +protected: | ||
| 166 | + virtual int nb_header(); | ||
| 167 | + virtual int encode_header(SrsBuffer* buf); | ||
| 168 | + virtual int decode_header(SrsBuffer* buf); | ||
| 109 | }; | 169 | }; |
| 110 | 170 | ||
| 111 | /** | 171 | /** |
| @@ -114,9 +174,16 @@ public: | @@ -114,9 +174,16 @@ public: | ||
| 114 | */ | 174 | */ |
| 115 | class SrsMp4FreeSpaceBox : public SrsMp4Box | 175 | class SrsMp4FreeSpaceBox : public SrsMp4Box |
| 116 | { | 176 | { |
| 177 | +private: | ||
| 178 | + int nb_data; | ||
| 179 | + uint8_t* data; | ||
| 117 | public: | 180 | public: |
| 118 | SrsMp4FreeSpaceBox(); | 181 | SrsMp4FreeSpaceBox(); |
| 119 | virtual ~SrsMp4FreeSpaceBox(); | 182 | virtual ~SrsMp4FreeSpaceBox(); |
| 183 | +protected: | ||
| 184 | + virtual int nb_header(); | ||
| 185 | + virtual int encode_header(SrsBuffer* buf); | ||
| 186 | + virtual int decode_header(SrsBuffer* buf); | ||
| 120 | }; | 187 | }; |
| 121 | 188 | ||
| 122 | /** | 189 | /** |
| @@ -172,6 +239,10 @@ public: | @@ -172,6 +239,10 @@ public: | ||
| 172 | public: | 239 | public: |
| 173 | SrsMp4MovieHeaderBox(); | 240 | SrsMp4MovieHeaderBox(); |
| 174 | virtual ~SrsMp4MovieHeaderBox(); | 241 | virtual ~SrsMp4MovieHeaderBox(); |
| 242 | +protected: | ||
| 243 | + virtual int nb_header(); | ||
| 244 | + virtual int encode_header(SrsBuffer* buf); | ||
| 245 | + virtual int decode_header(SrsBuffer* buf); | ||
| 175 | }; | 246 | }; |
| 176 | 247 | ||
| 177 | /** | 248 | /** |
| @@ -201,10 +272,6 @@ public: | @@ -201,10 +272,6 @@ public: | ||
| 201 | // an integer that declares the most recent time the presentation was modified (in | 272 | // an integer that declares the most recent time the presentation was modified (in |
| 202 | // seconds since midnight, Jan. 1, 1904, in UTC time) | 273 | // seconds since midnight, Jan. 1, 1904, in UTC time) |
| 203 | uint64_t modification_time; | 274 | uint64_t modification_time; |
| 204 | - // an integer that specifies the time-scale for the entire presentation; this is the number of | ||
| 205 | - // time units that pass in one second. For example, a time coordinate system that measures time in | ||
| 206 | - // sixtieths of a second has a time scale of 60. | ||
| 207 | - uint32_t timescale; | ||
| 208 | // an integer that uniquely identifies this track over the entire life-time of this presentation. | 275 | // an integer that uniquely identifies this track over the entire life-time of this presentation. |
| 209 | // Track IDs are never re-used and cannot be zero. | 276 | // Track IDs are never re-used and cannot be zero. |
| 210 | uint32_t track_ID; | 277 | uint32_t track_ID; |
| @@ -244,6 +311,10 @@ public: | @@ -244,6 +311,10 @@ public: | ||
| 244 | public: | 311 | public: |
| 245 | SrsMp4TrackHeaderBox(); | 312 | SrsMp4TrackHeaderBox(); |
| 246 | virtual ~SrsMp4TrackHeaderBox(); | 313 | virtual ~SrsMp4TrackHeaderBox(); |
| 314 | +protected: | ||
| 315 | + virtual int nb_header(); | ||
| 316 | + virtual int encode_header(SrsBuffer* buf); | ||
| 317 | + virtual int decode_header(SrsBuffer* buf); | ||
| 247 | }; | 318 | }; |
| 248 | 319 | ||
| 249 | /** | 320 | /** |
| @@ -282,6 +353,10 @@ public: | @@ -282,6 +353,10 @@ public: | ||
| 282 | int16_t media_rate_fraction; | 353 | int16_t media_rate_fraction; |
| 283 | public: | 354 | public: |
| 284 | SrsMp4ElstEntry(); | 355 | SrsMp4ElstEntry(); |
| 356 | +public: | ||
| 357 | + virtual int nb_header(uint32_t version); | ||
| 358 | + virtual int encode_header(SrsBuffer* buf, uint32_t version); | ||
| 359 | + virtual int decode_header(SrsBuffer* buf, uint32_t version); | ||
| 285 | }; | 360 | }; |
| 286 | 361 | ||
| 287 | /** | 362 | /** |
| @@ -300,6 +375,10 @@ public: | @@ -300,6 +375,10 @@ public: | ||
| 300 | public: | 375 | public: |
| 301 | SrsMp4EditListBox(); | 376 | SrsMp4EditListBox(); |
| 302 | virtual ~SrsMp4EditListBox(); | 377 | virtual ~SrsMp4EditListBox(); |
| 378 | +protected: | ||
| 379 | + virtual int nb_header(); | ||
| 380 | + virtual int encode_header(SrsBuffer* buf); | ||
| 381 | + virtual int decode_header(SrsBuffer* buf); | ||
| 303 | }; | 382 | }; |
| 304 | 383 | ||
| 305 | /** | 384 | /** |
| @@ -338,16 +417,29 @@ public: | @@ -338,16 +417,29 @@ public: | ||
| 338 | // is derived from the presentation’s tracks: the value of this field corresponds to the duration of the | 417 | // is derived from the presentation’s tracks: the value of this field corresponds to the duration of the |
| 339 | // longest track in the presentation. If the duration cannot be determined then duration is set to all 1s. | 418 | // longest track in the presentation. If the duration cannot be determined then duration is set to all 1s. |
| 340 | uint64_t duration; | 419 | uint64_t duration; |
| 341 | -public: | ||
| 342 | - uint8_t pad:1; | 420 | +private: |
| 343 | // the language code for this media. See ISO 639-2/T for the set of three character | 421 | // the language code for this media. See ISO 639-2/T for the set of three character |
| 344 | // codes. Each character is packed as the difference between its ASCII value and 0x60. Since the code | 422 | // codes. Each character is packed as the difference between its ASCII value and 0x60. Since the code |
| 345 | // is confined to being three lower-case letters, these values are strictly positive. | 423 | // is confined to being three lower-case letters, these values are strictly positive. |
| 346 | - uint16_t language:15; | 424 | + uint16_t language; |
| 347 | uint16_t pre_defined; | 425 | uint16_t pre_defined; |
| 348 | public: | 426 | public: |
| 349 | SrsMp4MediaHeaderBox(); | 427 | SrsMp4MediaHeaderBox(); |
| 350 | virtual ~SrsMp4MediaHeaderBox(); | 428 | virtual ~SrsMp4MediaHeaderBox(); |
| 429 | +public: | ||
| 430 | + // the language code for this media. See ISO 639-2/T for the set of three character | ||
| 431 | + // codes. Each character is packed as the difference between its ASCII value and 0x60. Since the code | ||
| 432 | + // is confined to being three lower-case letters, these values are strictly positive. | ||
| 433 | + virtual uint8_t language0(); | ||
| 434 | + virtual void set_language0(uint8_t v); | ||
| 435 | + virtual uint8_t language1(); | ||
| 436 | + virtual void set_language1(uint8_t v); | ||
| 437 | + virtual uint8_t language2(); | ||
| 438 | + virtual void set_language2(uint8_t v); | ||
| 439 | +protected: | ||
| 440 | + virtual int nb_header(); | ||
| 441 | + virtual int encode_header(SrsBuffer* buf); | ||
| 442 | + virtual int decode_header(SrsBuffer* buf); | ||
| 351 | }; | 443 | }; |
| 352 | 444 | ||
| 353 | /** | 445 | /** |
| @@ -371,6 +463,10 @@ public: | @@ -371,6 +463,10 @@ public: | ||
| 371 | public: | 463 | public: |
| 372 | SrsMp4HandlerReferenceBox(); | 464 | SrsMp4HandlerReferenceBox(); |
| 373 | virtual ~SrsMp4HandlerReferenceBox(); | 465 | virtual ~SrsMp4HandlerReferenceBox(); |
| 466 | +protected: | ||
| 467 | + virtual int nb_header(); | ||
| 468 | + virtual int encode_header(SrsBuffer* buf); | ||
| 469 | + virtual int decode_header(SrsBuffer* buf); | ||
| 374 | }; | 470 | }; |
| 375 | 471 | ||
| 376 | /** | 472 | /** |
| @@ -403,6 +499,10 @@ public: | @@ -403,6 +499,10 @@ public: | ||
| 403 | public: | 499 | public: |
| 404 | SrsMp4VideoMeidaHeaderBox(); | 500 | SrsMp4VideoMeidaHeaderBox(); |
| 405 | virtual ~SrsMp4VideoMeidaHeaderBox(); | 501 | virtual ~SrsMp4VideoMeidaHeaderBox(); |
| 502 | +protected: | ||
| 503 | + virtual int nb_header(); | ||
| 504 | + virtual int encode_header(SrsBuffer* buf); | ||
| 505 | + virtual int decode_header(SrsBuffer* buf); | ||
| 406 | }; | 506 | }; |
| 407 | 507 | ||
| 408 | /** | 508 | /** |
| @@ -421,6 +521,10 @@ public: | @@ -421,6 +521,10 @@ public: | ||
| 421 | public: | 521 | public: |
| 422 | SrsMp4SoundMeidaHeaderBox(); | 522 | SrsMp4SoundMeidaHeaderBox(); |
| 423 | virtual ~SrsMp4SoundMeidaHeaderBox(); | 523 | virtual ~SrsMp4SoundMeidaHeaderBox(); |
| 524 | +protected: | ||
| 525 | + virtual int nb_header(); | ||
| 526 | + virtual int encode_header(SrsBuffer* buf); | ||
| 527 | + virtual int decode_header(SrsBuffer* buf); | ||
| 424 | }; | 528 | }; |
| 425 | 529 | ||
| 426 | /** | 530 | /** |
| @@ -445,6 +549,11 @@ public: | @@ -445,6 +549,11 @@ public: | ||
| 445 | std::string location; | 549 | std::string location; |
| 446 | public: | 550 | public: |
| 447 | SrsMp4DataEntryBox(); | 551 | SrsMp4DataEntryBox(); |
| 552 | + virtual ~SrsMp4DataEntryBox(); | ||
| 553 | +protected: | ||
| 554 | + virtual int nb_header(); | ||
| 555 | + virtual int encode_header(SrsBuffer* buf); | ||
| 556 | + virtual int decode_header(SrsBuffer* buf); | ||
| 448 | }; | 557 | }; |
| 449 | 558 | ||
| 450 | /** | 559 | /** |
| @@ -455,6 +564,7 @@ class SrsMp4DataEntryUrlBox : public SrsMp4DataEntryBox | @@ -455,6 +564,7 @@ class SrsMp4DataEntryUrlBox : public SrsMp4DataEntryBox | ||
| 455 | { | 564 | { |
| 456 | public: | 565 | public: |
| 457 | SrsMp4DataEntryUrlBox(); | 566 | SrsMp4DataEntryUrlBox(); |
| 567 | + virtual ~SrsMp4DataEntryUrlBox(); | ||
| 458 | }; | 568 | }; |
| 459 | 569 | ||
| 460 | /** | 570 | /** |
| @@ -467,6 +577,11 @@ public: | @@ -467,6 +577,11 @@ public: | ||
| 467 | std::string name; | 577 | std::string name; |
| 468 | public: | 578 | public: |
| 469 | SrsMp4DataEntryUrnBox(); | 579 | SrsMp4DataEntryUrnBox(); |
| 580 | + virtual ~SrsMp4DataEntryUrnBox(); | ||
| 581 | +protected: | ||
| 582 | + virtual int nb_header(); | ||
| 583 | + virtual int encode_header(SrsBuffer* buf); | ||
| 584 | + virtual int decode_header(SrsBuffer* buf); | ||
| 470 | }; | 585 | }; |
| 471 | 586 | ||
| 472 | /** | 587 | /** |
| @@ -478,13 +593,18 @@ public: | @@ -478,13 +593,18 @@ public: | ||
| 478 | */ | 593 | */ |
| 479 | class SrsMp4DataReferenceBox : public SrsMp4FullBox | 594 | class SrsMp4DataReferenceBox : public SrsMp4FullBox |
| 480 | { | 595 | { |
| 481 | -public: | ||
| 482 | - // an integer that counts the actual entries | ||
| 483 | - uint32_t entry_count; | ||
| 484 | - SrsMp4DataEntryBox* entries; | 596 | +private: |
| 597 | + std::vector<SrsMp4DataEntryBox*> entries; | ||
| 485 | public: | 598 | public: |
| 486 | SrsMp4DataReferenceBox(); | 599 | SrsMp4DataReferenceBox(); |
| 487 | virtual ~SrsMp4DataReferenceBox(); | 600 | virtual ~SrsMp4DataReferenceBox(); |
| 601 | +public: | ||
| 602 | + virtual uint32_t entry_count(); | ||
| 603 | + virtual SrsMp4DataEntryBox* entry_at(int index); | ||
| 604 | +protected: | ||
| 605 | + virtual int nb_header(); | ||
| 606 | + virtual int encode_header(SrsBuffer* buf); | ||
| 607 | + virtual int decode_header(SrsBuffer* buf); | ||
| 488 | }; | 608 | }; |
| 489 | 609 | ||
| 490 | /** | 610 | /** |
| @@ -516,6 +636,10 @@ public: | @@ -516,6 +636,10 @@ public: | ||
| 516 | public: | 636 | public: |
| 517 | SrsMp4SampleEntry(); | 637 | SrsMp4SampleEntry(); |
| 518 | virtual ~SrsMp4SampleEntry(); | 638 | virtual ~SrsMp4SampleEntry(); |
| 639 | +protected: | ||
| 640 | + virtual int nb_header(); | ||
| 641 | + virtual int encode_header(SrsBuffer* buf); | ||
| 642 | + virtual int decode_header(SrsBuffer* buf); | ||
| 519 | }; | 643 | }; |
| 520 | 644 | ||
| 521 | /** | 645 | /** |
| @@ -549,6 +673,10 @@ public: | @@ -549,6 +673,10 @@ public: | ||
| 549 | public: | 673 | public: |
| 550 | SrsMp4VisualSampleEntry(); | 674 | SrsMp4VisualSampleEntry(); |
| 551 | virtual ~SrsMp4VisualSampleEntry(); | 675 | virtual ~SrsMp4VisualSampleEntry(); |
| 676 | +protected: | ||
| 677 | + virtual int nb_header(); | ||
| 678 | + virtual int encode_header(SrsBuffer* buf); | ||
| 679 | + virtual int decode_header(SrsBuffer* buf); | ||
| 552 | }; | 680 | }; |
| 553 | 681 | ||
| 554 | /** | 682 | /** |
| @@ -558,7 +686,7 @@ public: | @@ -558,7 +686,7 @@ public: | ||
| 558 | class SrsMp4AudioSampleEntry : public SrsMp4SampleEntry | 686 | class SrsMp4AudioSampleEntry : public SrsMp4SampleEntry |
| 559 | { | 687 | { |
| 560 | public: | 688 | public: |
| 561 | - uint32_t reserved0[2]; | 689 | + uint64_t reserved0; |
| 562 | uint16_t channelcount; | 690 | uint16_t channelcount; |
| 563 | uint16_t samplesize; | 691 | uint16_t samplesize; |
| 564 | uint16_t pre_defined0; | 692 | uint16_t pre_defined0; |
| @@ -567,6 +695,10 @@ public: | @@ -567,6 +695,10 @@ public: | ||
| 567 | public: | 695 | public: |
| 568 | SrsMp4AudioSampleEntry(); | 696 | SrsMp4AudioSampleEntry(); |
| 569 | virtual ~SrsMp4AudioSampleEntry(); | 697 | virtual ~SrsMp4AudioSampleEntry(); |
| 698 | +protected: | ||
| 699 | + virtual int nb_header(); | ||
| 700 | + virtual int encode_header(SrsBuffer* buf); | ||
| 701 | + virtual int decode_header(SrsBuffer* buf); | ||
| 570 | }; | 702 | }; |
| 571 | 703 | ||
| 572 | /** | 704 | /** |
| @@ -577,13 +709,18 @@ public: | @@ -577,13 +709,18 @@ public: | ||
| 577 | */ | 709 | */ |
| 578 | class SrsMp4SampleDescriptionBox : public SrsMp4FullBox | 710 | class SrsMp4SampleDescriptionBox : public SrsMp4FullBox |
| 579 | { | 711 | { |
| 580 | -public: | ||
| 581 | - // an integer that gives the number of entries in the following table | ||
| 582 | - uint32_t entry_count; | ||
| 583 | - SrsMp4SampleEntry* entries; | 712 | +private: |
| 713 | + std::vector<SrsMp4SampleEntry*> entries; | ||
| 584 | public: | 714 | public: |
| 585 | SrsMp4SampleDescriptionBox(); | 715 | SrsMp4SampleDescriptionBox(); |
| 586 | virtual ~SrsMp4SampleDescriptionBox(); | 716 | virtual ~SrsMp4SampleDescriptionBox(); |
| 717 | +public: | ||
| 718 | + virtual uint32_t entry_count(); | ||
| 719 | + virtual SrsMp4SampleEntry* entrie_at(int index); | ||
| 720 | +protected: | ||
| 721 | + virtual int nb_header(); | ||
| 722 | + virtual int encode_header(SrsBuffer* buf); | ||
| 723 | + virtual int decode_header(SrsBuffer* buf); | ||
| 587 | }; | 724 | }; |
| 588 | 725 | ||
| 589 | /** | 726 | /** |
| @@ -618,6 +755,10 @@ public: | @@ -618,6 +755,10 @@ public: | ||
| 618 | public: | 755 | public: |
| 619 | SrsMp4DecodingTime2SampleBox(); | 756 | SrsMp4DecodingTime2SampleBox(); |
| 620 | virtual ~SrsMp4DecodingTime2SampleBox(); | 757 | virtual ~SrsMp4DecodingTime2SampleBox(); |
| 758 | +protected: | ||
| 759 | + virtual int nb_header(); | ||
| 760 | + virtual int encode_header(SrsBuffer* buf); | ||
| 761 | + virtual int decode_header(SrsBuffer* buf); | ||
| 621 | }; | 762 | }; |
| 622 | 763 | ||
| 623 | 764 | ||
| @@ -657,6 +798,10 @@ public: | @@ -657,6 +798,10 @@ public: | ||
| 657 | public: | 798 | public: |
| 658 | SrsMp4CompositionTime2SampleBox(); | 799 | SrsMp4CompositionTime2SampleBox(); |
| 659 | virtual ~SrsMp4CompositionTime2SampleBox(); | 800 | virtual ~SrsMp4CompositionTime2SampleBox(); |
| 801 | +protected: | ||
| 802 | + virtual int nb_header(); | ||
| 803 | + virtual int encode_header(SrsBuffer* buf); | ||
| 804 | + virtual int decode_header(SrsBuffer* buf); | ||
| 660 | }; | 805 | }; |
| 661 | 806 | ||
| 662 | /** | 807 | /** |
| @@ -676,6 +821,10 @@ public: | @@ -676,6 +821,10 @@ public: | ||
| 676 | public: | 821 | public: |
| 677 | SrsMp4SyncSampleBox(); | 822 | SrsMp4SyncSampleBox(); |
| 678 | virtual ~SrsMp4SyncSampleBox(); | 823 | virtual ~SrsMp4SyncSampleBox(); |
| 824 | +protected: | ||
| 825 | + virtual int nb_header(); | ||
| 826 | + virtual int encode_header(SrsBuffer* buf); | ||
| 827 | + virtual int decode_header(SrsBuffer* buf); | ||
| 679 | }; | 828 | }; |
| 680 | 829 | ||
| 681 | /** | 830 | /** |
| @@ -716,6 +865,10 @@ public: | @@ -716,6 +865,10 @@ public: | ||
| 716 | public: | 865 | public: |
| 717 | SrsMp4Sample2ChunkBox(); | 866 | SrsMp4Sample2ChunkBox(); |
| 718 | virtual ~SrsMp4Sample2ChunkBox(); | 867 | virtual ~SrsMp4Sample2ChunkBox(); |
| 868 | +protected: | ||
| 869 | + virtual int nb_header(); | ||
| 870 | + virtual int encode_header(SrsBuffer* buf); | ||
| 871 | + virtual int decode_header(SrsBuffer* buf); | ||
| 719 | }; | 872 | }; |
| 720 | 873 | ||
| 721 | /** | 874 | /** |
| @@ -736,6 +889,10 @@ public: | @@ -736,6 +889,10 @@ public: | ||
| 736 | public: | 889 | public: |
| 737 | SrsMp4ChunkOffsetBox(); | 890 | SrsMp4ChunkOffsetBox(); |
| 738 | virtual ~SrsMp4ChunkOffsetBox(); | 891 | virtual ~SrsMp4ChunkOffsetBox(); |
| 892 | +protected: | ||
| 893 | + virtual int nb_header(); | ||
| 894 | + virtual int encode_header(SrsBuffer* buf); | ||
| 895 | + virtual int decode_header(SrsBuffer* buf); | ||
| 739 | }; | 896 | }; |
| 740 | 897 | ||
| 741 | /** | 898 | /** |
| @@ -760,6 +917,10 @@ public: | @@ -760,6 +917,10 @@ public: | ||
| 760 | public: | 917 | public: |
| 761 | SrsMp4SampleSizeBox(); | 918 | SrsMp4SampleSizeBox(); |
| 762 | virtual ~SrsMp4SampleSizeBox(); | 919 | virtual ~SrsMp4SampleSizeBox(); |
| 920 | +protected: | ||
| 921 | + virtual int nb_header(); | ||
| 922 | + virtual int encode_header(SrsBuffer* buf); | ||
| 923 | + virtual int decode_header(SrsBuffer* buf); | ||
| 763 | }; | 924 | }; |
| 764 | 925 | ||
| 765 | /** | 926 | /** |
| @@ -768,7 +929,13 @@ public: | @@ -768,7 +929,13 @@ public: | ||
| 768 | class SrsMp4Decoder | 929 | class SrsMp4Decoder |
| 769 | { | 930 | { |
| 770 | private: | 931 | private: |
| 932 | + // Underlayer reader. | ||
| 771 | ISrsReader* reader; | 933 | ISrsReader* reader; |
| 934 | + // The stream used to demux the boxes. | ||
| 935 | + // TODO: FIXME: refine for performance issue. | ||
| 936 | + SrsSimpleStream* stream; | ||
| 937 | + // Always load next box. | ||
| 938 | + SrsMp4Box* next; | ||
| 772 | public: | 939 | public: |
| 773 | SrsMp4Decoder(); | 940 | SrsMp4Decoder(); |
| 774 | virtual ~SrsMp4Decoder(); | 941 | virtual ~SrsMp4Decoder(); |
| @@ -779,6 +946,8 @@ public: | @@ -779,6 +946,8 @@ public: | ||
| 779 | * the decoder just read data from the reader. | 946 | * the decoder just read data from the reader. |
| 780 | */ | 947 | */ |
| 781 | virtual int initialize(ISrsReader* r); | 948 | virtual int initialize(ISrsReader* r); |
| 949 | +private: | ||
| 950 | + virtual int load_next_box(SrsMp4Box** ppbox); | ||
| 782 | }; | 951 | }; |
| 783 | 952 | ||
| 784 | #endif | 953 | #endif |
-
请 注册 或 登录 后发表评论