diff options
author | Jef <jef@targetspot.com> | 2024-09-24 08:54:57 -0400 |
---|---|---|
committer | Jef <jef@targetspot.com> | 2024-09-24 08:54:57 -0400 |
commit | 20d28e80a5c861a9d5f449ea911ab75b4f37ad0d (patch) | |
tree | 12f17f78986871dd2cfb0a56e5e93b545c1ae0d0 /Src/vp8x/mkv_vp8x_decoder.cpp | |
parent | 537bcbc86291b32fc04ae4133ce4d7cac8ebe9a7 (diff) | |
download | winamp-20d28e80a5c861a9d5f449ea911ab75b4f37ad0d.tar.gz |
Initial community commit
Diffstat (limited to 'Src/vp8x/mkv_vp8x_decoder.cpp')
-rw-r--r-- | Src/vp8x/mkv_vp8x_decoder.cpp | 150 |
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 + |