您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

132 行
4.7 KiB

  1. using JT1078.FMp4.Interfaces;
  2. using JT1078.FMp4.MessagePack;
  3. using System;
  4. using System.Collections.Generic;
  5. using System.Text;
  6. namespace JT1078.FMp4
  7. {
  8. /// <summary>
  9. /// trun
  10. /// </summary>
  11. public class TrackRunBox : FullBox, IFMp4MessagePackFormatter
  12. {
  13. /// <summary>
  14. /// trun
  15. /// 201 205 1
  16. /// 201 0010 0000 0001
  17. /// 205 0010 0000 0101
  18. /// 1 0000 0000 0001
  19. /// tr_flags 是用来表示下列 sample 相关的标识符是否应用到每个字段中:
  20. /// 0x000001-0000 0000 0001: data-offset-present,只应用 data-offset
  21. /// 0x000004-0000 0000 0100: 只对第一个 sample 应用对应的 flags。剩余 sample flags 就不管了。
  22. /// 0x000100-0001 0000 0000: 这个比较重要,表示每个 sample 都有自己的 duration,否则使用默认的
  23. /// 0x000200-0010 0000 0000: 每个 sample 有自己的 sample_size,否则使用默认的。
  24. /// 0x000400-0100 0000 0000: 对每个 sample 使用自己的 flags。否则,使用默认的。
  25. /// 0x000800-1000 0000 0000: 每个 sample 都有自己的 cts 值
  26. /// 0x000f01-1111 0000 0001
  27. /// </summary>
  28. /// <param name="version"></param>
  29. /// <param name="flags"></param>
  30. public TrackRunBox(byte version=0, uint flags= 0x000f01) : base("trun", version, flags)
  31. {
  32. }
  33. /// <summary>
  34. ///
  35. /// </summary>
  36. public uint SampleCount { get; set; }
  37. /// <summary>
  38. /// 可选的
  39. /// 用来表示和该moof配套的mdat中实际数据内容距moof开头有多少byte
  40. /// 相当于就是 moof.byteLength + mdat.headerSize(8)
  41. /// </summary>
  42. public int DataOffset { get; set; }
  43. /// <summary>
  44. /// 可选的
  45. /// </summary>
  46. public uint FirstSampleFlags { get; set; }
  47. /// <summary>
  48. /// 可选的
  49. /// length:SampleCount
  50. /// </summary>
  51. public List<TrackRunInfo> TrackRunInfos { get; set; }
  52. public void ToBuffer(ref FMp4MessagePackWriter writer)
  53. {
  54. Start(ref writer);
  55. WriterFullBoxToBuffer(ref writer);
  56. bool tmpFlag = TrackRunInfos != null && TrackRunInfos.Count > 0;
  57. if (tmpFlag)
  58. {
  59. writer.WriteUInt32((uint)TrackRunInfos.Count);
  60. }
  61. else
  62. {
  63. writer.WriteUInt32(0);
  64. }
  65. if((Flags & FMp4Constants.TRUN_FLAG_DATA_OFFSET_PRESENT) > 0)
  66. {
  67. if (DataOffset > 0)
  68. {
  69. //人工
  70. writer.WriteInt32(DataOffset);
  71. }
  72. else
  73. {
  74. //程序自动计算
  75. writer.CreateTrunOffsetPosition();
  76. writer.Skip(4, out _);
  77. }
  78. }
  79. if ((Flags & FMp4Constants.TRUN_FLAG_FIRST_SAMPLE_FLAGS_PRESENT) > 0)
  80. {
  81. writer.WriteUInt32(FirstSampleFlags);
  82. }
  83. if (tmpFlag)
  84. {
  85. foreach(var trun in TrackRunInfos)
  86. {
  87. if ((Flags & FMp4Constants.TRUN_FLAG_SAMPLE_DURATION_PRESENT) > 0)
  88. {
  89. writer.WriteUInt32(trun.SampleDuration);
  90. }
  91. if ((Flags & FMp4Constants.TRUN_FLAG_SAMPLE_SIZE_PRESENT) > 0)
  92. {
  93. writer.WriteUInt32(trun.SampleSize);
  94. }
  95. if ((Flags & FMp4Constants.TRUN_FLAG_SAMPLE_FLAGS_PRESENT) > 0)
  96. {
  97. writer.WriteUInt32(trun.SampleFlags);
  98. }
  99. if ((Flags & FMp4Constants.TRUN_FLAG_SAMPLE_COMPOSITION_TIME_OFFSET_PRESENT) > 0)
  100. {
  101. if (Version == 0)
  102. {
  103. writer.WriteUInt32((uint)trun.SampleCompositionTimeOffset);
  104. }
  105. else
  106. {
  107. writer.WriteInt32((int)trun.SampleCompositionTimeOffset);
  108. }
  109. }
  110. }
  111. }
  112. End(ref writer);
  113. }
  114. public class TrackRunInfo
  115. {
  116. public uint SampleDuration { get; set; }
  117. public uint SampleSize { get; set; }
  118. public uint SampleFlags { get; set; }
  119. /// <summary>
  120. /// cts
  121. /// version == 0
  122. /// 0:uint
  123. /// >0:int
  124. /// </summary>
  125. public long SampleCompositionTimeOffset { get; set; }
  126. }
  127. }
  128. }