diff options
author | Jean-Francois Mauguit <jfmauguit@mac.com> | 2024-09-24 09:03:25 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-09-24 09:03:25 -0400 |
commit | bab614c421ed7ae329d26bf028c4a3b1d2450f5a (patch) | |
tree | 12f17f78986871dd2cfb0a56e5e93b545c1ae0d0 /Src/h264/nsv_h264_decoder.cpp | |
parent | 4bde6044fddf053f31795b9eaccdd2a5a527d21f (diff) | |
parent | 20d28e80a5c861a9d5f449ea911ab75b4f37ad0d (diff) | |
download | winamp-bab614c421ed7ae329d26bf028c4a3b1d2450f5a.tar.gz |
Merge pull request #5 from WinampDesktop/community
Merge to main
Diffstat (limited to 'Src/h264/nsv_h264_decoder.cpp')
-rw-r--r-- | Src/h264/nsv_h264_decoder.cpp | 77 |
1 files changed, 77 insertions, 0 deletions
diff --git a/Src/h264/nsv_h264_decoder.cpp b/Src/h264/nsv_h264_decoder.cpp new file mode 100644 index 00000000..3fa781ff --- /dev/null +++ b/Src/h264/nsv_h264_decoder.cpp @@ -0,0 +1,77 @@ +#include "nsv_h264_decoder.h" +#include "../nsv/nsvlib.h" +#include "../nsv/dec_if.h" +#include <assert.h> +#include <Mferror.h> + +H264_Decoder::H264_Decoder() +{ + vidbufdec=0; + last_pic = 0; + decoder.Open(); +} + +H264_Decoder::~H264_Decoder() +{ + for (size_t i=0;i<buffered_frames.size();i++) { + nullsoft_h264_frame_data frame_data = buffered_frames[i]; + decoder.FreeFrame((YV12_PLANES *)frame_data.data, frame_data.decoder_data); + } + + decoder.FreeFrame(vidbufdec, last_pic); +} + +int H264_Decoder::decode(int need_kf, + void *_in, int _in_len, + void **out, // out is set to a pointer to data + unsigned int *out_type, // 'Y','V','1','2' is currently defined + int *is_kf) +{ + *out_type=NSV_MAKETYPE('Y','V','1','2'); + + if (last_pic) + { + decoder.FreeFrame(vidbufdec, last_pic); + vidbufdec=0; + last_pic=0; + } + + if (_in_len) { + for (;;) { + HRESULT hr = decoder.FeedRaw(_in, _in_len, 0); + if (hr == MF_E_NOTACCEPTING) { + nullsoft_h264_frame_data frame_data; + if (FAILED(decoder.GetFrame((YV12_PLANES **)&frame_data.data, &frame_data.decoder_data, &frame_data.local_timestamp))) { + continue; + } + buffered_frames.push_back(frame_data); + } else if (FAILED(hr)) { + return -1; + } else { + break; + } + } + } else { + decoder.Drain(); + } + + if (SUCCEEDED(decoder.GetFrame(&vidbufdec, &last_pic, 0))) { + *out = vidbufdec; + *is_kf = 1; + } else { + *out = 0; + } + + return 0; +} + +void H264_Decoder::flush() +{ + for ( size_t i = 0; i < buffered_frames.size(); i++ ) + { + nullsoft_h264_frame_data frame_data = buffered_frames[ i ]; + decoder.FreeFrame( (YV12_PLANES *)frame_data.data, frame_data.decoder_data ); + } + + decoder.Flush(); +} |