winamp/Src/vp6/avi_vp6_decoder.cpp
2024-09-24 14:54:57 +02:00

150 lines
3.1 KiB
C++

#include "avi_vp6_decoder.h"
#include "../nsv/nsvlib.h"
#include "../nsavi/nsavi.h"
#include "../libvp6/include/vp6.h"
int AVIDecoderCreator::CreateVideoDecoder(const nsavi::AVIH *avi_header, const nsavi::STRH *stream_header, const nsavi::STRF *stream_format, const nsavi::STRD *stream_data, ifc_avivideodecoder **decoder)
{
nsavi::video_format *format = (nsavi::video_format *)stream_format;
if (format)
{
if (format->compression == '26PV' || format->compression == '16PV' || format->compression == '06PV')
{
DXL_XIMAGE_HANDLE xim = DXL_AlterXImage( NULL, (unsigned char *)"" ,NSV_MAKETYPE('V','P','6','0'), DXRGBNULL, 0, 0);
if (!xim)
return CREATEDECODER_FAILURE;
*decoder = new AVIVP6(xim);
return CREATEDECODER_SUCCESS;
}
}
return CREATEDECODER_NOT_MINE;
}
#define CBCLASS AVIDecoderCreator
START_DISPATCH;
CB(CREATE_VIDEO_DECODER, CreateVideoDecoder)
END_DISPATCH;
#undef CBCLASS
static const int vp6_postProcess=6;
static const int vp6_cpuFree=70;
static const int vp6_deInterlace=0;
static const int vp6_addNoise=1;
enum
{
PBC_SET_POSTPROC,
PBC_SET_CPUFREE,
PBC_MAX_PARAM,
PBC_SET_TESTMODE,
PBC_SET_PBSTRUCT,
PBC_SET_BLACKCLAMP,
PBC_SET_WHITECLAMP,
PBC_SET_REFERENCEFRAME,
PBC_SET_DEINTERLACEMODE,
PBC_SET_ADDNOISE
} ;
extern "C"
{
void GetImageBufs(DXL_XIMAGE_HANDLE x, YV12_PLANES *p);
void vp60_SetParameter(DXL_XIMAGE_HANDLE src, int Command, uintptr_t Parameter );
};
AVIVP6::AVIVP6(DXL_XIMAGE_HANDLE xim) : xim(xim)
{
decoded=0;
if(vp6_cpuFree)
DXL_SetParameter(xim, PBC_SET_CPUFREE, vp6_cpuFree);
else
DXL_SetParameter(xim, PBC_SET_POSTPROC, vp6_postProcess);
DXL_SetParameter(xim, PBC_SET_DEINTERLACEMODE, vp6_deInterlace );
DXL_SetParameter(xim, PBC_SET_ADDNOISE, vp6_addNoise);
DXL_SetParameter(xim, PBC_SET_BLACKCLAMP,0);
DXL_SetParameter(xim, PBC_SET_WHITECLAMP,0);
}
int AVIVP6::GetOutputProperties(int *x, int *y, int *color_format, double *aspect_ratio, int *flip)
{
if (xim)
{
if (vp60_getWH(xim, x, y) == DXL_OK)
{
*color_format = nsaviFOURCC('Y','V','1','2');
*flip = 1;
return AVI_SUCCESS;
}
}
return AVI_FAILURE;
}
int AVIVP6::DecodeChunk(uint16_t type, const void *inputBuffer, size_t inputBufferBytes)
{
uint8_t *vp6_data = (uint8_t *)inputBuffer;
if (inputBufferBytes)
{
// skip first byte
//vp6_data++;
//inputBufferBytes--;
DXL_AlterXImageData(xim, (unsigned char *)vp6_data);
DXL_SetXImageCSize(xim, inputBufferBytes);
if (!vp60_decompress(xim))
{
decoded=1;
return AVI_SUCCESS;
}
}
return AVI_FAILURE;
}
void AVIVP6::Flush()
{
//if (decoder)
// MPEG4Video_Flush(decoder);
}
int AVIVP6::GetPicture(void **data, void **decoder_data)
{
if (decoded)
{
GetImageBufs(xim,&vidbufdec);
*data=&vidbufdec;
*decoder_data = 0;
decoded = 0;
return AVI_SUCCESS;
}
return AVI_FAILURE;
}
void AVIVP6::FreePicture(void *data, void *decoder_data)
{
}
void AVIVP6::HurryUp(int state)
{
}
#define CBCLASS AVIVP6
START_DISPATCH;
CB(GET_OUTPUT_PROPERTIES, GetOutputProperties)
CB(DECODE_CHUNK, DecodeChunk)
VCB(FLUSH, Flush)
CB(GET_PICTURE, GetPicture)
VCB(FREE_PICTURE, FreePicture)
VCB(HURRY_UP, HurryUp)
END_DISPATCH;
#undef CBCLASS