atom_avcC.cpp 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  1. /*
  2. * The contents of this file are subject to the Mozilla Public
  3. * License Version 1.1 (the "License"); you may not use this file
  4. * except in compliance with the License. You may obtain a copy of
  5. * the License at http://www.mozilla.org/MPL/
  6. *
  7. * Software distributed under the License is distributed on an "AS
  8. * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
  9. * implied. See the License for the specific language governing
  10. * rights and limitations under the License.
  11. *
  12. * The Original Code is MPEG4IP.
  13. *
  14. * The Initial Developer of the Original Code is Cisco Systems Inc.
  15. * Portions created by Cisco Systems Inc. are
  16. * Copyright (C) Cisco Systems Inc. 2004. All Rights Reserved.
  17. *
  18. * Contributor(s):
  19. * Bill May [email protected]
  20. */
  21. #include "mp4common.h"
  22. /*
  23. * SizeTableProperty is a special version of the MP4TableProperty -
  24. * the BytesProperty will need to set the value before it can read
  25. * from the file
  26. */
  27. class SizeTableProperty : public MP4TableProperty
  28. {
  29. public:
  30. SizeTableProperty(char *name, MP4IntegerProperty *pCountProperty) :
  31. MP4TableProperty(name, pCountProperty) {};
  32. protected:
  33. void ReadEntry(MP4File *pFile, u_int32_t index) {
  34. // Each table has a size, followed by the length field
  35. // first, read the length
  36. m_pProperties[0]->Read(pFile, index);
  37. MP4IntegerProperty *pIntProp = (MP4IntegerProperty *)m_pProperties[0];
  38. // set the size in the bytes property
  39. MP4BytesProperty *pBytesProp = (MP4BytesProperty *)m_pProperties[1];
  40. pBytesProp->SetValueSize(pIntProp->GetValue(index), index);
  41. // And read the bytes
  42. m_pProperties[1]->Read(pFile, index);
  43. };
  44. };
  45. MP4AvcCAtom::MP4AvcCAtom()
  46. : MP4Atom("avcC")
  47. {
  48. MP4BitfieldProperty *pCount;
  49. MP4TableProperty *pTable;
  50. AddProperty( new MP4Integer8Property("configurationVersion")); /* 0 */
  51. AddProperty( new MP4Integer8Property("AVCProfileIndication")); /* 1 */
  52. AddProperty( new MP4Integer8Property("profile_compatibility")); /* 2 */
  53. AddProperty( new MP4Integer8Property("AVCLevelIndication")); /* 3 */
  54. AddProperty( new MP4BitfieldProperty("reserved", 6)); /* 4 */
  55. AddProperty( new MP4BitfieldProperty("lengthSizeMinusOne", 2)); /* 5 */
  56. AddProperty( new MP4BitfieldProperty("reserved1", 3)); /* 6 */
  57. pCount = new MP4BitfieldProperty("numOfSequenceParameterSets", 5);
  58. AddProperty(pCount); /* 7 */
  59. pTable = new SizeTableProperty("sequenceEntries", pCount);
  60. AddProperty(pTable); /* 8 */
  61. pTable->AddProperty(new MP4Integer16Property("sequenceParameterSetLength"));
  62. pTable->AddProperty(new MP4BytesProperty("sequenceParameterSetNALUnit"));
  63. MP4Integer8Property *pCount2 = new MP4Integer8Property("numOfPictureParameterSets");
  64. AddProperty(pCount2); /* 9 */
  65. pTable = new SizeTableProperty("pictureEntries", pCount2);
  66. AddProperty(pTable); /* 10 */
  67. pTable->AddProperty(new MP4Integer16Property("pictureParameterSetLength"));
  68. pTable->AddProperty(new MP4BytesProperty("pictureParameterSetNALUnit"));
  69. }
  70. void MP4AvcCAtom::Generate()
  71. {
  72. MP4Atom::Generate();
  73. ((MP4Integer8Property*)m_pProperties[0])->SetValue(1);
  74. m_pProperties[4]->SetReadOnly(false);
  75. ((MP4BitfieldProperty*)m_pProperties[4])->SetValue(0x3f);
  76. m_pProperties[4]->SetReadOnly(true);
  77. m_pProperties[6]->SetReadOnly(false);
  78. ((MP4BitfieldProperty*)m_pProperties[6])->SetValue(0x7);
  79. m_pProperties[6]->SetReadOnly(true);
  80. #if 0
  81. // property reserved4 has non-zero fixed values
  82. static u_int8_t reserved4[4] = {
  83. 0x00, 0x18, 0xFF, 0xFF,
  84. };
  85. m_pProperties[7]->SetReadOnly(false);
  86. ((MP4BytesProperty*)m_pProperties[7])->
  87. SetValue(reserved4, sizeof(reserved4));
  88. m_pProperties[7]->SetReadOnly(true);
  89. #endif
  90. }
  91. //
  92. // Clone - clone my properties to destination atom
  93. //
  94. // this method simplifies duplicating avcC atom properties from
  95. // source to destination file using a single API rather than
  96. // having to copy each property. This API encapsulates the object
  97. // so the application layer need not concern with each property
  98. // thereby isolating any future changes to atom properties.
  99. //
  100. // ----------------------------------------
  101. // property description
  102. // ----------------------------------------
  103. //
  104. // 0 configurationVersion
  105. // 1 AVCProfileIndication
  106. // 2 profile_compatibility
  107. // 3 AVCLevelIndication
  108. // 4 reserved
  109. // 5 lengthSizeMinusOne
  110. // 6 reserved
  111. // 7 number of SPS
  112. // 8 SPS entries
  113. // 9 number of PPS
  114. // 10 PPS entries
  115. //
  116. //
  117. void MP4AvcCAtom::Clone(MP4AvcCAtom *dstAtom)
  118. {
  119. MP4Property *dstProperty;
  120. MP4TableProperty *pTable;
  121. u_int16_t i16;
  122. u_int64_t i32;
  123. u_int64_t i64;
  124. u_int8_t *tmp;
  125. // source pointer Property I16
  126. MP4Integer16Property *spPI16;
  127. // source pointer Property Bytes
  128. MP4BytesProperty *spPB;
  129. // dest pointer Property I16
  130. MP4Integer16Property *dpPI16;
  131. // dest pointer Property Bytes
  132. MP4BytesProperty *dpPB;
  133. // start with defaults and reserved fields
  134. dstAtom->Generate();
  135. // 0, 4, 6 are now generated from defaults
  136. // leaving 1, 2, 3, 5, 7, 8, 9, 10 to export
  137. dstProperty=dstAtom->GetProperty(1);
  138. ((MP4Integer8Property *)dstProperty)->SetValue(
  139. ((MP4Integer8Property *)m_pProperties[1])->GetValue());
  140. dstProperty=dstAtom->GetProperty(2);
  141. ((MP4Integer8Property *)dstProperty)->SetValue(
  142. ((MP4Integer8Property *)m_pProperties[2])->GetValue());
  143. dstProperty=dstAtom->GetProperty(3);
  144. ((MP4Integer8Property *)dstProperty)->SetValue(
  145. ((MP4Integer8Property *)m_pProperties[3])->GetValue());
  146. dstProperty=dstAtom->GetProperty(5);
  147. ((MP4BitfieldProperty *)dstProperty)->SetValue(
  148. ((MP4BitfieldProperty *)m_pProperties[5])->GetValue());
  149. //
  150. // 7 and 8 are related SPS (one set of sequence parameters)
  151. //
  152. // first the count bitfield
  153. //
  154. dstProperty=dstAtom->GetProperty(7);
  155. dstProperty->SetReadOnly(false);
  156. ((MP4BitfieldProperty *)dstProperty)->SetValue(
  157. ((MP4BitfieldProperty *)m_pProperties[7])->GetValue());
  158. dstProperty->SetReadOnly(true);
  159. // next export SPS Length and NAL bytes */
  160. // first source pointers
  161. pTable = (MP4TableProperty *) m_pProperties[8];
  162. spPI16 = (MP4Integer16Property *)pTable->GetProperty(0);
  163. spPB = (MP4BytesProperty *)pTable->GetProperty(1);
  164. // now dest pointers
  165. dstProperty=dstAtom->GetProperty(8);
  166. pTable = (MP4TableProperty *) dstProperty;
  167. dpPI16 = (MP4Integer16Property *)pTable->GetProperty(0);
  168. dpPB = (MP4BytesProperty *)pTable->GetProperty(1);
  169. // sps length
  170. i16 = spPI16->GetValue();
  171. i64 = i16;
  172. // FIXME - this leaves m_maxNumElements =2
  173. // but src atom m_maxNumElements is 1
  174. dpPI16->InsertValue(i64, 0);
  175. // export byte array
  176. i32 = i16;
  177. // copy bytes to local buffer
  178. tmp = (u_int8_t *)MP4Malloc(i32);
  179. ASSERT(tmp != NULL);
  180. spPB->CopyValue(tmp, 0);
  181. // set element count
  182. dpPB->SetCount(1);
  183. // copy bytes
  184. dpPB->SetValue(tmp, i32, 0);
  185. MP4Free((void *)tmp);
  186. //
  187. // 9 and 10 are related PPS (one set of picture parameters)
  188. //
  189. // first the integer8 count
  190. //
  191. dstProperty=dstAtom->GetProperty(9);
  192. dstProperty->SetReadOnly(false);
  193. ((MP4Integer8Property *)dstProperty)->SetValue(
  194. ((MP4Integer8Property *)m_pProperties[9])->GetValue());
  195. dstProperty->SetReadOnly(true);
  196. // next export PPS Length and NAL bytes */
  197. // first source pointers
  198. pTable = (MP4TableProperty *) m_pProperties[10];
  199. spPI16 = (MP4Integer16Property *)pTable->GetProperty(0);
  200. spPB = (MP4BytesProperty *)pTable->GetProperty(1);
  201. // now dest pointers
  202. dstProperty=dstAtom->GetProperty(10);
  203. pTable = (MP4TableProperty *) dstProperty;
  204. dpPI16 = (MP4Integer16Property *)pTable->GetProperty(0);
  205. dpPB = (MP4BytesProperty *)pTable->GetProperty(1);
  206. // pps length
  207. i16 = spPI16->GetValue();
  208. i64 = i16;
  209. dpPI16->InsertValue(i64, 0);
  210. // export byte array
  211. i32 = i16;
  212. // copy bytes to local buffer
  213. tmp = (u_int8_t *)MP4Malloc(i32);
  214. ASSERT(tmp != NULL);
  215. spPB->CopyValue(tmp, 0);
  216. // set element count
  217. dpPB->SetCount(1);
  218. // copy bytes
  219. dpPB->SetValue(tmp, i32, 0);
  220. MP4Free((void *)tmp);
  221. }