h264_mp4_decoder.cpp 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. #include "h264_mp4_decoder.h"
  2. #include "../winamp/wa_ipc.h"
  3. #include <Mferror.h>
  4. uint32_t Read24(const uint8_t *data)
  5. {
  6. // ugh, 24bit size
  7. uint32_t this_size=0;
  8. uint8_t *this_size_p = (uint8_t *)&this_size;
  9. this_size_p[0] = data[2];
  10. this_size_p[1] = data[1];
  11. this_size_p[2] = data[0];
  12. return this_size;
  13. }
  14. uint32_t GetNALUSize(uint64_t nalu_size_bytes, const uint8_t *h264_data, size_t data_len)
  15. {
  16. if ((data_len) < (nalu_size_bytes))
  17. return 0;
  18. switch(nalu_size_bytes)
  19. {
  20. case 1:
  21. return *h264_data;
  22. case 2:
  23. {
  24. return (h264_data[0] << 8) | h264_data[1];
  25. }
  26. case 3:
  27. {
  28. return Read24(h264_data);
  29. }
  30. case 4:
  31. {
  32. uint32_t this_size = *(uint32_t *)h264_data;
  33. this_size = htonl(this_size);
  34. return this_size;
  35. }
  36. }
  37. return 0;
  38. }
  39. H264MP4Decoder::H264MP4Decoder()
  40. {
  41. nalu_size_bytes=0;
  42. width=0;
  43. height=0;
  44. }
  45. H264MP4Decoder::~H264MP4Decoder()
  46. {
  47. for (size_t i=0;i<buffered_frames.size();i++) {
  48. nullsoft_h264_frame_data frame_data = buffered_frames[i];
  49. decoder.FreeFrame((YV12_PLANES *)frame_data.data, frame_data.decoder_data);
  50. }
  51. }
  52. int H264MP4Decoder::Open(MP4FileHandle mp4_file, MP4TrackId mp4_track)
  53. {
  54. this->mp4_file=mp4_file;
  55. this->mp4_track=mp4_track;
  56. decoder.Open();
  57. // TODO error checking
  58. uint8_t **seqHeaders = 0, **pictHeaders = 0;
  59. uint32_t *seqHeadersSize = 0, *pictHeadersSize = 0;
  60. __try
  61. {
  62. MP4GetTrackH264SeqPictHeaders(mp4_file, mp4_track,
  63. &seqHeaders, &seqHeadersSize,
  64. &pictHeaders, &pictHeadersSize);
  65. if (seqHeadersSize)
  66. {
  67. for (uint32_t i = 0; seqHeadersSize[i] != 0; i++)
  68. {
  69. decoder.Feed(seqHeaders[i], seqHeadersSize[i], 0);
  70. MP4Free(seqHeaders[i]);
  71. }
  72. }
  73. MP4Free(seqHeadersSize);
  74. if (pictHeadersSize)
  75. {
  76. for (uint32_t i = 0; pictHeadersSize[i] != 0; i++)
  77. {
  78. decoder.Feed(pictHeaders[i], pictHeadersSize[i], 0);
  79. MP4Free(pictHeaders[i]);
  80. }
  81. }
  82. MP4Free(pictHeadersSize);
  83. MP4GetTrackH264LengthSize(mp4_file, mp4_track, &nalu_size_bytes);
  84. }
  85. __except(EXCEPTION_EXECUTE_HANDLER)
  86. {
  87. return MP4_VIDEO_FAILURE;
  88. }
  89. return MP4_VIDEO_SUCCESS;
  90. }
  91. int H264MP4Decoder::GetOutputFormat(int *x, int *y, int *color_format, double *aspect_ratio)
  92. {
  93. bool flip;
  94. if (SUCCEEDED(decoder.GetOutputFormat(&width, &height, &flip, aspect_ratio))) {
  95. *x = width;
  96. *y = height;
  97. *color_format = htonl('YV12');
  98. return MP4_VIDEO_SUCCESS;
  99. }
  100. return MP4_VIDEO_FAILURE;
  101. }
  102. int H264MP4Decoder::DecodeSample(const void *inputBuffer, size_t inputBufferBytes, MP4Timestamp timestamp)
  103. {
  104. const uint8_t *h264_data = (const uint8_t *)inputBuffer;
  105. while (inputBufferBytes)
  106. {
  107. uint32_t this_size =GetNALUSize(nalu_size_bytes, h264_data, inputBufferBytes);
  108. if (this_size == 0)
  109. return MP4_VIDEO_FAILURE;
  110. inputBufferBytes-=nalu_size_bytes;
  111. h264_data+=nalu_size_bytes;
  112. if (this_size > inputBufferBytes)
  113. return MP4_VIDEO_FAILURE;
  114. for (;;) {
  115. uint64_t hundrednanos = MP4ConvertFromTrackTimestamp(mp4_file, mp4_track, timestamp, MP4_NANOSECONDS_TIME_SCALE/100ULL);
  116. HRESULT hr = decoder.Feed(h264_data, this_size, hundrednanos);
  117. if (hr == MF_E_NOTACCEPTING) {
  118. nullsoft_h264_frame_data frame_data;
  119. if (FAILED(decoder.GetFrame((YV12_PLANES **)&frame_data.data, &frame_data.decoder_data, &frame_data.local_timestamp))) {
  120. continue;
  121. }
  122. buffered_frames.push_back(frame_data);
  123. } else if (FAILED(hr)) {
  124. return MP4_VIDEO_FAILURE;
  125. } else {
  126. break;
  127. }
  128. }
  129. inputBufferBytes-=this_size;
  130. h264_data+=this_size;
  131. }
  132. return MP4_VIDEO_SUCCESS;
  133. }
  134. int H264MP4Decoder::CanHandleCodec(const char *codecName)
  135. {
  136. return !strcmp(codecName, "avc1");
  137. }
  138. void H264MP4Decoder::Flush()
  139. {
  140. for (size_t i=0;i<buffered_frames.size();i++) {
  141. nullsoft_h264_frame_data frame_data = buffered_frames[i];
  142. decoder.FreeFrame((YV12_PLANES *)frame_data.data, frame_data.decoder_data);
  143. }
  144. decoder.Flush();
  145. }
  146. int H264MP4Decoder::GetPicture(void **data, void **decoder_data, MP4Timestamp *timestamp)
  147. {
  148. if (!buffered_frames.empty()) {
  149. nullsoft_h264_frame_data frame_data = buffered_frames[0];
  150. buffered_frames.erase(buffered_frames.begin());
  151. *data = frame_data.data;
  152. *decoder_data = frame_data.decoder_data;
  153. *timestamp = MP4ConvertToTrackTimestamp(mp4_file, mp4_track, frame_data.local_timestamp, MP4_NANOSECONDS_TIME_SCALE/100ULL);
  154. return MP4_VIDEO_SUCCESS;
  155. }
  156. uint64_t local_timestamp;
  157. if (SUCCEEDED(decoder.GetFrame((YV12_PLANES **)data, decoder_data, &local_timestamp))) {
  158. *timestamp = MP4ConvertToTrackTimestamp(mp4_file, mp4_track, local_timestamp, MP4_NANOSECONDS_TIME_SCALE/100ULL);
  159. return MP4_VIDEO_SUCCESS;
  160. } else {
  161. return MP4_VIDEO_FAILURE;
  162. }
  163. }
  164. void H264MP4Decoder::FreePicture(void *data, void *decoder_data)
  165. {
  166. decoder.FreeFrame((YV12_PLANES *)data, decoder_data);
  167. }
  168. void H264MP4Decoder::HurryUp(int state)
  169. {
  170. // TODO if (decoder)
  171. //H264_HurryUp(decoder, state);
  172. }
  173. #define CBCLASS H264MP4Decoder
  174. START_DISPATCH;
  175. CB(MPEG4_VIDEO_OPEN, Open)
  176. CB(MPEG4_VIDEO_GETOUTPUTFORMAT, GetOutputFormat)
  177. CB(MPEG4_VIDEO_DECODE, DecodeSample)
  178. CB(MPEG4_VIDEO_HANDLES_CODEC, CanHandleCodec)
  179. VCB(MPEG4_VIDEO_FLUSH, Flush)
  180. CB(MPEG4_VIDEO_GET_PICTURE, GetPicture)
  181. VCB(MPEG4_VIDEO_FREE_PICTURE, FreePicture)
  182. VCB(MPEG4_VIDEO_HURRY_UP, HurryUp)
  183. END_DISPATCH;
  184. #undef CBCLASS