⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ds_videodecoder.c

📁 coreavc for linux in unix_linux
💻 C
📖 第 1 页 / 共 3 页
字号:
/********************************************************	DirectShow Video decoder implementation	Copyright 2000 Eugene Kuznetsov  (divx@euro.ru)*********************************************************/#include "config.h"#include "guids.h"#include "interfaces.h"#include "registry.h"#include "libwin32.h"#include "DS_Filter.h"struct DS_VideoDecoder{    IVideoDecoder iv;        DS_Filter* m_pDS_Filter;    AM_MEDIA_TYPE m_sOurType, m_sDestType;    VIDEOINFOHEADER* m_sVhdr;    VIDEOINFOHEADER2* m_sVhdr2;    int m_Caps;//CAPS m_Caps;                // capabilities of DirectShow decoder    int m_iLastQuality;         // remember last quality as integer    int m_iMinBuffers;    int m_iMaxAuto;    int m_bIsDivX;             // for speed    int m_bIsDivX4;            // for speed};static SampleProcUserData sampleProcData;static int discontinuity = 1;#include "DS_VideoDecoder.h"#include "wine/winerror.h"#ifdef WIN32_LOADER#include "ldt_keeper.h"#endif#include <unistd.h>#include <fcntl.h>#include <errno.h>#include <sys/types.h>#include <stdio.h>#include <stdlib.h>  // labs// strcmp((const char*)info.dll,...)  is used instead of  (... == ...)// so Arpi could use char* pointer in his simplified DS_VideoDecoder class#define false 0#define true 1int DS_VideoDecoder_GetCapabilities(DS_VideoDecoder *this){return this->m_Caps;}	    typedef struct ct ct;struct ct {		unsigned int bits;		fourcc_t fcc;		const GUID *subtype;		int cap;	    };            static ct check[] = {		{16, fccYUY2, &MEDIASUBTYPE_YUY2, CAP_YUY2},		{12, fccIYUV, &MEDIASUBTYPE_IYUV, CAP_IYUV},		{16, fccUYVY, &MEDIASUBTYPE_UYVY, CAP_UYVY},		{12, fccYV12, &MEDIASUBTYPE_YV12, CAP_YV12},		//{16, fccYV12, &MEDIASUBTYPE_YV12, CAP_YV12},		{16, fccYVYU, &MEDIASUBTYPE_YVYU, CAP_YVYU},		{12, fccI420, &MEDIASUBTYPE_I420, CAP_I420},		{9,  fccYVU9, &MEDIASUBTYPE_YVU9, CAP_YVU9},		{0, 0, 0, 0},	    };#define AV_RB16(x)  ((((const uint8_t*)(x))[0] << 8) | ((const uint8_t*)(x))[1])DWORD avc_quant(BYTE *src, BYTE *dst, int len){    //Stolen from libavcodec h264.c    BYTE *p = src, *d = dst;    int cnt;    cnt = *(p+5) & 0x1f; // Number of sps    if(src[0] != 0x01 || cnt > 1) {      memcpy(dst, src, len);      return len;    }    p += 6;    //cnt > 1 not supported?    cnt = AV_RB16(p) + 2;    memcpy(d, p, cnt);    d+=cnt;    p+=cnt;    //assume pps cnt == 1 too    p++;    cnt = AV_RB16(p) + 2;    memcpy(d, p, cnt);    return d + cnt - dst;      }#define is_avc(cc) (cc == mmioFOURCC('A', 'V', 'C', '1') || \                    cc == mmioFOURCC('a', 'v', 'c', '1'))char *ConvertVIHtoMPEG2VI(VIDEOINFOHEADER *vih, int *size){    struct VIDEOINFOHEADER2 {        RECT32              rcSource;        RECT32              rcTarget;        DWORD               dwBitRate;        DWORD               dwBitErrorRate;        REFERENCE_TIME      AvgTimePerFrame;        DWORD               dwInterlaceFlags;        DWORD               dwCopyProtectFlags;        DWORD               dwPictAspectRatioX;         DWORD               dwPictAspectRatioY;         union {            DWORD           dwControlFlags;            DWORD           dwReserved1;        };        DWORD               dwReserved2;        BITMAPINFOHEADER    bmiHeader;    };    struct MPEG2VIDEOINFO {        struct VIDEOINFOHEADER2    hdr;        DWORD               dwStartTimeCode;           DWORD               cbSequenceHeader;             DWORD               dwProfile;             DWORD               dwLevel;                    DWORD               dwFlags;                    DWORD               dwSequenceHeader[1];    } *mp2vi;    int extra = 0;    if(vih->bmiHeader.biSize > sizeof(BITMAPINFOHEADER)) {      extra = vih->bmiHeader.biSize-sizeof(BITMAPINFOHEADER);    }    mp2vi = (struct MPEG2VIDEOINFO *)malloc(sizeof(struct MPEG2VIDEOINFO)+extra-4);    memset(mp2vi, 0, sizeof(struct MPEG2VIDEOINFO));    mp2vi->hdr.rcSource = vih->rcSource;    mp2vi->hdr.rcTarget = vih->rcTarget;    mp2vi->hdr.dwBitRate = vih->dwBitRate;    mp2vi->hdr.dwBitErrorRate = vih->dwBitErrorRate;    mp2vi->hdr.AvgTimePerFrame = vih->AvgTimePerFrame;    mp2vi->hdr.dwPictAspectRatioX = vih->bmiHeader.biWidth;    mp2vi->hdr.dwPictAspectRatioY = vih->bmiHeader.biHeight;    memcpy(&mp2vi->hdr.bmiHeader, &vih->bmiHeader, sizeof(BITMAPINFOHEADER));    mp2vi->hdr.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);    if(extra) {      if(is_avc(vih->bmiHeader.biCompression)) {        mp2vi->dwFlags = 4; //What does this mean?        mp2vi->cbSequenceHeader = avc_quant(                          (BYTE *)(&vih->bmiHeader) + sizeof(BITMAPINFOHEADER),                          (BYTE *)(&mp2vi->dwSequenceHeader[0]), extra);      } else {        mp2vi->cbSequenceHeader = extra;        memcpy(&mp2vi->dwSequenceHeader[0],               (BYTE *)(&vih->bmiHeader) + sizeof(BITMAPINFOHEADER), extra);      }    }    // The '4' is from the allocated space of dwSequenceHeader    *size = sizeof(struct MPEG2VIDEOINFO) + mp2vi->cbSequenceHeader - 4;    return (char *)mp2vi;}void DS_VideoDecoder_SetInputType(DS_VideoDecoder *this, BITMAPINFOHEADER * format){  unsigned int bihs;  bihs = (format->biSize < (int) sizeof(BITMAPINFOHEADER)) ?         sizeof(BITMAPINFOHEADER) : format->biSize;  this->iv.m_bh = realloc(this->iv.m_bh, bihs);  memcpy(this->iv.m_bh, format, bihs);  this->iv.m_bh->biSize = bihs;  bihs += sizeof(VIDEOINFOHEADER) - sizeof(BITMAPINFOHEADER);  this->m_sVhdr = realloc(this->m_sVhdr, bihs);  memset(this->m_sVhdr, 0, bihs);  memcpy(&this->m_sVhdr->bmiHeader, this->iv.m_bh, this->iv.m_bh->biSize);  this->m_sVhdr->rcSource.left = this->m_sVhdr->rcSource.top = 0;  this->m_sVhdr->rcSource.right = this->m_sVhdr->bmiHeader.biWidth;  this->m_sVhdr->rcSource.bottom = this->m_sVhdr->bmiHeader.biHeight;  //this->m_sVhdr->rcSource.right = 0;  //this->m_sVhdr->rcSource.bottom = 0;  this->m_sVhdr->rcTarget = this->m_sVhdr->rcSource;  this->m_sOurType.majortype = MEDIATYPE_Video;  this->m_sOurType.subtype = MEDIATYPE_Video;  this->m_sOurType.subtype.f1 = this->m_sVhdr->bmiHeader.biCompression;  this->m_sOurType.formattype = FORMAT_VideoInfo;  this->m_sOurType.bFixedSizeSamples = false;  this->m_sOurType.bTemporalCompression = true;  this->m_sOurType.pUnk = 0;  this->m_sOurType.cbFormat = bihs;  this->m_sOurType.pbFormat = (char*)this->m_sVhdr;  if(is_avc(this->m_sVhdr->bmiHeader.biCompression)) {    int size;    this->m_sOurType.formattype = FORMAT_MPEG2Video;    this->m_sOurType.pbFormat =                    (char*)ConvertVIHtoMPEG2VI(this->m_sVhdr, &size);    this->m_sOurType.cbFormat = size;  }}DS_VideoDecoder * DS_VideoDecoder_Open(char* dllname, GUID* guid, BITMAPINFOHEADER * format, int flip, int maxauto){    DS_VideoDecoder *this;    HRESULT result;    ct* c;                            this = malloc(sizeof(DS_VideoDecoder));    memset( this, 0, sizeof(DS_VideoDecoder));    this->m_iMaxAuto = maxauto;#ifdef WIN32_LOADER    Setup_LDT_Keeper();#endif    //memset(&m_obh, 0, sizeof(m_obh));    //m_obh.biSize = sizeof(m_obh);    /*try*/    {        this->iv.m_State = STOP;        //this->iv.m_pFrame = 0;        this->iv.m_Mode = DIRECT;        this->iv.m_iDecpos = 0;        this->iv.m_iPlaypos = -1;        this->iv.m_fQuality = 0.0f;        this->iv.m_bCapable16b = true;        DS_VideoDecoder_SetInputType(this, format);  	this->m_sVhdr2 = malloc(sizeof(VIDEOINFOHEADER2)+12);        memset((char*)this->m_sVhdr2, 0, sizeof(VIDEOINFOHEADER2)+12);	this->m_sVhdr2->rcSource = this->m_sVhdr->rcSource;	this->m_sVhdr2->rcTarget = this->m_sVhdr->rcTarget;	this->m_sVhdr2->dwBitRate = this->m_sVhdr->dwBitRate;	this->m_sVhdr2->dwBitErrorRate = this->m_sVhdr->dwBitErrorRate;	this->m_sVhdr2->bmiHeader = this->m_sVhdr->bmiHeader;	this->m_sVhdr2->bmiHeader.biCompression = 0;	this->m_sVhdr2->bmiHeader.biBitCount = 24;	memset(&this->m_sDestType, 0, sizeof(this->m_sDestType));	this->m_sDestType.majortype = MEDIATYPE_Video;	this->m_sDestType.subtype = MEDIASUBTYPE_RGB24;	this->m_sDestType.formattype = FORMAT_VideoInfo2;	this->m_sDestType.bFixedSizeSamples = true;	this->m_sDestType.bTemporalCompression = false;	this->m_sDestType.lSampleSize = labs(this->m_sVhdr2->bmiHeader.biWidth*this->m_sVhdr2->bmiHeader.biHeight				       * ((this->m_sVhdr2->bmiHeader.biBitCount + 7) / 8));	this->m_sVhdr2->bmiHeader.biSizeImage = this->m_sDestType.lSampleSize;	this->m_sDestType.pUnk = 0;	this->m_sDestType.cbFormat = sizeof(VIDEOINFOHEADER2);	this->m_sDestType.pbFormat = (char*)this->m_sVhdr2;                memset(&this->iv.m_obh, 0, sizeof(this->iv.m_obh));	memcpy(&this->iv.m_obh, this->iv.m_bh, sizeof(this->iv.m_obh) < (unsigned) this->iv.m_bh->biSize	       ? sizeof(this->iv.m_obh) : (unsigned) this->iv.m_bh->biSize);	this->iv.m_obh.biBitCount=24;        this->iv.m_obh.biSize = sizeof(BITMAPINFOHEADER);        this->iv.m_obh.biCompression = 0;	//BI_RGB        //this->iv.m_obh.biHeight = labs(this->iv.m_obh.biHeight);        this->iv.m_obh.biSizeImage = labs(this->iv.m_obh.biWidth * this->iv.m_obh.biHeight)                              * ((this->iv.m_obh.biBitCount + 7) / 8);        memset(&sampleProcData, 0, sizeof(sampleProcData));	this->m_pDS_Filter = DS_FilterCreate(dllname, guid, &this->m_sOurType, &this->m_sDestType,&sampleProcData);		if (!this->m_pDS_Filter)	{	    printf("Failed to create DirectShow filter\n");	    return 0;	}	if (!flip)	{	    this->iv.m_obh.biHeight *= -1;	    this->m_sVhdr2->bmiHeader.biHeight = this->iv.m_obh.biHeight;	    result = this->m_pDS_Filter->m_pOutputPin->vt->QueryAccept(this->m_pDS_Filter->m_pOutputPin, &this->m_sDestType);	    if (result)	    {		printf("Decoder does not support upside-down RGB frames\n");		this->iv.m_obh.biHeight *= -1;		this->m_sVhdr2->bmiHeader.biHeight = this->iv.m_obh.biHeight;	    }	}        memcpy( &this->iv.m_decoder, &this->iv.m_obh, sizeof(this->iv.m_obh) );	switch (this->iv.m_bh->biCompression)	{#if 0	case fccDIV3:	case fccDIV4:	case fccDIV5:	case fccDIV6:	case fccMP42:	case fccWMV2:	    //YV12 seems to be broken for DivX :-) codec//	case fccIV50:	    //produces incorrect picture	    //m_Caps = (CAPS) (m_Caps & ~CAP_YV12);	    //m_Caps = CAP_UYVY;//CAP_YUY2; // | CAP_I420;	    //m_Caps = CAP_I420;	    this->m_Caps = (CAP_YUY2 | CAP_UYVY);	    break;#endif	default:              	    this->m_Caps = CAP_NONE;	    printf("Decoder supports the following YUV formats: ");	    for (c = check; c->bits; c++)	    {		this->m_sVhdr2->bmiHeader.biBitCount = c->bits;		this->m_sVhdr2->bmiHeader.biCompression = c->fcc;		this->m_sDestType.subtype = *c->subtype;		result = this->m_pDS_Filter->m_pOutputPin->vt->QueryAccept(this->m_pDS_Filter->m_pOutputPin, &this->m_sDestType);		if (!result)		{		    this->m_Caps = (this->m_Caps | c->cap);		    printf("%.4s ", (char *)&c->fcc);		}	    }	    printf("\n");	}	if (this->m_Caps != CAP_NONE)	    printf("Decoder is capable of YUV output (flags 0x%x)\n", (int)this->m_Caps);	this->m_sVhdr2->bmiHeader.biBitCount = 24;	this->m_sVhdr2->bmiHeader.biCompression = 0;	this->m_sDestType.subtype = MEDIASUBTYPE_RGB24;	this->m_iMinBuffers = this->iv.VBUFSIZE;	this->m_bIsDivX = (strcmp(dllname, "divxcvki.ax") == 0		     || strcmp(dllname, "divx_c32.ax") == 0		     || strcmp(dllname, "wmvds32.ax") == 0		     || strcmp(dllname, "wmv8ds32.ax") == 0);	this->m_bIsDivX4 = (strcmp(dllname, "divxdec.ax") == 0);	if (this->m_bIsDivX)	    this->iv.VBUFSIZE += 7;	else if (this->m_bIsDivX4)	    this->iv.VBUFSIZE += 9;    }    /*catch (FatalError& error)    {        delete[] m_sVhdr;	delete[] m_sVhdr2;        delete m_pDS_Filter;	throw;    }*/    return this;}static int framecount, framecount_in;void DS_VideoDecoder_Destroy(DS_VideoDecoder *this){    DS_VideoDecoder_StopInternal(this);    this->iv.m_State = STOP;    free(this->m_sVhdr);    free(this->m_sVhdr2);    DS_Filter_Destroy(this->m_pDS_Filter);    printf("************\nin-frames: %d out-frames: %d\n************\n", framecount_in, framecount);}void DS_VideoDecoder_StartInternal(DS_VideoDecoder *this)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -