mkv_mp4v_decoder.cpp 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. #include "mkv_mp4v_decoder.h"
  2. #include "../Winamp/wa_ipc.h" // for YV12_PLANES
  3. #include <mmsystem.h>
  4. #include <assert.h>
  5. int MKVDecoderCreator::CreateVideoDecoder(const char *codec_id, const nsmkv::TrackEntryData *track_entry_data, const nsmkv::VideoData *video_data, ifc_mkvvideodecoder **decoder)
  6. {
  7. if (!strcmp(codec_id, "V_MPEG4/ISO/ASP")
  8. || !strcmp(codec_id, "V_MPEG4/ISO/SP"))
  9. {
  10. VIDEOINFOHEADER header = {0, };
  11. header.bmiHeader.biHeight = (LONG)video_data->pixel_height;
  12. header.bmiHeader.biWidth = (LONG)video_data->pixel_width;
  13. header.bmiHeader.biCompression = 'v4pm';
  14. MFTDecoder *ctx = new MFTDecoder;
  15. if (!ctx) {
  16. return CREATEDECODER_FAILURE;
  17. }
  18. HRESULT hr = ctx->Open(&header);
  19. if (FAILED(hr)) {
  20. delete ctx;
  21. return CREATEDECODER_FAILURE;
  22. }
  23. if (ctx)
  24. {
  25. if (track_entry_data->codec_private && track_entry_data->codec_private_len) {
  26. // mkv stores headers up to first VOP in codec_private
  27. hr = ctx->Feed(track_entry_data->codec_private, track_entry_data->codec_private_len, 0);
  28. if (FAILED(hr)) {
  29. delete ctx;
  30. return CREATEDECODER_FAILURE;
  31. }
  32. }
  33. *decoder = new MKVMP4V(ctx, video_data);
  34. return CREATEDECODER_SUCCESS;
  35. }
  36. else
  37. {
  38. return CREATEDECODER_FAILURE;
  39. }
  40. }
  41. else if (!strcmp(codec_id, "V_MS/VFW/FOURCC"))
  42. {
  43. if (track_entry_data->codec_private && track_entry_data->codec_private_len)
  44. {
  45. const BITMAPINFOHEADER *header = (const BITMAPINFOHEADER *)track_entry_data->codec_private;
  46. if (header->biCompression == 'DIVX'
  47. || header->biCompression == '05XD')
  48. {
  49. if (track_entry_data->codec_private_len < 40) {
  50. return CREATEDECODER_FAILURE;
  51. }
  52. VIDEOINFOHEADER video_header = {0, };
  53. memcpy(&video_header.bmiHeader, header, 40);
  54. assert(track_entry_data->codec_private_len == 40);
  55. MFTDecoder *ctx = new MFTDecoder;
  56. if (!ctx) {
  57. return CREATEDECODER_FAILURE;
  58. }
  59. if (FAILED(ctx->Open(&video_header))) {
  60. delete ctx;
  61. return CREATEDECODER_FAILURE;
  62. }
  63. *decoder = new MKVMP4V(ctx, video_data);
  64. return CREATEDECODER_SUCCESS;
  65. }
  66. }
  67. return CREATEDECODER_NOT_MINE;
  68. }
  69. else
  70. {
  71. return CREATEDECODER_NOT_MINE;
  72. }
  73. }
  74. #define CBCLASS MKVDecoderCreator
  75. START_DISPATCH;
  76. CB(CREATE_VIDEO_DECODER, CreateVideoDecoder)
  77. END_DISPATCH;
  78. #undef CBCLASS
  79. MKVMP4V::MKVMP4V(MFTDecoder *decoder, const nsmkv::VideoData *video_data) : decoder(decoder), video_data(video_data)
  80. {
  81. }
  82. MKVMP4V::~MKVMP4V()
  83. {
  84. delete decoder;
  85. }
  86. int MKVMP4V::GetOutputProperties(int *x, int *y, int *color_format, double *aspect_ratio)
  87. {
  88. UINT width, height;
  89. bool local_flip=false;
  90. if (SUCCEEDED(decoder->GetOutputFormat(&width, &height, &local_flip, aspect_ratio))) {
  91. *x = width;
  92. *y = height;
  93. *color_format = '21VY';
  94. return MKV_SUCCESS;
  95. }
  96. return MKV_FAILURE;
  97. }
  98. int MKVMP4V::DecodeBlock(const void *inputBuffer, size_t inputBufferBytes, uint64_t timestamp)
  99. {
  100. HRESULT hr;
  101. hr=decoder->Feed(inputBuffer, inputBufferBytes, timestamp);
  102. return MKV_SUCCESS;
  103. }
  104. void MKVMP4V::Flush()
  105. {
  106. if (decoder) {
  107. decoder->Flush();
  108. }
  109. }
  110. int MKVMP4V::GetPicture(void **data, void **decoder_data, uint64_t *timestamp)
  111. {
  112. if (SUCCEEDED(decoder->GetFrame((YV12_PLANES **)data, decoder_data, timestamp))) {
  113. return MKV_SUCCESS;
  114. } else {
  115. return MKV_FAILURE;
  116. }
  117. }
  118. void MKVMP4V::FreePicture(void *data, void *decoder_data)
  119. {
  120. if (decoder) {
  121. decoder->FreeFrame((YV12_PLANES *)data, decoder_data);
  122. }
  123. }
  124. void MKVMP4V::HurryUp(int state)
  125. {
  126. // if (decoder)
  127. // MPEG4Video_HurryUp(decoder, state);
  128. }
  129. void MKVMP4V::Close()
  130. {
  131. delete this;
  132. }
  133. #define CBCLASS MKVMP4V
  134. START_DISPATCH;
  135. CB(GET_OUTPUT_PROPERTIES, GetOutputProperties)
  136. CB(DECODE_BLOCK, DecodeBlock)
  137. VCB(FLUSH, Flush)
  138. CB(GET_PICTURE, GetPicture)
  139. VCB(FREE_PICTURE, FreePicture)
  140. VCB(HURRY_UP, HurryUp)
  141. VCB(CLOSE, Close)
  142. END_DISPATCH;
  143. #undef CBCLASS