ffglobals.cpp.svn-base

来自「ffshow源码」· SVN-BASE 代码 · 共 1,552 行 · 第 1/3 页

SVN-BASE
1,552
字号
/* * Copyright (c) 2002-2006 Milan Cutka * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */#include "stdafx.h"#include "ffglobals.h"#include <shlobj.h>#include "libavcodec/bitstream.h"#include "libavcodec/golomb.h"#include "ffdshow_mediaguids.h"#include "rational.h"#include "libavcodec/avcodec.h"#include "TffPict.h"#include "autoptr.h"#include "reg.h"#include "Tstream.h"#include "compiler.h"#ifdef UNICODE #define UNICODE_BUILD "unicode"#else #define UNICODE_BUILD "ansi"#endifconst char_t *FFDSHOW_VER=_l(__DATE__) _l(" ") _l(__TIME__) _l(" (") _l(COMPILER) _l(COMPILER_X64) _l(", ") _l(UNICODE_BUILD) _l(")");#undef COMPILER#undef COMPILER_SSE#undef COMPILER_SSE2#undef COMPILER_X64char_t* strcatf(char_t *dst,const char_t *fmt,...){ char_t pomS[1024]; va_list va; va_start(va,fmt); vsprintf(pomS,fmt,va); va_end(va); return strcat(dst,pomS);}char_t* strncatf(char_t *dst,size_t dstlen,const char_t *fmt,...){ char_t pomS[1024]; va_list va; va_start(va,fmt); vsprintf(pomS,fmt,va); va_end(va); return strncat(dst,pomS,dstlen);}char_t* strcpyf(char_t *dst,const char_t *fmt,...){ va_list va; va_start(va,fmt); vsprintf(dst,fmt,va); va_end(va); return dst;}char_t* strncpyf(char_t *dst,size_t dstlen,const char_t *fmt,...){ va_list va; va_start(va,fmt); _vsnprintf(dst,dstlen,fmt,va); va_end(va); return dst;}template<class tchar,class TlistItem> void strtok(const tchar *s,const tchar *delim,std::vector<TlistItem > &lst,bool add_empty,size_t max_parts){ typedef typename tchar_traits<tchar>::ffstring ffstring; lst.clear(); size_t delimLen=strlen(delim); const tchar *f; while ((f=strstr(s,delim))!=NULL && lst.size()+1<max_parts)  {   if (f-s || add_empty)    lst.push_back(TlistItem(s,f-s));   s=f+delimLen;  } if (s[0] || add_empty)   lst.push_back(s); }template<class tchar> void strtok(const tchar *s,const tchar *delim,ints &lst,bool add_empty,size_t max_parts){ typedef typename tchar_traits<tchar>::strings strings; strings listS;strtok(s,delim,listS,add_empty,max_parts); lst.clear(); for (typename strings::const_iterator i=listS.begin();i!=listS.end();i++)  {   tchar *end;   int x=strtol(i->c_str(),&end,10);   if (*end=='\0') lst.push_back(x);  } }void mergetok(char_t *dst,size_t dstlen,const char_t *delim,const strings &list){ size_t pos=0,delimlen=strlen(delim); for (strings::const_iterator l=list.begin();pos+1<dstlen && l!=list.end();l++)  {   size_t strlenl=l->size(),n=std::min(dstlen-pos,strlenl);   memcpy(dst+pos,l->c_str(),n*sizeof(char_t));   pos+=n;   if (l!=list.end()-1)    {     n=std::min(dstlen-pos,delimlen);     memcpy(dst+pos,delim,n*sizeof(char_t));     pos+=n;    }   } dst[pos]='\0'; }//inspired by XBrowseForFolder by Hans Dietrichstatic int CALLBACK dlgGetDirFn(HWND hwnd,UINT uMsg,LPARAM lParam,LPARAM lpData){ switch (uMsg)  {   case BFFM_INITIALIZED:    {     // remove context help button from dialog caption     LONG lStyle=GetWindowLong(hwnd,GWL_STYLE);     lStyle&=~DS_CONTEXTHELP;     SetWindowLong(hwnd,GWL_STYLE,lStyle);     lStyle=GetWindowLong(hwnd,GWL_EXSTYLE);     lStyle&=~WS_EX_CONTEXTHELP;     SetWindowLong(hwnd,GWL_EXSTYLE,lStyle);     // set initial directory     SendMessage(hwnd,BFFM_SETSELECTION,TRUE,lpData);     break;    }  } return 0;}bool dlgGetDir(HWND owner,char_t *dir,const char_t *capt){ bool ret=false; IMalloc *g_pMalloc;CoGetMalloc(1,&g_pMalloc); LPTSTR lpBuffer=(LPTSTR)g_pMalloc->Alloc(MAX_PATH*sizeof(char_t));strcpy(lpBuffer,dir); BROWSEINFO bi;  bi.hwndOwner=owner;  bi.pidlRoot=NULL; bi.pszDisplayName=lpBuffer; bi.lpszTitle=capt;  bi.ulFlags=BIF_RETURNONLYFSDIRS/*|BIF_NEWDIALOGSTYLE*/; bi.lpfn=dlgGetDirFn;  bi.lParam=LPARAM(dir); LPITEMIDLIST pidlBrowse=SHBrowseForFolder(&bi); if (pidlBrowse)  {    SHGetPathFromIDList(pidlBrowse,lpBuffer);   g_pMalloc->Free((void*)pidlBrowse);    if (lpBuffer[0])    {     strcpy(dir,lpBuffer);     ret=true;    }    }  g_pMalloc->Free(lpBuffer);  return ret;}void findFiles(const char_t *mask,strings &lst,bool fullpaths){ lst.clear(); char_t dsk[MAX_PATH],dir[MAX_PATH];_splitpath(mask,dsk,dir,NULL,NULL); WIN32_FIND_DATA ff; HANDLE hFind=FindFirstFile(mask,&ff); BOOL bOk=(hFind!=(HANDLE)-1); while (bOk)  {   if (fullpaths)    {     char_t flnm[MAX_PATH];     _makepath(flnm,dsk,dir,ff.cFileName,NULL);     lst.push_back(flnm);    }   else    lst.push_back(ff.cFileName);   bOk=FindNextFile(hFind,&ff);  }   if (hFind!=(HANDLE)-1) FindClose(hFind);}bool fileexists(const char_t *flnm){ return GetFileAttributes(flnm)!=INVALID_FILE_ATTRIBUTES;}bool directoryexists(const char_t *dir){ DWORD r=GetFileAttributes(dir); return r!=INVALID_FILE_ATTRIBUTES && (r&FILE_ATTRIBUTE_DIRECTORY)!=0;}void extractfilepath(const char_t *flnm,char_t *path){ char_t dsk[MAX_PATH],dir[MAX_PATH]; _splitpath(flnm,dsk,dir,NULL,NULL); _makepath(path,dsk,dir,NULL,NULL);}void extractfilename(const char_t *flnm,char_t *nameext){ char_t nm[MAX_PATH],ext[MAX_PATH]; _splitpath(flnm,NULL,NULL,nm,ext); _makepath(nameext,NULL,NULL,nm,ext);}void extractfilenameWOext(const char_t *flnm,char_t *name){ char_t nm[MAX_PATH]; _splitpath(flnm,NULL,NULL,nm,NULL); _makepath(name,NULL,NULL,nm,NULL);}void extractfileext(const char_t *flnm,char_t *ext){ _splitpath(flnm,NULL,NULL,NULL,ext); if (ext[0]) memmove(ext,ext+1,strlen(ext)*sizeof(char_t));}FILETIME fileLastWriteTime(const char_t *flnm){ WIN32_FIND_DATA fd; HANDLE h=FindFirstFile(flnm,&fd); if (h==INVALID_HANDLE_VALUE)  {   FILETIME ft={0,0};   return ft;  } else  {   FindClose(h);   return fd.ftLastWriteTime;  }}int nCopyAnsiToWideChar(WCHAR *pWCStr,PCTSTR pAnsiIn,int cchAnsi){ if (!cchAnsi) cchAnsi = lstrlen(pAnsiIn);#ifdef UNICODE return (int)strlen(strncpy(pWCStr, pAnsiIn,cchAnsi)) + 1;#else return MultiByteToWideChar(GetACP(), MB_PRECOMPOSED, pAnsiIn, cchAnsi, pWCStr, cchAnsi) + 1;#endif}char *unicode16toAnsi(const WCHAR *data16,int data16len,char *data8){ int data8len=WideCharToMultiByte(CP_ACP,0,data16,data16len,NULL,0,NULL,NULL); if (!data8)  data8=(char*)calloc(data8len+1,1); BOOL wasDefChar; WideCharToMultiByte(CP_ACP,0,data16,data16len,data8,data8len,NULL,&wasDefChar); return data8;}char *utf8toAnsi(const char *data,int datalen,char *data8){ int data16len=MultiByteToWideChar(CP_UTF8,0,data,datalen,NULL,0); LPWSTR data16=(LPWSTR)_alloca(data16len*2); MultiByteToWideChar(CP_UTF8,0,data,-1,data16,data16len); return unicode16toAnsi(data16,data16len,data8);}wchar_t *utf8toUnicode(const char *data,int datalen,wchar_t *data16){ int data16len=MultiByteToWideChar(CP_UTF8,0,data,datalen,NULL,0); if (!data16)  data16=(wchar_t*)calloc(data16len+1,1); MultiByteToWideChar(CP_UTF8,0,data,-1,data16,data16len); return data16;}bool dlgGetFile(bool save,HWND owner,const char_t *capt,const char_t *filter,const char_t *defext,char_t *flnm,const char_t *initdir,DWORD flags,DWORD *filterIndex){ OPENFILENAME ofn; memset(&ofn,0,sizeof(ofn)); ofn.lStructSize    =sizeof(OPENFILENAME); ofn.hwndOwner      =owner; ofn.lpstrFilter    =filter; if (filterIndex)  ofn.nFilterIndex=*filterIndex; ofn.lpstrInitialDir=initdir; ofn.lpstrFile      =flnm; ofn.lpstrTitle     =capt; ofn.lpstrDefExt    =defext;   ofn.nMaxFile       =MAX_PATH; ofn.Flags          =flags|(save?OFN_PATHMUSTEXIST|OFN_OVERWRITEPROMPT:OFN_PATHMUSTEXIST|OFN_FILEMUSTEXIST)|OFN_ENABLESIZING|OFN_HIDEREADONLY; bool ret=(save?GetSaveFileName(&ofn):GetOpenFileName(&ofn))?true:false; if (ret && filterIndex)  *filterIndex=ofn.nFilterIndex; return ret; }bool dlgOpenFiles(HWND owner,const char_t *capt,const char_t *filter,const char_t *defext,strings &files,const char_t *initdir,DWORD flags){ OPENFILENAME ofn; memset(&ofn,0,sizeof(ofn)); ofn.lStructSize    =sizeof(OPENFILENAME); ofn.hwndOwner      =owner; ofn.lpstrFilter    =filter; ofn.lpstrInitialDir=initdir; char_t *flnm=(char_t*)malloc(65536*sizeof(char_t));if (files.empty()) flnm[0]='\0';else strcpy(flnm,files[0].c_str()); ofn.lpstrFile      =LPTSTR(flnm); ofn.lpstrTitle     =capt; ofn.lpstrDefExt    =defext;   ofn.nMaxFile       =MAX_PATH; ofn.Flags          =flags|OFN_PATHMUSTEXIST|OFN_FILEMUSTEXIST|OFN_ENABLESIZING|OFN_HIDEREADONLY|OFN_ALLOWMULTISELECT|OFN_EXPLORER; BOOL ret=GetOpenFileName(&ofn); if (ret)  {   const char_t *dir=ofn.lpstrFile;   if (directoryexists(dir))    while ((ofn.lpstrFile=strchr(ofn.lpstrFile,'\0')+1)!=NULL && ofn.lpstrFile[0])     {      char_t flnm1[MAX_PATH];      _makepath(flnm1,NULL,dir,ofn.lpstrFile,NULL);      files.push_back(flnm1);     }    else     files.push_back(dir);   free(flnm);   return true;  } else   {   free(flnm);   return false;  } }// copied from ffmpeg// (c) Michael Niedermayerstatic const unsigned char ff_sqrt_tab[128]={ 0, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,11,11,11,11,11,11,11};unsigned int ff_sqrt(unsigned int a){ if (a<128) return ff_sqrt_tab[a];     unsigned int ret=0; unsigned int ret_sq=0; for(int s=15; s>=0; s--)  {   unsigned int b= ret_sq + (1<<(s*2)) + (ret<<s)*2;   if (b<=a)    {     ret_sq=b;     ret+= 1<<s;    }  } return ret;}int64_t lavc_gcd(int64_t a, int64_t b){    if(b) return lavc_gcd(b, a%b);    else  return a;}int lavc_reduce(int *dst_nom, int *dst_den, int64_t nom, int64_t den, int64_t max){/*    int exact=1, sign=0;    int64_t gcd;    assert(den != 0);    if(den < 0){        den= -den;        nom= -nom;    }        if(nom < 0){        nom= -nom;        sign= 1;    }            gcd = lavc_gcd(nom, den);        nom /= gcd;        den /= gcd;        if(nom > max || den > max){        AVRational a0={0,1}, a1={1,0};        exact=0;        for(;;){            int64_t x= nom / den;            int64_t a2n= x*a1.num + a0.num;            int64_t a2d= x*a1.den + a0.den;            if(a2n > max || a2d > max) break;                nom %= den;                    a0= a1;            a1.num=int(a2n);a1.den=int(a2d);// = (AVRational){a2n, a2d};            if(nom==0) break;            x= nom; nom=den; den=x;        }        nom= a1.num;        den= a1.den;    }        assert(lavc_gcd(nom, den) == 1);        if(sign) nom= -nom;        *dst_nom = int(nom);    *dst_den = int(den);        return exact;*/    AVRational a0={0,1}, a1={1,0};    int sign= (nom<0) ^ (den<0);    int64_t gcd= lavc_gcd(ff_abs(nom), ff_abs(den));    nom = ff_abs(nom)/gcd;    den = ff_abs(den)/gcd;    if(nom<=max && den<=max){        a1.num=(int)nom;a1.den=(int)den;//= (AVRational){nom, den};        den=0;    }        while(den){        int64_t x       = nom / den;        int64_t next_den= nom - den*x;        int64_t a2n= x*a1.num + a0.num;        int64_t a2d= x*a1.den + a0.den;        if(a2n > max || a2d > max) break;        a0= a1;        a1.num=(int)a2n;a1.den=(int)a2d;//= (AVRational){a2n, a2d};        nom= den;        den= next_den;    }    assert(lavc_gcd(a1.num, a1.den) == 1);        *dst_nom = sign ? -a1.num : a1.num;    *dst_den = a1.den;        return den==0;}static const uint8_t ff_log2_tab[256]={        0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,        5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,        6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,        6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,        7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,        7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,        7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,        7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7};int av_log2(unsigned int v){    int n;    n = 0;    if (v & 0xffff0000) {        v >>= 16;        n += 16;    }    if (v & 0xff00) {        v >>= 8;        n += 8;    }    n += ff_log2_tab[v];    return n;}static int sync_video_packet(const uint8_t *videobuf_code,size_t len){  if (len<4)   return 0;  int skipped=0;  while(1)   {    if(videobuf_code[0]==0 &&       videobuf_code[1]==0 &&       videobuf_code[2]==1) break; // synced    // shift buffer, drop first byte    ++skipped;    videobuf_code++;len--;if (len==0) return 0; //EOF   }  //if(skipped) DPRINTF("videobuf: %d bytes skipped  (next: 0x1%02X)\n",skipped,videobuf_code[3]);  return 0x100|videobuf_code[3];}bool decodeMPEGsequenceHeader(bool mpeg2,const unsigned char *hdr,size_t len,TffPictBase &pict,bool *isH264){ int sync=sync_video_packet(hdr,len); if((sync&~0x60) == 0x107 && sync != 0x107)  // H.264  {   *isH264=true;   return decodeH264SPS(hdr+2,len,pict);  }  *isH264=false;  len*=8; if (!hdr || len<12+12+4) return false; GetBitContext gb; init_get_bits(&gb, hdr, (int)len); int id=get_bits(&gb,32); if (id!=0x01b3)  return false; int dx=get_bits(&gb,12),dy=get_bits(&gb,12);

⌨️ 快捷键说明

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