H264Sei.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367
  1. /*------------------------------------------------------------------------------
  2. -- --
  3. -- This software is confidential and proprietary and may be used --
  4. -- only as expressly authorized by a licensing agreement from --
  5. -- --
  6. -- Hantro Products Oy. --
  7. -- --
  8. -- (C) COPYRIGHT 2006 HANTRO PRODUCTS OY --
  9. -- ALL RIGHTS RESERVED --
  10. -- --
  11. -- The entire notice above must be reproduced --
  12. -- on all copies and should not be removed. --
  13. -- --
  14. --------------------------------------------------------------------------------
  15. --
  16. -- Description : H.264 SEI Messages.
  17. --
  18. ------------------------------------------------------------------------------*/
  19. #include "H264Sei.h"
  20. #include "H264PutBits.h"
  21. #include "H264NalUnit.h"
  22. #include "enccommon.h"
  23. #define SEI_BUFFERING_PERIOD 0
  24. #define SEI_PIC_TIMING 1
  25. #define SEI_FILLER_PAYLOAD 3
  26. #define SEI_USER_DATA_UNREGISTERED 5
  27. /*------------------------------------------------------------------------------
  28. H264InitSei()
  29. ------------------------------------------------------------------------------*/
  30. void H264InitSei(sei_s * sei, true_e byteStream, u32 hrd, u32 timeScale,
  31. u32 nuit)
  32. {
  33. ASSERT(sei != NULL);
  34. sei->byteStream = byteStream;
  35. sei->hrd = hrd;
  36. sei->seqId = 0x0;
  37. sei->psp = (u32) ENCHW_YES;
  38. sei->cts = (u32) ENCHW_YES;
  39. /* sei->icrd = 0; */
  40. sei->icrdLen = 24;
  41. /* sei->icrdo = 0; */
  42. sei->icrdoLen = 24;
  43. /* sei->crd = 0; */
  44. sei->crdLen = 24;
  45. /* sei->dod = 0; */
  46. sei->dodLen = 24;
  47. sei->ps = 0;
  48. sei->cntType = 1;
  49. sei->cdf = 0;
  50. sei->nframes = 0;
  51. sei->toffs = 0;
  52. {
  53. u32 n = 1;
  54. while(nuit > (1U << n))
  55. n++;
  56. sei->toffsLen = n;
  57. }
  58. sei->ts.timeScale = timeScale;
  59. sei->ts.nuit = nuit;
  60. sei->ts.time = 0;
  61. sei->ts.sec = 0;
  62. sei->ts.min = 0;
  63. sei->ts.hr = 0;
  64. sei->ts.fts = (u32) ENCHW_YES;
  65. sei->ts.secf = (u32) ENCHW_NO;
  66. sei->ts.minf = (u32) ENCHW_NO;
  67. sei->ts.hrf = (u32) ENCHW_NO;
  68. sei->userDataEnabled = (u32) ENCHW_NO;
  69. sei->userDataSize = 0;
  70. sei->pUserData = NULL;
  71. }
  72. /*------------------------------------------------------------------------------
  73. H264UpdateSeiTS() Calculate new time stamp.
  74. ------------------------------------------------------------------------------*/
  75. void H264UpdateSeiTS(sei_s * sei, u32 timeInc)
  76. {
  77. timeStamp_s *ts = &sei->ts;
  78. ASSERT(sei != NULL);
  79. timeInc += ts->time;
  80. while(timeInc >= ts->timeScale)
  81. {
  82. timeInc -= ts->timeScale;
  83. ts->sec++;
  84. if(ts->sec == 60)
  85. {
  86. ts->sec = 0;
  87. ts->min++;
  88. if(ts->min == 60)
  89. {
  90. ts->min = 0;
  91. ts->hr++;
  92. if(ts->hr == 32)
  93. {
  94. ts->hr = 0;
  95. }
  96. }
  97. }
  98. }
  99. ts->time = timeInc;
  100. sei->nframes = ts->time / ts->nuit;
  101. sei->toffs = ts->time - sei->nframes * ts->nuit;
  102. ts->hrf = (ts->hr != 0);
  103. ts->minf = ts->hrf || (ts->min != 0);
  104. ts->secf = ts->minf || (ts->sec != 0);
  105. #ifdef TRACE_PIC_TIMING
  106. DEBUG_PRINT(("Picture Timing: %02i:%02i:%02i %6i ticks\n", ts->hr, ts->min,
  107. ts->sec, (sei->nframes * ts->nuit + sei->toffs)));
  108. #endif
  109. }
  110. /*------------------------------------------------------------------------------
  111. H264FillerSei() Filler payload SEI message. Requested filler payload size
  112. could be huge. Use of temporary stream buffer is not needed, because size is
  113. know.
  114. ------------------------------------------------------------------------------*/
  115. void H264FillerSei(stream_s * sp, sei_s * sei, i32 cnt)
  116. {
  117. i32 i = cnt;
  118. ASSERT(sp != NULL && sei != NULL);
  119. H264NalUnitHdr(sp, 0, SEI, sei->byteStream);
  120. H264NalBits(sp, SEI_FILLER_PAYLOAD, 8);
  121. COMMENT("last_payload_type_byte");
  122. while(cnt >= 255)
  123. {
  124. H264NalBits(sp, 0xFF, 0x8);
  125. COMMENT("ff_byte");
  126. cnt -= 255;
  127. }
  128. H264NalBits(sp, cnt, 8);
  129. COMMENT("last_payload_size_byte");
  130. for(; i > 0; i--)
  131. {
  132. H264NalBits(sp, 0xFF, 8);
  133. COMMENT("filler ff_byte");
  134. }
  135. H264RbspTrailingBits(sp);
  136. }
  137. /*------------------------------------------------------------------------------
  138. H264BufferingSei() Buffering period SEI message.
  139. ------------------------------------------------------------------------------*/
  140. void H264BufferingSei(stream_s * sp, sei_s * sei)
  141. {
  142. u8 *pPayloadSizePos;
  143. u32 startByteCnt;
  144. ASSERT(sei != NULL);
  145. if(sei->hrd == ENCHW_NO)
  146. {
  147. return;
  148. }
  149. H264NalBits(sp, SEI_BUFFERING_PERIOD, 8);
  150. COMMENT("last_payload_type_byte");
  151. pPayloadSizePos = sp->stream;
  152. H264NalBits(sp, 0xFF, 8); /* this will be updated after we know exact payload size */
  153. COMMENT("last_payload_size_byte");
  154. startByteCnt = sp->byteCnt;
  155. sp->emulCnt = 0; /* count emul_3_byte for this payload */
  156. H264ExpGolombUnsigned(sp, sei->seqId);
  157. COMMENT("seq_parameter_set_id");
  158. H264NalBits(sp, sei->icrd, sei->icrdLen);
  159. COMMENT("initial_cpb_removal_delay");
  160. H264NalBits(sp, sei->icrdo, sei->icrdoLen);
  161. COMMENT("initial_cpb_removal_delay_offset");
  162. if(sp->bufferedBits)
  163. {
  164. H264RbspTrailingBits(sp);
  165. }
  166. {
  167. u32 payload_size;
  168. payload_size = sp->byteCnt - startByteCnt - sp->emulCnt;
  169. *pPayloadSizePos = payload_size;
  170. }
  171. /* reset cpb_removal_delay */
  172. sei->crd = 0;
  173. }
  174. /*------------------------------------------------------------------------------
  175. TimeStamp()
  176. ------------------------------------------------------------------------------*/
  177. static void TimeStamp(stream_s * sp, timeStamp_s * ts)
  178. {
  179. if(ts->fts)
  180. {
  181. H264NalBits(sp, ts->sec, 6);
  182. COMMENT("seconds_value");
  183. H264NalBits(sp, ts->min, 6);
  184. COMMENT("minutes_value");
  185. H264NalBits(sp, ts->hr, 5);
  186. COMMENT("hours_value");
  187. }
  188. else
  189. {
  190. H264NalBits(sp, ts->secf, 1);
  191. COMMENT("seconds_flag");
  192. if(ts->secf)
  193. {
  194. H264NalBits(sp, ts->sec, 6);
  195. COMMENT("seconds_value");
  196. H264NalBits(sp, ts->minf, 1);
  197. COMMENT("minutes_flag");
  198. if(ts->minf)
  199. {
  200. H264NalBits(sp, ts->min, 6);
  201. COMMENT("minutes_value");
  202. H264NalBits(sp, ts->hrf, 1);
  203. COMMENT("hours_flag");
  204. if(ts->hrf)
  205. {
  206. H264NalBits(sp, ts->hr, 5);
  207. COMMENT("hours_value");
  208. }
  209. }
  210. }
  211. }
  212. }
  213. /*------------------------------------------------------------------------------
  214. H264PicTimingSei() Picture timing SEI message.
  215. ------------------------------------------------------------------------------*/
  216. void H264PicTimingSei(stream_s * sp, sei_s * sei)
  217. {
  218. u8 *pPayloadSizePos;
  219. u32 startByteCnt;
  220. ASSERT(sei != NULL);
  221. H264NalBits(sp, SEI_PIC_TIMING, 8);
  222. COMMENT("last_payload_type_byte");
  223. pPayloadSizePos = sp->stream;
  224. H264NalBits(sp, 0xFF, 8); /* this will be updated after we know exact payload size */
  225. COMMENT("last_payload_size_byte");
  226. startByteCnt = sp->byteCnt;
  227. sp->emulCnt = 0; /* count emul_3_byte for this payload */
  228. if(sei->hrd)
  229. {
  230. H264NalBits(sp, sei->crd, sei->crdLen);
  231. COMMENT("cpb_removal_delay");
  232. H264NalBits(sp, sei->dod, sei->dodLen);
  233. COMMENT("dpb_output_delay");
  234. }
  235. if(sei->psp)
  236. {
  237. H264NalBits(sp, sei->ps, 4);
  238. COMMENT("pic_struct");
  239. H264NalBits(sp, sei->cts, 1);
  240. COMMENT("clock_timestamp_flag");
  241. if(sei->cts)
  242. {
  243. H264NalBits(sp, 0, 2);
  244. COMMENT("ct_type");
  245. H264NalBits(sp, 0, 1);
  246. COMMENT("nuit_field_based_flag");
  247. H264NalBits(sp, sei->cntType, 5);
  248. COMMENT("counting_type");
  249. H264NalBits(sp, sei->ts.fts, 1);
  250. COMMENT("full_timestamp_flag");
  251. H264NalBits(sp, 0, 1);
  252. COMMENT("discontinuity_flag");
  253. H264NalBits(sp, sei->cdf, 1);
  254. COMMENT("cnt_dropped_flag");
  255. H264NalBits(sp, sei->nframes, 8);
  256. COMMENT("n_frames");
  257. TimeStamp(sp, &sei->ts);
  258. if(sei->toffsLen > 0)
  259. {
  260. H264NalBits(sp, sei->toffs, sei->toffsLen);
  261. COMMENT("time_offset");
  262. }
  263. }
  264. }
  265. if(sp->bufferedBits)
  266. {
  267. H264RbspTrailingBits(sp);
  268. }
  269. {
  270. u32 payload_size;
  271. payload_size = sp->byteCnt - startByteCnt - sp->emulCnt;
  272. *pPayloadSizePos = payload_size;
  273. }
  274. }
  275. /*------------------------------------------------------------------------------
  276. H264UserDataUnregSei() User data unregistered SEI message.
  277. ------------------------------------------------------------------------------*/
  278. void H264UserDataUnregSei(stream_s * sp, sei_s * sei)
  279. {
  280. u32 i, cnt;
  281. const u8 * pUserData;
  282. ASSERT(sei != NULL);
  283. ASSERT(sei->pUserData != NULL);
  284. ASSERT(sei->userDataSize >= 16);
  285. pUserData = sei->pUserData;
  286. cnt = sei->userDataSize;
  287. if(sei->userDataEnabled == ENCHW_NO)
  288. {
  289. return;
  290. }
  291. H264NalBits(sp, SEI_USER_DATA_UNREGISTERED, 8);
  292. COMMENT("last_payload_type_byte");
  293. while(cnt >= 255)
  294. {
  295. H264NalBits(sp, 0xFF, 0x8);
  296. COMMENT("ff_byte");
  297. cnt -= 255;
  298. }
  299. H264NalBits(sp, cnt, 8);
  300. COMMENT("last_payload_size_byte");
  301. /* Write uuid */
  302. for (i = 0; i < 16; i++)
  303. {
  304. H264NalBits(sp, pUserData[i], 8);
  305. COMMENT("uuid_iso_iec_11578_byte");
  306. }
  307. /* Write payload */
  308. for (i = 16; i < sei->userDataSize; i++)
  309. {
  310. H264NalBits(sp, pUserData[i], 8);
  311. COMMENT("user_data_payload_byte");
  312. }
  313. }