1
0

mkv_theora_decoder.cpp 3.6 KB

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