123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163 |
- #include "mkv_mp4v_decoder.h"
- #include "../Winamp/wa_ipc.h" // for YV12_PLANES
- #include <mmsystem.h>
- #include <assert.h>
- int MKVDecoderCreator::CreateVideoDecoder(const char *codec_id, const nsmkv::TrackEntryData *track_entry_data, const nsmkv::VideoData *video_data, ifc_mkvvideodecoder **decoder)
- {
- if (!strcmp(codec_id, "V_MPEG4/ISO/ASP")
- || !strcmp(codec_id, "V_MPEG4/ISO/SP"))
- {
- VIDEOINFOHEADER header = {0, };
- header.bmiHeader.biHeight = (LONG)video_data->pixel_height;
- header.bmiHeader.biWidth = (LONG)video_data->pixel_width;
- header.bmiHeader.biCompression = 'v4pm';
- MFTDecoder *ctx = new MFTDecoder;
- if (!ctx) {
- return CREATEDECODER_FAILURE;
- }
- HRESULT hr = ctx->Open(&header);
- if (FAILED(hr)) {
- delete ctx;
- return CREATEDECODER_FAILURE;
- }
- if (ctx)
- {
- if (track_entry_data->codec_private && track_entry_data->codec_private_len) {
- // mkv stores headers up to first VOP in codec_private
- hr = ctx->Feed(track_entry_data->codec_private, track_entry_data->codec_private_len, 0);
- if (FAILED(hr)) {
- delete ctx;
- return CREATEDECODER_FAILURE;
- }
- }
- *decoder = new MKVMP4V(ctx, video_data);
- return CREATEDECODER_SUCCESS;
- }
- else
- {
- return CREATEDECODER_FAILURE;
- }
- }
- else if (!strcmp(codec_id, "V_MS/VFW/FOURCC"))
- {
- if (track_entry_data->codec_private && track_entry_data->codec_private_len)
- {
- const BITMAPINFOHEADER *header = (const BITMAPINFOHEADER *)track_entry_data->codec_private;
- if (header->biCompression == 'DIVX'
- || header->biCompression == '05XD')
- {
- if (track_entry_data->codec_private_len < 40) {
- return CREATEDECODER_FAILURE;
- }
- VIDEOINFOHEADER video_header = {0, };
- memcpy(&video_header.bmiHeader, header, 40);
- assert(track_entry_data->codec_private_len == 40);
- MFTDecoder *ctx = new MFTDecoder;
- if (!ctx) {
- return CREATEDECODER_FAILURE;
- }
- if (FAILED(ctx->Open(&video_header))) {
- delete ctx;
- return CREATEDECODER_FAILURE;
- }
- *decoder = new MKVMP4V(ctx, video_data);
- return CREATEDECODER_SUCCESS;
- }
- }
- return CREATEDECODER_NOT_MINE;
- }
- else
- {
- return CREATEDECODER_NOT_MINE;
- }
- }
- #define CBCLASS MKVDecoderCreator
- START_DISPATCH;
- CB(CREATE_VIDEO_DECODER, CreateVideoDecoder)
- END_DISPATCH;
- #undef CBCLASS
- MKVMP4V::MKVMP4V(MFTDecoder *decoder, const nsmkv::VideoData *video_data) : decoder(decoder), video_data(video_data)
- {
- }
- MKVMP4V::~MKVMP4V()
- {
- delete decoder;
- }
- int MKVMP4V::GetOutputProperties(int *x, int *y, int *color_format, double *aspect_ratio)
- {
- UINT width, height;
- bool local_flip=false;
- if (SUCCEEDED(decoder->GetOutputFormat(&width, &height, &local_flip, aspect_ratio))) {
- *x = width;
- *y = height;
- *color_format = '21VY';
- return MKV_SUCCESS;
- }
- return MKV_FAILURE;
- }
- int MKVMP4V::DecodeBlock(const void *inputBuffer, size_t inputBufferBytes, uint64_t timestamp)
- {
- HRESULT hr;
- hr=decoder->Feed(inputBuffer, inputBufferBytes, timestamp);
- return MKV_SUCCESS;
- }
- void MKVMP4V::Flush()
- {
- if (decoder) {
- decoder->Flush();
- }
- }
- int MKVMP4V::GetPicture(void **data, void **decoder_data, uint64_t *timestamp)
- {
- if (SUCCEEDED(decoder->GetFrame((YV12_PLANES **)data, decoder_data, timestamp))) {
- return MKV_SUCCESS;
- } else {
- return MKV_FAILURE;
- }
- }
- void MKVMP4V::FreePicture(void *data, void *decoder_data)
- {
- if (decoder) {
- decoder->FreeFrame((YV12_PLANES *)data, decoder_data);
- }
- }
- void MKVMP4V::HurryUp(int state)
- {
- // if (decoder)
- // MPEG4Video_HurryUp(decoder, state);
- }
- void MKVMP4V::Close()
- {
- delete this;
- }
- #define CBCLASS MKVMP4V
- 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
|