1
0

h264_mkv_decoder.cpp 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. #include "h264_mkv_decoder.h"
  2. #include "../Winamp/wa_ipc.h" // for YV12_PLANES
  3. #include <winsock.h>
  4. #include <mmsystem.h>
  5. #include <Mferror.h>
  6. int MKVDecoderCreator::CreateVideoDecoder(const char *codec_id, const nsmkv::TrackEntryData *track_entry_data, const nsmkv::VideoData *video_data, ifc_mkvvideodecoder **decoder)
  7. {
  8. if (!strcmp(codec_id, "V_MPEG4/ISO/AVC"))
  9. {
  10. const uint8_t *init_data = (const uint8_t *)track_entry_data->codec_private;
  11. size_t init_data_len = track_entry_data->codec_private_len;
  12. if (init_data && init_data_len >= 6)
  13. {
  14. MFTDecoder *ctx = new MFTDecoder;
  15. if (!ctx)
  16. return CREATEDECODER_FAILURE;
  17. if (FAILED(ctx->Open())) {
  18. delete ctx;
  19. return CREATEDECODER_FAILURE;
  20. }
  21. init_data+=4; // don't care about level & profile
  22. init_data_len-=4;
  23. // read NALU header size length
  24. uint8_t nalu_minus_one = *init_data++ & 0x3;
  25. init_data_len--;
  26. // number of SPS NAL units
  27. uint8_t num_sps = *init_data++ & 0x1F;
  28. init_data_len--;
  29. for (uint8_t i=0;i!=num_sps;i++)
  30. {
  31. if (init_data_len < 2)
  32. {
  33. delete ctx;
  34. return CREATEDECODER_FAILURE;
  35. }
  36. uint16_t *s = (uint16_t *)init_data;
  37. uint16_t sps_size = htons(*s);
  38. init_data+=2;
  39. init_data_len-=2;
  40. if (init_data_len < sps_size)
  41. {
  42. delete ctx;
  43. return CREATEDECODER_FAILURE;
  44. }
  45. ctx->Feed(init_data, sps_size, 0);
  46. init_data+=sps_size;
  47. init_data_len-=sps_size;
  48. }
  49. // read PPS NAL units
  50. if (init_data_len)
  51. {
  52. // number of PPS NAL units
  53. uint8_t num_pps = *init_data++ & 0x1F;
  54. init_data_len--;
  55. for (uint8_t i=0;i!=num_pps;i++)
  56. {
  57. if (init_data_len < 2)
  58. {
  59. delete ctx;
  60. return CREATEDECODER_FAILURE;
  61. }
  62. uint16_t *s = (uint16_t *)init_data;
  63. uint16_t pps_size = htons(*s);
  64. init_data+=2;
  65. init_data_len-=2;
  66. if (init_data_len < pps_size)
  67. {
  68. delete ctx;
  69. return CREATEDECODER_FAILURE;
  70. }
  71. ctx->Feed(init_data, pps_size, 0);
  72. init_data+=pps_size;
  73. init_data_len-=pps_size;
  74. }
  75. }
  76. // if we made it here, we should be good
  77. *decoder = new MKVH264(ctx, nalu_minus_one, video_data);
  78. return CREATEDECODER_SUCCESS;
  79. }
  80. else
  81. {
  82. return CREATEDECODER_FAILURE;
  83. }
  84. }
  85. else
  86. {
  87. return CREATEDECODER_NOT_MINE;
  88. }
  89. }
  90. #define CBCLASS MKVDecoderCreator
  91. START_DISPATCH;
  92. CB(CREATE_VIDEO_DECODER, CreateVideoDecoder)
  93. END_DISPATCH;
  94. #undef CBCLASS
  95. MKVH264::MKVH264(MFTDecoder *ctx, uint8_t nalu_minus_one, const nsmkv::VideoData *video_data) : decoder(ctx), video_data(video_data)
  96. {
  97. nalu_size = nalu_minus_one + 1;
  98. width=0;
  99. height=0;
  100. }
  101. MKVH264::~MKVH264()
  102. {
  103. for (size_t i=0;i<buffered_frames.size();i++) {
  104. nullsoft_h264_frame_data frame_data = buffered_frames[i];
  105. decoder->FreeFrame((YV12_PLANES *)frame_data.data, frame_data.decoder_data);
  106. }
  107. delete decoder;
  108. }
  109. int MKVH264::GetOutputProperties(int *x, int *y, int *color_format, double *aspect_ratio)
  110. {
  111. if (decoder) {
  112. bool flip;
  113. if (SUCCEEDED(decoder->GetOutputFormat(&width, &height, &flip, aspect_ratio))) {
  114. *x = width;
  115. *y = height;
  116. *color_format = htonl('YV12');
  117. return MKV_SUCCESS;
  118. }
  119. }
  120. return MKV_FAILURE;
  121. }
  122. uint32_t GetNALUSize(uint64_t nalu_size_bytes, const uint8_t *h264_data, size_t data_len);
  123. int MKVH264::DecodeBlock(const void *inputBuffer, size_t inputBufferBytes, uint64_t timestamp)
  124. {
  125. const uint8_t *h264_data = (const uint8_t *)inputBuffer;
  126. while (inputBufferBytes) {
  127. uint32_t this_size = GetNALUSize(nalu_size, h264_data, inputBufferBytes);
  128. if (this_size == 0)
  129. return MKV_FAILURE;
  130. inputBufferBytes-=nalu_size;
  131. h264_data+=nalu_size;
  132. if (this_size > inputBufferBytes)
  133. return MKV_FAILURE;
  134. for (;;) {
  135. HRESULT hr = decoder->Feed(h264_data, this_size, timestamp);
  136. if (hr == MF_E_NOTACCEPTING) {
  137. nullsoft_h264_frame_data frame_data;
  138. if (FAILED(decoder->GetFrame((YV12_PLANES **)&frame_data.data, &frame_data.decoder_data, &frame_data.local_timestamp))) {
  139. continue;
  140. }
  141. buffered_frames.push_back(frame_data);
  142. } else if (FAILED(hr)) {
  143. return MKV_FAILURE;
  144. } else {
  145. break;
  146. }
  147. }
  148. inputBufferBytes-=this_size;
  149. h264_data+=this_size;
  150. }
  151. return MKV_SUCCESS;
  152. }
  153. void MKVH264::Flush()
  154. {
  155. for (size_t i=0;i<buffered_frames.size();i++) {
  156. nullsoft_h264_frame_data frame_data = buffered_frames[i];
  157. decoder->FreeFrame((YV12_PLANES *)frame_data.data, frame_data.decoder_data);
  158. }
  159. if (decoder) {
  160. decoder->Flush();
  161. }
  162. }
  163. int MKVH264::GetPicture(void **data, void **decoder_data, uint64_t *timestamp)
  164. {
  165. if (!buffered_frames.empty()) {
  166. nullsoft_h264_frame_data frame_data = buffered_frames[0];
  167. buffered_frames.erase(buffered_frames.begin());
  168. *data = frame_data.data;
  169. *decoder_data = frame_data.decoder_data;
  170. *timestamp = frame_data.local_timestamp;
  171. return MKV_SUCCESS;
  172. }
  173. if (SUCCEEDED(decoder->GetFrame((YV12_PLANES **)data, decoder_data, timestamp))) {
  174. return MKV_SUCCESS;
  175. } else {
  176. return MKV_FAILURE;
  177. }
  178. }
  179. void MKVH264::FreePicture(void *data, void *decoder_data)
  180. {
  181. decoder->FreeFrame((YV12_PLANES *)data, decoder_data);
  182. }
  183. void MKVH264::EndOfStream()
  184. {
  185. if (decoder) {
  186. decoder->Drain();
  187. }
  188. }
  189. void MKVH264::HurryUp(int state)
  190. {
  191. // TODO(benski)
  192. //if (decoder)
  193. // H264_HurryUp(decoder, state);
  194. }
  195. void MKVH264::Close()
  196. {
  197. delete this;
  198. }
  199. #define CBCLASS MKVH264
  200. START_DISPATCH;
  201. CB(GET_OUTPUT_PROPERTIES, GetOutputProperties)
  202. CB(DECODE_BLOCK, DecodeBlock)
  203. VCB(FLUSH, Flush)
  204. VCB(CLOSE, Close)
  205. CB(GET_PICTURE, GetPicture)
  206. VCB(FREE_PICTURE, FreePicture)
  207. VCB(END_OF_STREAM, EndOfStream)
  208. VCB(HURRY_UP, HurryUp)
  209. END_DISPATCH;
  210. #undef CBCLASS