mkv_vp8x_decoder.cpp 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. #include "mkv_vp8x_decoder.h"
  2. #include "../nsmkv/Lacing.h"
  3. #include "../nsmkv/Cluster.h"
  4. #include <mmsystem.h>
  5. int MKVDecoder::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_VP8"))
  8. {
  9. vpx_codec_ctx_t codec;
  10. if (vpx_codec_dec_init(&codec, &vpx_codec_vp8_dx_algo, NULL, 0) == VPX_CODEC_OK)
  11. {
  12. MKVVP8 *vp8 = new MKVVP8(codec, video_data);
  13. *decoder = vp8;
  14. return CREATEDECODER_SUCCESS;
  15. }
  16. #if 0
  17. nsmkv::LacingState lacing_state;
  18. if (nsmkv::Lacing::GetState(nsmkv::BlockBinary::XIPH_LACING, (const uint8_t *)track_entry_data->codec_private, track_entry_data->codec_private_len, &lacing_state))
  19. {
  20. const uint8_t *frame;
  21. size_t frame_len;
  22. uint16_t frame_number=0;
  23. while (nsmkv::Lacing::GetFrame(frame_number, (const uint8_t *)track_entry_data->codec_private, track_entry_data->codec_private_len, &frame, &frame_len, &lacing_state))
  24. {
  25. ogg_packet packet = {const_cast<uint8_t *>(frame), frame_len, (frame_number==0), 0, 0 /*-1?*/, theora->packet_number++};
  26. int ret = th_decode_headerin(&theora->info, &theora->comment, &theora->setup, &packet);
  27. if (ret < 0)
  28. goto bail;
  29. frame_number++;
  30. }
  31. theora->decoder = th_decode_alloc(&theora->info, theora->setup);
  32. if (!theora->decoder)
  33. goto bail;
  34. *decoder = theora;
  35. return CREATEDECODER_SUCCESS;
  36. }
  37. bail:
  38. delete theora;
  39. #endif
  40. return CREATEDECODER_FAILURE;
  41. }
  42. else
  43. {
  44. return CREATEDECODER_NOT_MINE;
  45. }
  46. }
  47. #define CBCLASS MKVDecoder
  48. START_DISPATCH;
  49. CB(CREATE_VIDEO_DECODER, CreateVideoDecoder)
  50. END_DISPATCH;
  51. #undef CBCLASS
  52. MKVVP8::MKVVP8(vpx_codec_ctx_t decoder, const nsmkv::VideoData *video_data) : decoder(decoder), video_data(video_data)
  53. {
  54. flushing=false;
  55. }
  56. int MKVVP8::GetOutputProperties(int *x, int *y, int *color_format, double *aspect_ratio)
  57. {
  58. vpx_codec_stream_info_t stream_info;
  59. stream_info.sz = sizeof(stream_info);
  60. if (vpx_codec_get_stream_info(&decoder, &stream_info) == VPX_CODEC_OK)
  61. {
  62. *x = stream_info.w;
  63. *y = stream_info.h;
  64. *aspect_ratio=1.0;
  65. *color_format = mmioFOURCC('Y','V','1','2');
  66. return MKV_SUCCESS;
  67. }
  68. return MKV_FAILURE;
  69. }
  70. int MKVVP8::DecodeBlock(const void *inputBuffer, size_t inputBufferBytes, uint64_t timestamp)
  71. {
  72. frame_iterator = 0;
  73. vpx_codec_decode(&decoder, (const uint8_t *)inputBuffer, (unsigned int)inputBufferBytes, 0, 0);
  74. return MKV_SUCCESS;
  75. }
  76. void MKVVP8::Flush()
  77. {
  78. flushing=true;
  79. }
  80. int MKVVP8::GetPicture(void **data, void **decoder_data, uint64_t *timestamp)
  81. {
  82. if (flushing)
  83. {
  84. vpx_codec_stream_info_t stream_info;
  85. stream_info.sz = sizeof(stream_info);
  86. if (vpx_codec_get_stream_info(&decoder, &stream_info) == VPX_CODEC_OK)
  87. {
  88. if (!stream_info.is_kf)
  89. return MKV_FAILURE;
  90. flushing=false;
  91. }
  92. }
  93. vpx_image_t *image = vpx_codec_get_frame(&decoder, &frame_iterator);
  94. if (image)
  95. {
  96. planes.y.baseAddr = image->planes[0];
  97. planes.y.rowBytes = image->stride[0];
  98. planes.u.baseAddr = image->planes[1];
  99. planes.u.rowBytes = image->stride[1];
  100. planes.v.baseAddr = image->planes[2];
  101. planes.v.rowBytes = image->stride[2];
  102. *data = &planes;
  103. *decoder_data = 0;
  104. return MKV_SUCCESS;
  105. }
  106. return MKV_FAILURE;
  107. }
  108. void MKVVP8::FreePicture(void *data, void *decoder_data)
  109. {
  110. }
  111. void MKVVP8::HurryUp(int state)
  112. {
  113. }
  114. void MKVVP8::Close()
  115. {
  116. vpx_codec_destroy(&decoder);
  117. delete this;
  118. }
  119. #define CBCLASS MKVVP8
  120. START_DISPATCH;
  121. CB(GET_OUTPUT_PROPERTIES, GetOutputProperties)
  122. CB(DECODE_BLOCK, DecodeBlock)
  123. VCB(FLUSH, Flush)
  124. CB(GET_PICTURE, GetPicture)
  125. VCB(FREE_PICTURE, FreePicture)
  126. VCB(HURRY_UP, HurryUp)
  127. VCB(CLOSE, Close)
  128. END_DISPATCH;
  129. #undef CBCLASS