aboutsummaryrefslogtreecommitdiff
path: root/Src/vp8x/mkv_vp8x_decoder.cpp
diff options
context:
space:
mode:
authorJef <jef@targetspot.com>2024-09-24 08:54:57 -0400
committerJef <jef@targetspot.com>2024-09-24 08:54:57 -0400
commit20d28e80a5c861a9d5f449ea911ab75b4f37ad0d (patch)
tree12f17f78986871dd2cfb0a56e5e93b545c1ae0d0 /Src/vp8x/mkv_vp8x_decoder.cpp
parent537bcbc86291b32fc04ae4133ce4d7cac8ebe9a7 (diff)
downloadwinamp-20d28e80a5c861a9d5f449ea911ab75b4f37ad0d.tar.gz
Initial community commit
Diffstat (limited to 'Src/vp8x/mkv_vp8x_decoder.cpp')
-rw-r--r--Src/vp8x/mkv_vp8x_decoder.cpp150
1 files changed, 150 insertions, 0 deletions
diff --git a/Src/vp8x/mkv_vp8x_decoder.cpp b/Src/vp8x/mkv_vp8x_decoder.cpp
new file mode 100644
index 00000000..e9471e38
--- /dev/null
+++ b/Src/vp8x/mkv_vp8x_decoder.cpp
@@ -0,0 +1,150 @@
+#include "mkv_vp8x_decoder.h"
+#include "../nsmkv/Lacing.h"
+#include "../nsmkv/Cluster.h"
+#include <mmsystem.h>
+
+int MKVDecoder::CreateVideoDecoder(const char *codec_id, const nsmkv::TrackEntryData *track_entry_data, const nsmkv::VideoData *video_data, ifc_mkvvideodecoder **decoder)
+{
+ if (!strcmp(codec_id, "V_VP8"))
+ {
+ vpx_codec_ctx_t codec;
+ if (vpx_codec_dec_init(&codec, &vpx_codec_vp8_dx_algo, NULL, 0) == VPX_CODEC_OK)
+ {
+ MKVVP8 *vp8 = new MKVVP8(codec, video_data);
+ *decoder = vp8;
+ return CREATEDECODER_SUCCESS;
+ }
+#if 0
+
+ nsmkv::LacingState lacing_state;
+ if (nsmkv::Lacing::GetState(nsmkv::BlockBinary::XIPH_LACING, (const uint8_t *)track_entry_data->codec_private, track_entry_data->codec_private_len, &lacing_state))
+ {
+ const uint8_t *frame;
+ size_t frame_len;
+ uint16_t frame_number=0;
+ 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))
+ {
+ ogg_packet packet = {const_cast<uint8_t *>(frame), frame_len, (frame_number==0), 0, 0 /*-1?*/, theora->packet_number++};
+ int ret = th_decode_headerin(&theora->info, &theora->comment, &theora->setup, &packet);
+ if (ret < 0)
+ goto bail;
+ frame_number++;
+ }
+ theora->decoder = th_decode_alloc(&theora->info, theora->setup);
+ if (!theora->decoder)
+ goto bail;
+
+ *decoder = theora;
+ return CREATEDECODER_SUCCESS;
+ }
+
+bail:
+ delete theora;
+#endif
+ return CREATEDECODER_FAILURE;
+
+ }
+ else
+ {
+ return CREATEDECODER_NOT_MINE;
+ }
+}
+
+
+#define CBCLASS MKVDecoder
+START_DISPATCH;
+CB(CREATE_VIDEO_DECODER, CreateVideoDecoder)
+END_DISPATCH;
+#undef CBCLASS
+
+MKVVP8::MKVVP8(vpx_codec_ctx_t decoder, const nsmkv::VideoData *video_data) : decoder(decoder), video_data(video_data)
+{
+ flushing=false;
+}
+
+int MKVVP8::GetOutputProperties(int *x, int *y, int *color_format, double *aspect_ratio)
+{
+ vpx_codec_stream_info_t stream_info;
+ stream_info.sz = sizeof(stream_info);
+ if (vpx_codec_get_stream_info(&decoder, &stream_info) == VPX_CODEC_OK)
+ {
+ *x = stream_info.w;
+ *y = stream_info.h;
+ *aspect_ratio=1.0;
+ *color_format = mmioFOURCC('Y','V','1','2');
+ return MKV_SUCCESS;
+ }
+
+ return MKV_FAILURE;
+}
+
+int MKVVP8::DecodeBlock(const void *inputBuffer, size_t inputBufferBytes, uint64_t timestamp)
+{
+ frame_iterator = 0;
+ vpx_codec_decode(&decoder, (const uint8_t *)inputBuffer, (unsigned int)inputBufferBytes, 0, 0);
+ return MKV_SUCCESS;
+}
+
+void MKVVP8::Flush()
+{
+ flushing=true;
+}
+
+int MKVVP8::GetPicture(void **data, void **decoder_data, uint64_t *timestamp)
+{
+ if (flushing)
+ {
+ vpx_codec_stream_info_t stream_info;
+ stream_info.sz = sizeof(stream_info);
+ if (vpx_codec_get_stream_info(&decoder, &stream_info) == VPX_CODEC_OK)
+ {
+ if (!stream_info.is_kf)
+ return MKV_FAILURE;
+ flushing=false;
+ }
+ }
+
+ vpx_image_t *image = vpx_codec_get_frame(&decoder, &frame_iterator);
+ if (image)
+ {
+ planes.y.baseAddr = image->planes[0];
+ planes.y.rowBytes = image->stride[0];
+ planes.u.baseAddr = image->planes[1];
+ planes.u.rowBytes = image->stride[1];
+ planes.v.baseAddr = image->planes[2];
+ planes.v.rowBytes = image->stride[2];
+ *data = &planes;
+ *decoder_data = 0;
+
+ return MKV_SUCCESS;
+ }
+
+ return MKV_FAILURE;
+}
+
+void MKVVP8::FreePicture(void *data, void *decoder_data)
+{
+}
+
+void MKVVP8::HurryUp(int state)
+{
+}
+
+void MKVVP8::Close()
+{
+ vpx_codec_destroy(&decoder);
+ delete this;
+}
+
+#define CBCLASS MKVVP8
+START_DISPATCH;
+CB(GET_OUTPUT_PROPERTIES, GetOutputProperties)
+CB(DECODE_BLOCK, DecodeBlock)
+VCB(FLUSH, Flush)
+CB(GET_PICTURE, GetPicture)
+VCB(FREE_PICTURE, FreePicture)
+VCB(HURRY_UP, HurryUp)
+VCB(CLOSE, Close)
+END_DISPATCH;
+#undef CBCLASS
+