正在显示
5 个修改的文件
包含
162 行增加
和
15 行删除
@@ -123,7 +123,6 @@ Please select your language: | @@ -123,7 +123,6 @@ Please select your language: | ||
123 | * [SRS 2.0 English][v2_EN_Home] | 123 | * [SRS 2.0 English][v2_EN_Home] |
124 | * [SRS 2.0 Chinese][v2_CN_Home] | 124 | * [SRS 2.0 Chinese][v2_CN_Home] |
125 | 125 | ||
126 | -<<<<<<< HEAD | ||
127 | ### SRS 3.0 wiki | 126 | ### SRS 3.0 wiki |
128 | 127 | ||
129 | Please select your language: | 128 | Please select your language: |
@@ -182,6 +181,8 @@ Please select your language: | @@ -182,6 +181,8 @@ Please select your language: | ||
182 | - [ ] Support MPEG-DASH, the future streaming protocol, read [#299][bug #299]. | 181 | - [ ] Support MPEG-DASH, the future streaming protocol, read [#299][bug #299]. |
183 | - [ ] Support HLS+, please read [#466][bug #466] and [#468][bug #468]. | 182 | - [ ] Support HLS+, please read [#466][bug #466] and [#468][bug #468]. |
184 | 183 | ||
184 | +### Change Logs | ||
185 | + | ||
185 | ### V3 changes | 186 | ### V3 changes |
186 | 187 | ||
187 | * v3.0, 2017-01-19, for [#742][bug #742] refine source, meta and origin hub. 3.0.16 | 188 | * v3.0, 2017-01-19, for [#742][bug #742] refine source, meta and origin hub. 3.0.16 |
@@ -250,6 +250,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | @@ -250,6 +250,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
250 | #define ERROR_MP4_BOX_ILLEGAL_BRAND 3074 | 250 | #define ERROR_MP4_BOX_ILLEGAL_BRAND 3074 |
251 | #define ERROR_MP4_NOT_NON_SEEKABLE 3075 | 251 | #define ERROR_MP4_NOT_NON_SEEKABLE 3075 |
252 | #define ERROR_MP4_ESDS_SL_Config 3076 | 252 | #define ERROR_MP4_ESDS_SL_Config 3076 |
253 | +#define ERROR_MP4_ILLEGAL_MOOV 3077 | ||
253 | 254 | ||
254 | /////////////////////////////////////////////////////// | 255 | /////////////////////////////////////////////////////// |
255 | // HTTP/StreamCaster/KAFKA protocol error. | 256 | // HTTP/StreamCaster/KAFKA protocol error. |
@@ -141,15 +141,17 @@ extern ISrsThreadContext* _srs_context; | @@ -141,15 +141,17 @@ extern ISrsThreadContext* _srs_context; | ||
141 | #define srs_trace(msg, ...) _srs_log->trace(NULL, _srs_context->get_id(), msg, ##__VA_ARGS__) | 141 | #define srs_trace(msg, ...) _srs_log->trace(NULL, _srs_context->get_id(), msg, ##__VA_ARGS__) |
142 | #define srs_warn(msg, ...) _srs_log->warn(NULL, _srs_context->get_id(), msg, ##__VA_ARGS__) | 142 | #define srs_warn(msg, ...) _srs_log->warn(NULL, _srs_context->get_id(), msg, ##__VA_ARGS__) |
143 | #define srs_error(msg, ...) _srs_log->error(NULL, _srs_context->get_id(), msg, ##__VA_ARGS__) | 143 | #define srs_error(msg, ...) _srs_log->error(NULL, _srs_context->get_id(), msg, ##__VA_ARGS__) |
144 | +#endif | ||
144 | // use __FUNCTION__ to print c method | 145 | // use __FUNCTION__ to print c method |
145 | -#elif 0 | 146 | +#if 0 |
146 | #define srs_verbose(msg, ...) _srs_log->verbose(__FUNCTION__, _srs_context->get_id(), msg, ##__VA_ARGS__) | 147 | #define srs_verbose(msg, ...) _srs_log->verbose(__FUNCTION__, _srs_context->get_id(), msg, ##__VA_ARGS__) |
147 | #define srs_info(msg, ...) _srs_log->info(__FUNCTION__, _srs_context->get_id(), msg, ##__VA_ARGS__) | 148 | #define srs_info(msg, ...) _srs_log->info(__FUNCTION__, _srs_context->get_id(), msg, ##__VA_ARGS__) |
148 | #define srs_trace(msg, ...) _srs_log->trace(__FUNCTION__, _srs_context->get_id(), msg, ##__VA_ARGS__) | 149 | #define srs_trace(msg, ...) _srs_log->trace(__FUNCTION__, _srs_context->get_id(), msg, ##__VA_ARGS__) |
149 | #define srs_warn(msg, ...) _srs_log->warn(__FUNCTION__, _srs_context->get_id(), msg, ##__VA_ARGS__) | 150 | #define srs_warn(msg, ...) _srs_log->warn(__FUNCTION__, _srs_context->get_id(), msg, ##__VA_ARGS__) |
150 | #define srs_error(msg, ...) _srs_log->error(__FUNCTION__, _srs_context->get_id(), msg, ##__VA_ARGS__) | 151 | #define srs_error(msg, ...) _srs_log->error(__FUNCTION__, _srs_context->get_id(), msg, ##__VA_ARGS__) |
152 | +#endif | ||
151 | // use __PRETTY_FUNCTION__ to print c++ class:method | 153 | // use __PRETTY_FUNCTION__ to print c++ class:method |
152 | -#else | 154 | +#if 0 |
153 | #define srs_verbose(msg, ...) _srs_log->verbose(__PRETTY_FUNCTION__, _srs_context->get_id(), msg, ##__VA_ARGS__) | 155 | #define srs_verbose(msg, ...) _srs_log->verbose(__PRETTY_FUNCTION__, _srs_context->get_id(), msg, ##__VA_ARGS__) |
154 | #define srs_info(msg, ...) _srs_log->info(__PRETTY_FUNCTION__, _srs_context->get_id(), msg, ##__VA_ARGS__) | 156 | #define srs_info(msg, ...) _srs_log->info(__PRETTY_FUNCTION__, _srs_context->get_id(), msg, ##__VA_ARGS__) |
155 | #define srs_trace(msg, ...) _srs_log->trace(__PRETTY_FUNCTION__, _srs_context->get_id(), msg, ##__VA_ARGS__) | 157 | #define srs_trace(msg, ...) _srs_log->trace(__PRETTY_FUNCTION__, _srs_context->get_id(), msg, ##__VA_ARGS__) |
@@ -121,6 +121,19 @@ bool SrsMp4Box::is_mdat() | @@ -121,6 +121,19 @@ bool SrsMp4Box::is_mdat() | ||
121 | return type == SrsMp4BoxTypeMDAT; | 121 | return type == SrsMp4BoxTypeMDAT; |
122 | } | 122 | } |
123 | 123 | ||
124 | +SrsMp4Box* SrsMp4Box::get(SrsMp4BoxType bt) | ||
125 | +{ | ||
126 | + vector<SrsMp4Box*>::iterator it; | ||
127 | + for (it = boxes.begin(); it != boxes.end(); ++it) { | ||
128 | + SrsMp4Box* box = *it; | ||
129 | + if (box->type == bt) { | ||
130 | + return box; | ||
131 | + } | ||
132 | + } | ||
133 | + | ||
134 | + return NULL; | ||
135 | +} | ||
136 | + | ||
124 | int SrsMp4Box::discovery(SrsBuffer* buf, SrsMp4Box** ppbox) | 137 | int SrsMp4Box::discovery(SrsBuffer* buf, SrsMp4Box** ppbox) |
125 | { | 138 | { |
126 | *ppbox = NULL; | 139 | *ppbox = NULL; |
@@ -625,6 +638,40 @@ SrsMp4MovieBox::~SrsMp4MovieBox() | @@ -625,6 +638,40 @@ SrsMp4MovieBox::~SrsMp4MovieBox() | ||
625 | { | 638 | { |
626 | } | 639 | } |
627 | 640 | ||
641 | +SrsMp4MovieHeaderBox* SrsMp4MovieBox::mvhd() | ||
642 | +{ | ||
643 | + SrsMp4Box* box = get(SrsMp4BoxTypeMVHD); | ||
644 | + return dynamic_cast<SrsMp4MovieHeaderBox*>(box); | ||
645 | +} | ||
646 | + | ||
647 | +SrsMp4TrackBox* SrsMp4MovieBox::video() | ||
648 | +{ | ||
649 | + for (int i = 0; i < boxes.size(); i++) { | ||
650 | + SrsMp4Box* box = boxes.at(i); | ||
651 | + if (box->type == SrsMp4BoxTypeTRAK) { | ||
652 | + SrsMp4TrackBox* trak = dynamic_cast<SrsMp4TrackBox*>(box); | ||
653 | + if ((trak->track_type() & SrsMp4TrackTypeVideo) == SrsMp4TrackTypeVideo) { | ||
654 | + return trak; | ||
655 | + } | ||
656 | + } | ||
657 | + } | ||
658 | + return NULL; | ||
659 | +} | ||
660 | + | ||
661 | +SrsMp4TrackBox* SrsMp4MovieBox::audio() | ||
662 | +{ | ||
663 | + for (int i = 0; i < boxes.size(); i++) { | ||
664 | + SrsMp4Box* box = boxes.at(i); | ||
665 | + if (box->type == SrsMp4BoxTypeTRAK) { | ||
666 | + SrsMp4TrackBox* trak = dynamic_cast<SrsMp4TrackBox*>(box); | ||
667 | + if ((trak->track_type() & SrsMp4TrackTypeAudio) == SrsMp4TrackTypeAudio) { | ||
668 | + return trak; | ||
669 | + } | ||
670 | + } | ||
671 | + } | ||
672 | + return NULL; | ||
673 | +} | ||
674 | + | ||
628 | int SrsMp4MovieBox::nb_header() | 675 | int SrsMp4MovieBox::nb_header() |
629 | { | 676 | { |
630 | return SrsMp4Box::nb_header(); | 677 | return SrsMp4Box::nb_header(); |
@@ -659,6 +706,11 @@ SrsMp4MovieHeaderBox::~SrsMp4MovieHeaderBox() | @@ -659,6 +706,11 @@ SrsMp4MovieHeaderBox::~SrsMp4MovieHeaderBox() | ||
659 | { | 706 | { |
660 | } | 707 | } |
661 | 708 | ||
709 | +uint64_t SrsMp4MovieHeaderBox::duration() | ||
710 | +{ | ||
711 | + return duration_in_tbn * 1000 / timescale; | ||
712 | +} | ||
713 | + | ||
662 | int SrsMp4MovieHeaderBox::nb_header() | 714 | int SrsMp4MovieHeaderBox::nb_header() |
663 | { | 715 | { |
664 | int size = SrsMp4FullBox::nb_header(); | 716 | int size = SrsMp4FullBox::nb_header(); |
@@ -686,12 +738,12 @@ int SrsMp4MovieHeaderBox::encode_header(SrsBuffer* buf) | @@ -686,12 +738,12 @@ int SrsMp4MovieHeaderBox::encode_header(SrsBuffer* buf) | ||
686 | buf->write_8bytes(creation_time); | 738 | buf->write_8bytes(creation_time); |
687 | buf->write_8bytes(modification_time); | 739 | buf->write_8bytes(modification_time); |
688 | buf->write_4bytes(timescale); | 740 | buf->write_4bytes(timescale); |
689 | - buf->write_8bytes(duration); | 741 | + buf->write_8bytes(duration_in_tbn); |
690 | } else { | 742 | } else { |
691 | buf->write_4bytes((uint32_t)creation_time); | 743 | buf->write_4bytes((uint32_t)creation_time); |
692 | buf->write_4bytes((uint32_t)modification_time); | 744 | buf->write_4bytes((uint32_t)modification_time); |
693 | buf->write_4bytes(timescale); | 745 | buf->write_4bytes(timescale); |
694 | - buf->write_4bytes((uint32_t)duration); | 746 | + buf->write_4bytes((uint32_t)duration_in_tbn); |
695 | } | 747 | } |
696 | 748 | ||
697 | buf->write_4bytes(rate); | 749 | buf->write_4bytes(rate); |
@@ -721,12 +773,12 @@ int SrsMp4MovieHeaderBox::decode_header(SrsBuffer* buf) | @@ -721,12 +773,12 @@ int SrsMp4MovieHeaderBox::decode_header(SrsBuffer* buf) | ||
721 | creation_time = buf->read_8bytes(); | 773 | creation_time = buf->read_8bytes(); |
722 | modification_time = buf->read_8bytes(); | 774 | modification_time = buf->read_8bytes(); |
723 | timescale = buf->read_4bytes(); | 775 | timescale = buf->read_4bytes(); |
724 | - duration = buf->read_8bytes(); | 776 | + duration_in_tbn = buf->read_8bytes(); |
725 | } else { | 777 | } else { |
726 | creation_time = buf->read_4bytes(); | 778 | creation_time = buf->read_4bytes(); |
727 | modification_time = buf->read_4bytes(); | 779 | modification_time = buf->read_4bytes(); |
728 | timescale = buf->read_4bytes(); | 780 | timescale = buf->read_4bytes(); |
729 | - duration = buf->read_4bytes(); | 781 | + duration_in_tbn = buf->read_4bytes(); |
730 | } | 782 | } |
731 | 783 | ||
732 | rate = buf->read_4bytes(); | 784 | rate = buf->read_4bytes(); |
@@ -769,6 +821,18 @@ SrsMp4TrackHeaderBox::~SrsMp4TrackHeaderBox() | @@ -769,6 +821,18 @@ SrsMp4TrackHeaderBox::~SrsMp4TrackHeaderBox() | ||
769 | { | 821 | { |
770 | } | 822 | } |
771 | 823 | ||
824 | +SrsMp4TrackType SrsMp4TrackBox::track_type() | ||
825 | +{ | ||
826 | + SrsMp4Box* box = get(SrsMp4BoxTypeMDIA); | ||
827 | + if (!box) { | ||
828 | + return SrsMp4TrackTypeForbidden; | ||
829 | + } | ||
830 | + | ||
831 | + // TODO: Maybe should discovery all mdia boxes. | ||
832 | + SrsMp4MediaBox* mdia = dynamic_cast<SrsMp4MediaBox*>(box); | ||
833 | + return mdia->track_type(); | ||
834 | +} | ||
835 | + | ||
772 | int SrsMp4TrackHeaderBox::nb_header() | 836 | int SrsMp4TrackHeaderBox::nb_header() |
773 | { | 837 | { |
774 | int size = SrsMp4FullBox::nb_header(); | 838 | int size = SrsMp4FullBox::nb_header(); |
@@ -962,6 +1026,23 @@ SrsMp4MediaBox::~SrsMp4MediaBox() | @@ -962,6 +1026,23 @@ SrsMp4MediaBox::~SrsMp4MediaBox() | ||
962 | { | 1026 | { |
963 | } | 1027 | } |
964 | 1028 | ||
1029 | +SrsMp4TrackType SrsMp4MediaBox::track_type() | ||
1030 | +{ | ||
1031 | + SrsMp4Box* box = get(SrsMp4BoxTypeHDLR); | ||
1032 | + if (!box) { | ||
1033 | + return SrsMp4TrackTypeForbidden; | ||
1034 | + } | ||
1035 | + | ||
1036 | + SrsMp4HandlerReferenceBox* hdlr = dynamic_cast<SrsMp4HandlerReferenceBox*>(box); | ||
1037 | + if (hdlr->handler_type == SrsMp4HandlerTypeSOUN) { | ||
1038 | + return SrsMp4TrackTypeAudio; | ||
1039 | + } else if (hdlr->handler_type == SrsMp4HandlerTypeVIDE) { | ||
1040 | + return SrsMp4TrackTypeVideo; | ||
1041 | + } else { | ||
1042 | + return SrsMp4TrackTypeForbidden; | ||
1043 | + } | ||
1044 | +} | ||
1045 | + | ||
965 | SrsMp4MediaHeaderBox::SrsMp4MediaHeaderBox() | 1046 | SrsMp4MediaHeaderBox::SrsMp4MediaHeaderBox() |
966 | { | 1047 | { |
967 | type = SrsMp4BoxTypeMDHD; | 1048 | type = SrsMp4BoxTypeMDHD; |
@@ -1084,12 +1165,12 @@ SrsMp4HandlerReferenceBox::~SrsMp4HandlerReferenceBox() | @@ -1084,12 +1165,12 @@ SrsMp4HandlerReferenceBox::~SrsMp4HandlerReferenceBox() | ||
1084 | 1165 | ||
1085 | bool SrsMp4HandlerReferenceBox::is_video() | 1166 | bool SrsMp4HandlerReferenceBox::is_video() |
1086 | { | 1167 | { |
1087 | - return handler_type == SrsMp4BoxTypeVIDE; | 1168 | + return handler_type == SrsMp4HandlerTypeVIDE; |
1088 | } | 1169 | } |
1089 | 1170 | ||
1090 | bool SrsMp4HandlerReferenceBox::is_audio() | 1171 | bool SrsMp4HandlerReferenceBox::is_audio() |
1091 | { | 1172 | { |
1092 | - return handler_type == SrsMp4BoxTypeSOUN; | 1173 | + return handler_type == SrsMp4HandlerTypeSOUN; |
1093 | } | 1174 | } |
1094 | 1175 | ||
1095 | int SrsMp4HandlerReferenceBox::nb_header() | 1176 | int SrsMp4HandlerReferenceBox::nb_header() |
@@ -1124,7 +1205,7 @@ int SrsMp4HandlerReferenceBox::decode_header(SrsBuffer* buf) | @@ -1124,7 +1205,7 @@ int SrsMp4HandlerReferenceBox::decode_header(SrsBuffer* buf) | ||
1124 | } | 1205 | } |
1125 | 1206 | ||
1126 | buf->skip(4); | 1207 | buf->skip(4); |
1127 | - handler_type = buf->read_4bytes(); | 1208 | + handler_type = (SrsMp4HandlerType)buf->read_4bytes(); |
1128 | buf->skip(12); | 1209 | buf->skip(12); |
1129 | 1210 | ||
1130 | if ((ret = srs_mp4_string_read(buf, name, left_space(buf))) != ERROR_SUCCESS) { | 1211 | if ((ret = srs_mp4_string_read(buf, name, left_space(buf))) != ERROR_SUCCESS) { |
@@ -2766,6 +2847,24 @@ int SrsMp4Decoder::initialize(ISrsReader* r) | @@ -2766,6 +2847,24 @@ int SrsMp4Decoder::initialize(ISrsReader* r) | ||
2766 | int SrsMp4Decoder::parse_moov(SrsMp4MovieBox* moov) | 2847 | int SrsMp4Decoder::parse_moov(SrsMp4MovieBox* moov) |
2767 | { | 2848 | { |
2768 | int ret = ERROR_SUCCESS; | 2849 | int ret = ERROR_SUCCESS; |
2850 | + | ||
2851 | + SrsMp4MovieHeaderBox* mvhd = moov->mvhd(); | ||
2852 | + if (!mvhd) { | ||
2853 | + ret = ERROR_MP4_ILLEGAL_MOOV; | ||
2854 | + srs_error("MP4 missing mvhd. ret=%d", ret); | ||
2855 | + return ret; | ||
2856 | + } | ||
2857 | + | ||
2858 | + SrsMp4TrackBox* vide = moov->video(); | ||
2859 | + SrsMp4TrackBox* soun = moov->audio(); | ||
2860 | + if (!vide && !soun) { | ||
2861 | + ret = ERROR_MP4_ILLEGAL_MOOV; | ||
2862 | + srs_error("MP4 missing audio and video track. ret=%d", ret); | ||
2863 | + return ret; | ||
2864 | + } | ||
2865 | + | ||
2866 | + srs_trace("MP4 moov dur=%dms, vide=%d, soun=%d", mvhd->duration(), vide != NULL, soun != NULL); | ||
2867 | + | ||
2769 | return ret; | 2868 | return ret; |
2770 | } | 2869 | } |
2771 | 2870 |
@@ -81,9 +81,18 @@ enum SrsMp4BoxType | @@ -81,9 +81,18 @@ enum SrsMp4BoxType | ||
81 | SrsMp4BoxTypeMP4A = 0x6d703461, // 'mp4a' | 81 | SrsMp4BoxTypeMP4A = 0x6d703461, // 'mp4a' |
82 | SrsMp4BoxTypeESDS = 0x65736473, // 'esds' | 82 | SrsMp4BoxTypeESDS = 0x65736473, // 'esds' |
83 | SrsMp4BoxTypeUDTA = 0x75647461, // 'udta' | 83 | SrsMp4BoxTypeUDTA = 0x75647461, // 'udta' |
84 | +}; | ||
85 | + | ||
86 | +/** | ||
87 | + * 8.4.3.3 Semantics | ||
88 | + * ISO_IEC_14496-12-base-format-2012.pdf, page 37 | ||
89 | + */ | ||
90 | +enum SrsMp4HandlerType | ||
91 | +{ | ||
92 | + SrsMp4HandlerTypeForbidden = 0x00, | ||
84 | 93 | ||
85 | - SrsMp4BoxTypeVIDE = 0x76696465, // 'vide' | ||
86 | - SrsMp4BoxTypeSOUN = 0x736f756e, // 'soun' | 94 | + SrsMp4HandlerTypeVIDE = 0x76696465, // 'vide' |
95 | + SrsMp4HandlerTypeSOUN = 0x736f756e, // 'soun' | ||
87 | }; | 96 | }; |
88 | 97 | ||
89 | /** | 98 | /** |
@@ -121,7 +130,7 @@ public: | @@ -121,7 +130,7 @@ public: | ||
121 | SrsMp4BoxType type; | 130 | SrsMp4BoxType type; |
122 | // For box 'uuid'. | 131 | // For box 'uuid'. |
123 | uint8_t* usertype; | 132 | uint8_t* usertype; |
124 | -private: | 133 | +protected: |
125 | std::vector<SrsMp4Box*> boxes; | 134 | std::vector<SrsMp4Box*> boxes; |
126 | private: | 135 | private: |
127 | // The position at buffer to start demux the box. | 136 | // The position at buffer to start demux the box. |
@@ -138,6 +147,9 @@ public: | @@ -138,6 +147,9 @@ public: | ||
138 | virtual bool is_ftyp(); | 147 | virtual bool is_ftyp(); |
139 | virtual bool is_moov(); | 148 | virtual bool is_moov(); |
140 | virtual bool is_mdat(); | 149 | virtual bool is_mdat(); |
150 | + // Get the contained box of specific type. | ||
151 | + // @return The first matched box. | ||
152 | + virtual SrsMp4Box* get(SrsMp4BoxType bt); | ||
141 | /** | 153 | /** |
142 | * Discovery the box from buffer. | 154 | * Discovery the box from buffer. |
143 | * @param ppbox Output the discoveried box, which user must free it. | 155 | * @param ppbox Output the discoveried box, which user must free it. |
@@ -252,6 +264,9 @@ protected: | @@ -252,6 +264,9 @@ protected: | ||
252 | virtual int decode_header(SrsBuffer* buf); | 264 | virtual int decode_header(SrsBuffer* buf); |
253 | }; | 265 | }; |
254 | 266 | ||
267 | +class SrsMp4TrackBox; | ||
268 | +class SrsMp4MovieHeaderBox; | ||
269 | + | ||
255 | /** | 270 | /** |
256 | * 8.2.1 Movie Box (moov) | 271 | * 8.2.1 Movie Box (moov) |
257 | * ISO_IEC_14496-12-base-format-2012.pdf, page 30 | 272 | * ISO_IEC_14496-12-base-format-2012.pdf, page 30 |
@@ -263,6 +278,13 @@ class SrsMp4MovieBox : public SrsMp4Box | @@ -263,6 +278,13 @@ class SrsMp4MovieBox : public SrsMp4Box | ||
263 | public: | 278 | public: |
264 | SrsMp4MovieBox(); | 279 | SrsMp4MovieBox(); |
265 | virtual ~SrsMp4MovieBox(); | 280 | virtual ~SrsMp4MovieBox(); |
281 | +public: | ||
282 | + // Get the header of moov. | ||
283 | + virtual SrsMp4MovieHeaderBox* mvhd(); | ||
284 | + // Get the first video track. | ||
285 | + virtual SrsMp4TrackBox* video(); | ||
286 | + // Get the first audio track. | ||
287 | + virtual SrsMp4TrackBox* audio(); | ||
266 | protected: | 288 | protected: |
267 | virtual int nb_header(); | 289 | virtual int nb_header(); |
268 | virtual int encode_header(SrsBuffer* buf); | 290 | virtual int encode_header(SrsBuffer* buf); |
@@ -282,6 +304,7 @@ public: | @@ -282,6 +304,7 @@ public: | ||
282 | // an integer that declares the most recent time the presentation was modified (in | 304 | // an integer that declares the most recent time the presentation was modified (in |
283 | // seconds since midnight, Jan. 1, 1904, in UTC time) | 305 | // seconds since midnight, Jan. 1, 1904, in UTC time) |
284 | uint64_t modification_time; | 306 | uint64_t modification_time; |
307 | +private: | ||
285 | // an integer that specifies the time-scale for the entire presentation; this is the number of | 308 | // an integer that specifies the time-scale for the entire presentation; this is the number of |
286 | // time units that pass in one second. For example, a time coordinate system that measures time in | 309 | // time units that pass in one second. For example, a time coordinate system that measures time in |
287 | // sixtieths of a second has a time scale of 60. | 310 | // sixtieths of a second has a time scale of 60. |
@@ -289,7 +312,7 @@ public: | @@ -289,7 +312,7 @@ public: | ||
289 | // an integer that declares length of the presentation (in the indicated timescale). This property | 312 | // an integer that declares length of the presentation (in the indicated timescale). This property |
290 | // is derived from the presentation’s tracks: the value of this field corresponds to the duration of the | 313 | // is derived from the presentation’s tracks: the value of this field corresponds to the duration of the |
291 | // longest track in the presentation. If the duration cannot be determined then duration is set to all 1s. | 314 | // longest track in the presentation. If the duration cannot be determined then duration is set to all 1s. |
292 | - uint64_t duration; | 315 | + uint64_t duration_in_tbn; |
293 | public: | 316 | public: |
294 | // a fixed point 16.16 number that indicates the preferred rate to play the presentation; 1.0 | 317 | // a fixed point 16.16 number that indicates the preferred rate to play the presentation; 1.0 |
295 | // (0x00010000) is normal forward playback | 318 | // (0x00010000) is normal forward playback |
@@ -309,12 +332,23 @@ public: | @@ -309,12 +332,23 @@ public: | ||
309 | public: | 332 | public: |
310 | SrsMp4MovieHeaderBox(); | 333 | SrsMp4MovieHeaderBox(); |
311 | virtual ~SrsMp4MovieHeaderBox(); | 334 | virtual ~SrsMp4MovieHeaderBox(); |
335 | +public: | ||
336 | + // Get the duration in ms. | ||
337 | + virtual uint64_t duration(); | ||
312 | protected: | 338 | protected: |
313 | virtual int nb_header(); | 339 | virtual int nb_header(); |
314 | virtual int encode_header(SrsBuffer* buf); | 340 | virtual int encode_header(SrsBuffer* buf); |
315 | virtual int decode_header(SrsBuffer* buf); | 341 | virtual int decode_header(SrsBuffer* buf); |
316 | }; | 342 | }; |
317 | 343 | ||
344 | +// The type of track, maybe combine of types. | ||
345 | +enum SrsMp4TrackType | ||
346 | +{ | ||
347 | + SrsMp4TrackTypeForbidden = 0x00, | ||
348 | + SrsMp4TrackTypeAudio = 0x01, | ||
349 | + SrsMp4TrackTypeVideo = 0x02, | ||
350 | +}; | ||
351 | + | ||
318 | /** | 352 | /** |
319 | * 8.3.1 Track Box (trak) | 353 | * 8.3.1 Track Box (trak) |
320 | * ISO_IEC_14496-12-base-format-2012.pdf, page 32 | 354 | * ISO_IEC_14496-12-base-format-2012.pdf, page 32 |
@@ -327,6 +361,11 @@ class SrsMp4TrackBox : public SrsMp4Box | @@ -327,6 +361,11 @@ class SrsMp4TrackBox : public SrsMp4Box | ||
327 | public: | 361 | public: |
328 | SrsMp4TrackBox(); | 362 | SrsMp4TrackBox(); |
329 | virtual ~SrsMp4TrackBox(); | 363 | virtual ~SrsMp4TrackBox(); |
364 | +public: | ||
365 | + // Get the type of track, maybe combine of track type, | ||
366 | + // for example, it maybe Audio|Video when contains both. | ||
367 | + // Generally, only single type, no combination. | ||
368 | + virtual SrsMp4TrackType track_type(); | ||
330 | }; | 369 | }; |
331 | 370 | ||
332 | /** | 371 | /** |
@@ -458,6 +497,11 @@ class SrsMp4MediaBox : public SrsMp4Box | @@ -458,6 +497,11 @@ class SrsMp4MediaBox : public SrsMp4Box | ||
458 | public: | 497 | public: |
459 | SrsMp4MediaBox(); | 498 | SrsMp4MediaBox(); |
460 | virtual ~SrsMp4MediaBox(); | 499 | virtual ~SrsMp4MediaBox(); |
500 | +public: | ||
501 | + // Get the type of track, maybe combine of track type, | ||
502 | + // for example, it maybe Audio|Video when contains both. | ||
503 | + // Generally, only single type, no combination. | ||
504 | + virtual SrsMp4TrackType track_type(); | ||
461 | }; | 505 | }; |
462 | 506 | ||
463 | /** | 507 | /** |
@@ -521,7 +565,7 @@ public: | @@ -521,7 +565,7 @@ public: | ||
521 | // an integer containing one of the following values, or a value from a derived specification: | 565 | // an integer containing one of the following values, or a value from a derived specification: |
522 | // ‘vide’, Video track | 566 | // ‘vide’, Video track |
523 | // ‘soun’, Audio track | 567 | // ‘soun’, Audio track |
524 | - uint32_t handler_type; | 568 | + SrsMp4HandlerType handler_type; |
525 | uint32_t reserved[3]; | 569 | uint32_t reserved[3]; |
526 | // a null-terminated string in UTF-8 characters which gives a human-readable name for the track | 570 | // a null-terminated string in UTF-8 characters which gives a human-readable name for the track |
527 | // type (for debugging and inspection purposes). | 571 | // type (for debugging and inspection purposes). |
-
请 注册 或 登录 后发表评论