1
0

h264_flv_decoder.cpp 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. #include "h264_flv_decoder.h"
  2. #include "../Winamp/wa_ipc.h" // for YV12_PLANES
  3. #include <Mferror.h>
  4. int FLVDecoderCreator::CreateVideoDecoder(int format_type, int width, int height, ifc_flvvideodecoder **decoder)
  5. {
  6. if (format_type == FLV::VIDEO_FORMAT_AVC)
  7. {
  8. MFTDecoder *ctx = new MFTDecoder();
  9. if (!ctx || FAILED(ctx->Open())) {
  10. delete ctx;
  11. return CREATEDECODER_FAILURE;
  12. }
  13. *decoder = new FLVH264(ctx);
  14. return CREATEDECODER_SUCCESS;
  15. }
  16. return CREATEDECODER_NOT_MINE;
  17. }
  18. int FLVDecoderCreator::HandlesVideo(int format_type)
  19. {
  20. if (format_type == FLV::VIDEO_FORMAT_AVC)
  21. {
  22. return CREATEDECODER_SUCCESS;
  23. }
  24. return CREATEDECODER_NOT_MINE;
  25. }
  26. #define CBCLASS FLVDecoderCreator
  27. START_DISPATCH;
  28. CB(CREATE_VIDEO_DECODER, CreateVideoDecoder)
  29. CB(HANDLES_VIDEO, HandlesVideo)
  30. END_DISPATCH;
  31. #undef CBCLASS
  32. /* --- */
  33. uint32_t GetNALUSize(uint64_t nalu_size_bytes, const uint8_t *h264_data, size_t data_len);
  34. uint32_t Read24(const uint8_t *data);
  35. FLVH264::FLVH264(MFTDecoder *decoder) : decoder(decoder)
  36. {
  37. sequence_headers_parsed=0;
  38. nalu_size_bytes=0;
  39. }
  40. FLVH264::~FLVH264()
  41. {
  42. for (size_t i=0;i<buffered_frames.size();i++) {
  43. nullsoft_h264_frame_data frame_data = buffered_frames[i];
  44. decoder->FreeFrame((YV12_PLANES *)frame_data.data, frame_data.decoder_data);
  45. }
  46. delete decoder;
  47. }
  48. int FLVH264::GetOutputFormat(int *x, int *y, int *color_format)
  49. {
  50. UINT width, height;
  51. bool local_flip=false;
  52. double aspect_ratio;
  53. if (SUCCEEDED(decoder->GetOutputFormat(&width, &height, &local_flip, &aspect_ratio))) {
  54. *x = width;
  55. *y = height;
  56. *color_format = '21VY';
  57. return FLV_VIDEO_SUCCESS;
  58. }
  59. return FLV_VIDEO_FAILURE;
  60. }
  61. int FLVH264::DecodeSample(const void *inputBuffer, size_t inputBufferBytes, int32_t timestamp)
  62. {
  63. const uint8_t *h264_data = (const uint8_t *)inputBuffer;
  64. if (*h264_data == 0 && inputBufferBytes >= 10) // sequence headers
  65. {
  66. h264_data++; // skip packet type
  67. uint32_t timestamp_offset = Read24(h264_data);
  68. h264_data+=3;
  69. inputBufferBytes -=4;
  70. h264_data+=4; // don't care about level & profile
  71. inputBufferBytes -=4;
  72. nalu_size_bytes = (*h264_data++ & 0x3)+1;
  73. inputBufferBytes--;
  74. size_t num_sps = *h264_data++ & 0x1F;
  75. inputBufferBytes--;
  76. for (size_t i=0;i!=num_sps;i++)
  77. {
  78. if (inputBufferBytes > 2)
  79. {
  80. uint16_t sps_size = (h264_data[0] << 8) | h264_data[1];
  81. h264_data+=2;
  82. inputBufferBytes-=2;
  83. //H264_ProcessSPS(decoder, h264_data+1, sps_size);
  84. if (inputBufferBytes >= sps_size)
  85. {
  86. decoder->Feed(h264_data, sps_size, timestamp+timestamp_offset);
  87. h264_data+=sps_size;
  88. inputBufferBytes-=sps_size;
  89. }
  90. }
  91. }
  92. if (inputBufferBytes)
  93. {
  94. size_t num_pps = *h264_data++;
  95. inputBufferBytes--;
  96. for (size_t i=0;i!=num_pps;i++)
  97. {
  98. if (inputBufferBytes > 2)
  99. {
  100. uint16_t sps_size = (h264_data[0] << 8) | h264_data[1];
  101. h264_data+=2;
  102. inputBufferBytes-=2;
  103. //H264_ProcessPPS(decoder, h264_data+1, sps_size);
  104. if (inputBufferBytes >= sps_size)
  105. {
  106. decoder->Feed(h264_data, sps_size, timestamp+timestamp_offset);
  107. h264_data+=sps_size;
  108. inputBufferBytes-=sps_size;
  109. }
  110. }
  111. }
  112. }
  113. sequence_headers_parsed=1;
  114. }
  115. else if (*h264_data == 1) // frame
  116. {
  117. h264_data++;
  118. inputBufferBytes--;
  119. if (inputBufferBytes < 3)
  120. return FLV_VIDEO_FAILURE;
  121. uint32_t timestamp_offset = Read24(h264_data);
  122. h264_data+=3;
  123. inputBufferBytes-=3;
  124. while (inputBufferBytes)
  125. {
  126. uint32_t this_size =GetNALUSize(nalu_size_bytes, h264_data, inputBufferBytes);
  127. if (this_size == 0)
  128. return FLV_VIDEO_FAILURE;
  129. inputBufferBytes-=nalu_size_bytes;
  130. h264_data+=nalu_size_bytes;
  131. if (this_size > inputBufferBytes)
  132. return FLV_VIDEO_FAILURE;
  133. for (;;) {
  134. HRESULT hr = decoder->Feed(h264_data, this_size, timestamp+timestamp_offset);
  135. if (hr == MF_E_NOTACCEPTING) {
  136. nullsoft_h264_frame_data frame_data;
  137. if (FAILED(decoder->GetFrame((YV12_PLANES **)&frame_data.data, &frame_data.decoder_data, &frame_data.local_timestamp))) {
  138. continue;
  139. }
  140. buffered_frames.push_back(frame_data);
  141. } else if (FAILED(hr)) {
  142. return FLV_VIDEO_FAILURE;
  143. } else {
  144. break;
  145. }
  146. }
  147. inputBufferBytes-=this_size;
  148. h264_data+=this_size;
  149. }
  150. }
  151. return FLV_VIDEO_SUCCESS;
  152. }
  153. void FLVH264::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. decoder->Flush();
  160. }
  161. void FLVH264::Close()
  162. {
  163. delete this;
  164. }
  165. int FLVH264::GetPicture(void **data, void **decoder_data, uint64_t *timestamp)
  166. {
  167. if (!buffered_frames.empty()) {
  168. nullsoft_h264_frame_data frame_data = buffered_frames[0];
  169. buffered_frames.erase(buffered_frames.begin());
  170. *data = frame_data.data;
  171. *decoder_data = frame_data.decoder_data;
  172. *timestamp = frame_data.local_timestamp;
  173. return FLV_VIDEO_SUCCESS;
  174. }
  175. if (SUCCEEDED(decoder->GetFrame((YV12_PLANES **)data, decoder_data, timestamp))) {
  176. return FLV_VIDEO_SUCCESS;
  177. } else {
  178. return FLV_VIDEO_FAILURE;
  179. }
  180. }
  181. void FLVH264::FreePicture(void *data, void *decoder_data)
  182. {
  183. decoder->FreeFrame((YV12_PLANES *)data, decoder_data);
  184. }
  185. int FLVH264::Ready()
  186. {
  187. return sequence_headers_parsed;
  188. }
  189. #define CBCLASS FLVH264
  190. START_DISPATCH;
  191. CB(FLV_VIDEO_GETOUTPUTFORMAT, GetOutputFormat)
  192. CB(FLV_VIDEO_DECODE, DecodeSample)
  193. VCB(FLV_VIDEO_FLUSH, Flush)
  194. VCB(FLV_VIDEO_CLOSE, Close)
  195. CB(FLV_VIDEO_GET_PICTURE, GetPicture)
  196. VCB(FLV_VIDEO_FREE_PICTURE, FreePicture)
  197. CB(FLV_VIDEO_READY, Ready)
  198. END_DISPATCH;
  199. #undef CBCLASS