QGMP4Box.h 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. // QGMP4Box.h
  2. // Tencent is pleased to support the open source community by making vap available.
  3. //
  4. // Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
  5. //
  6. // Licensed under the MIT License (the "License"); you may not use this file except in
  7. // compliance with the License. You may obtain a copy of the License at
  8. //
  9. // http://opensource.org/licenses/MIT
  10. //
  11. // Unless required by applicable law or agreed to in writing, software distributed under the License is
  12. // distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
  13. // either express or implied. See the License for the specific language governing permissions and
  14. // limitations under the License.
  15. #import <Foundation/Foundation.h>
  16. #define ATOM_TYPE(a, b, c, d) ((d) | ((c) << 8) | ((b) << 16) | ((unsigned)(a) << 24))
  17. #define READ32BIT(bytes) ((((bytes)[0]&0xff)<<24)+(((bytes)[1]&0xff)<<16)+(((bytes)[2]&0xff)<<8)+((bytes)[3]&0xff))
  18. extern NSInteger const kQGBoxSizeLengthInBytes;
  19. extern NSInteger const kQGBoxTypeLengthInBytes;
  20. @class QGMP4Box;
  21. typedef NSData* (^QGMp4BoxDataFetcher)(QGMP4Box *box);
  22. typedef NS_ENUM(NSUInteger, QGMP4CodecType) {
  23. QGMP4CodecTypeUnknown = 0,
  24. QGMP4CodecTypeVideo,
  25. QGMP4CodecTypeAudio
  26. };
  27. typedef NS_ENUM(uint32_t, QGMP4TrackType) {
  28. QGMP4TrackType_Video = ATOM_TYPE('v','i','d','e'),
  29. QGMP4TrackType_Audio = ATOM_TYPE('s','o','u','n'),
  30. QGMP4TrackType_Hint = ATOM_TYPE('h','i','n','t')
  31. };
  32. typedef NS_ENUM(NSUInteger, QGMP4BoxType) {
  33. QGMP4BoxType_unknown = 0x0,
  34. QGMP4BoxType_ftyp = ATOM_TYPE('f','t','y','p'),//0x66747970,
  35. QGMP4BoxType_free = ATOM_TYPE('f','r','e','e'),//0x66726565,
  36. QGMP4BoxType_mdat = ATOM_TYPE('m','d','a','t'),//0x6d646174,
  37. QGMP4BoxType_moov = ATOM_TYPE('m','o','o','v'),//0x6d6f6f76,
  38. QGMP4BoxType_mvhd = ATOM_TYPE('m','v','h','d'),//0x6d766864,
  39. QGMP4BoxType_iods = ATOM_TYPE('i','o','d','s'),//0x696f6473,
  40. QGMP4BoxType_trak = ATOM_TYPE('t','r','a','k'),//0x7472616b,
  41. QGMP4BoxType_tkhd = ATOM_TYPE('t','k','h','d'),//0x746b6864,
  42. QGMP4BoxType_edts = ATOM_TYPE('e','d','t','s'),//0x65647473,
  43. QGMP4BoxType_elst = ATOM_TYPE('e','l','s','t'),//0x656c7374,
  44. QGMP4BoxType_mdia = ATOM_TYPE('m','d','i','a'),//0x6d646961,
  45. QGMP4BoxType_mdhd = ATOM_TYPE('m','d','h','d'),//0x6d646864,
  46. QGMP4BoxType_hdlr = ATOM_TYPE('h','d','l','r'),//0x68646c72,
  47. QGMP4BoxType_minf = ATOM_TYPE('m','i','n','f'),//0x6d696e66,
  48. QGMP4BoxType_vmhd = ATOM_TYPE('v','m','h','d'),//0x766d6864,
  49. QGMP4BoxType_dinf = ATOM_TYPE('d','i','n','f'),//0x64696e66,
  50. QGMP4BoxType_dref = ATOM_TYPE('d','r','e','f'),//0x64726566,
  51. QGMP4BoxType_url = ATOM_TYPE( 0 ,'u','r','l'),//0x75726c,
  52. QGMP4BoxType_stbl = ATOM_TYPE('s','t','b','l'),//0x7374626c,
  53. QGMP4BoxType_stsd = ATOM_TYPE('s','t','s','d'),//0x73747364,
  54. QGMP4BoxType_avc1 = ATOM_TYPE('a','v','c','1'),//0x61766331,
  55. QGMP4BoxType_avcC = ATOM_TYPE('a','v','c','C'),//0x61766343,
  56. QGMP4BoxType_stts = ATOM_TYPE('s','t','t','s'),//0x73747473,
  57. QGMP4BoxType_stss = ATOM_TYPE('s','t','s','s'),//0x73747373,
  58. QGMP4BoxType_stsc = ATOM_TYPE('s','t','s','c'),//0x73747363,
  59. QGMP4BoxType_stsz = ATOM_TYPE('s','t','s','z'),//0x7374737a,
  60. QGMP4BoxType_stco = ATOM_TYPE('s','t','c','o'),//0x7374636f,
  61. QGMP4BoxType_ctts = ATOM_TYPE('c', 't', 't', 's'),//只有视频有,主要⽤来记录pts和dts的差值,通过它可以计算出pts
  62. QGMP4BoxType_udta = ATOM_TYPE('u','d','t','a'),//0x75647461,
  63. QGMP4BoxType_meta = ATOM_TYPE('m','e','t','a'),//0x6d657461,
  64. QGMP4BoxType_ilst = ATOM_TYPE('i','l','s','t'),//0x696c7374,
  65. QGMP4BoxType_data = ATOM_TYPE('d','a','t','a'),//0x64617461,
  66. QGMP4BoxType_wide = ATOM_TYPE('w','i','d','e'),//0x77696465,
  67. QGMP4BoxType_loci = ATOM_TYPE('l','o','c','i'),//0x6c6f6369,
  68. QGMP4BoxType_smhd = ATOM_TYPE('s','m','h','d'),//0x736d6864,
  69. QGMP4BoxType_vapc = ATOM_TYPE('v','a','p','c'),//0x76617063,//vap专属,存储json配置信息
  70. QGMP4BoxType_hvc1 = ATOM_TYPE('h','v','c','1'),
  71. QGMP4BoxType_hvcC = ATOM_TYPE('h','v','c','C')
  72. };
  73. typedef NS_ENUM(NSUInteger, QGMP4VideoStreamCodecID) {
  74. QGMP4VideoStreamCodecIDUnknown = 0,
  75. QGMP4VideoStreamCodecIDH264,
  76. QGMP4VideoStreamCodecIDH265
  77. };
  78. /**
  79. * QGCttsEntry
  80. */
  81. @interface QGCttsEntry : NSObject
  82. /** sampleCount */
  83. @property (nonatomic, assign) uint32_t sampleCount;
  84. /** compositionOffset */
  85. @property (nonatomic, assign) uint32_t compositionOffset;
  86. @end
  87. @interface QGMP4BoxFactory : NSObject
  88. + (BOOL)isTypeValueValid:(QGMP4BoxType)type;
  89. + (Class)boxClassForType:(QGMP4BoxType)type;
  90. + (QGMP4Box *)createBoxForType:(QGMP4BoxType)type startIndex:(unsigned long long)startIndexInBytes length:(unsigned long long)length;
  91. @end
  92. @protocol QGMP4BoxDelegate <NSObject>
  93. @optional
  94. - (void)boxDidParsed:(QGMp4BoxDataFetcher)datablock;
  95. @end
  96. @interface QGMP4Box : NSObject <QGMP4BoxDelegate>
  97. @property (nonatomic, assign) QGMP4BoxType type;
  98. @property (nonatomic, assign) unsigned long long length;
  99. @property (nonatomic, assign) unsigned long long startIndexInBytes;
  100. @property (nonatomic, weak) QGMP4Box *superBox;
  101. @property (nonatomic, strong) NSMutableArray *subBoxes;
  102. - (instancetype)initWithType:(QGMP4BoxType)type startIndex:(unsigned long long)startIndexInBytes length:(unsigned long long)length;
  103. - (id)subBoxOfType:(QGMP4BoxType)type;
  104. - (id)superBoxOfType:(QGMP4BoxType)type;
  105. @end
  106. //实际媒体数据,具体的划分等,都在moov⾥⾯。
  107. @interface QGMP4MdatBox : QGMP4Box
  108. @end
  109. @interface QGMP4AvccBox : QGMP4Box
  110. @end
  111. @interface QGMP4HvccBox : QGMP4Box
  112. @end
  113. @interface QGMP4MvhdBox : QGMP4Box
  114. @end
  115. //sample description
  116. @interface QGMP4StsdBox : QGMP4Box
  117. @end
  118. /**Samples within the media data are grouped into chunks. Chunks can be of different sizes, and the samples within a chunk can have different sizes. This table can be used to find the chunk that contains a sample, its position, and the associated sample description.
  119. The table is compactly coded. Each entry gives the index of the first chunk of a run of chunks with the same characteristics. By subtracting one entry here from the previous one, you can compute how many chunks are in this run. You can convert this to a sample count by multiplying by the appropriate samples-per-chunk.*/
  120. //https://blog.csdn.net/tung214/article/details/30492895
  121. @interface QGStscEntry : NSObject
  122. @property (nonatomic, assign) uint32_t firstChunk;
  123. @property (nonatomic, assign) uint32_t samplesPerChunk;
  124. @property (nonatomic, assign) uint32_t sampleDescriptionIndex;
  125. @end
  126. @interface QGMP4StscBox : QGMP4Box
  127. @property (nonatomic, strong) NSMutableArray<QGStscEntry *> *entries;
  128. @end
  129. @interface QGMP4StcoBox : QGMP4Box
  130. @property (nonatomic, assign) uint32_t chunkCount;
  131. @property (nonatomic, strong) NSMutableArray<NSNumber *> *chunkOffsets;
  132. @end
  133. @interface QGMP4StssBox : QGMP4Box
  134. @property(nonatomic, strong) NSMutableArray<NSNumber *> *syncSamples;
  135. @end
  136. /**
  137. * ctts
  138. */
  139. @interface QGMP4CttsBox : QGMP4Box
  140. /** compositionOffsets */
  141. @property (nonatomic, strong) NSMutableArray<NSNumber *> *compositionOffsets;
  142. @end
  143. //This box contains a compact version of a table that allows indexing from decoding time to sample number. Other tables give sample sizes and pointers, from the sample number. Each entry in the table gives the number of consecutive samples with the same time delta, and the delta of those samples. By adding the deltas a complete time-to-sample map may be built.
  144. @interface QGSttsEntry : NSObject
  145. @property (nonatomic, assign) uint32_t sampleCount;
  146. @property (nonatomic, assign) uint32_t sampleDelta;
  147. @end
  148. @interface QGMP4SttsBox : QGMP4Box
  149. @property (nonatomic, strong) NSMutableArray<QGSttsEntry *> *entries;
  150. @end
  151. //sample size
  152. @interface QGMP4StszBox : QGMP4Box
  153. @property (nonatomic, assign) uint32_t sampleCount;
  154. @property (nonatomic, strong) NSMutableArray<NSNumber *> *sampleSizes;
  155. @end
  156. @interface QGMP4TrackBox : QGMP4Box
  157. @end
  158. @interface QGMP4HdlrBox : QGMP4Box
  159. @property (nonatomic, assign) QGMP4TrackType trackType;
  160. @end
  161. @interface QGMP4Sample : NSObject
  162. @property (nonatomic, assign) QGMP4CodecType codecType;
  163. @property (nonatomic, assign) uint32_t sampleDelta;
  164. @property (nonatomic, assign) uint32_t sampleSize;
  165. @property (nonatomic, assign) uint32_t sampleIndex;
  166. @property (nonatomic, assign) uint32_t chunkIndex;
  167. @property (nonatomic, assign) uint32_t streamOffset;
  168. @property (nonatomic, assign) uint64_t pts;
  169. @property (nonatomic, assign) uint64_t dts;
  170. @property (nonatomic, assign) BOOL isKeySample;
  171. @end
  172. @interface QGChunkOffsetEntry : NSObject
  173. @property (nonatomic, assign) uint32_t samplesPerChunk;
  174. @property (nonatomic, assign) uint32_t offset;
  175. @end