快捷搜索:

您的位置:澳门新葡4473网站 > 热门贴子 > 关于 AVI 的一些代码

关于 AVI 的一些代码

发布时间:2019-11-01 11:47编辑:热门贴子浏览(92)

    新葡亰平台娱乐, 

    #ifndef __HSS_AUTO_REVISE_AVI_FRAMERATE_HSS__
    #define __HSS_AUTO_REVISE_AVI_FRAMERATE_HSS__
    
    
    /**************************************************************************************************
     *  2012-05-31
     关于avi的一些功能。
     (1)
     由于丢帧等问题,导致录像长度不对,根据录像时间和帧数,修正avi文件中的帧率信息
        auto_avi::ReviseAviFrameRate(sec, frame, file);
        auto_avi::ReviseAviFrameRate_ms(millsec, frame, file);
    
    **************************************************************************************************/
    
    
    #include <auto_file.h>
    #include <__time.h>
    
    class auto_avi
    {
    public:
        auto_avi()
        {
        };
    
        ~auto_avi()
        {
        }
    
    public:
        /**************************************************************************************************
        * static void           :    
        * ReviseAviFrameRate    :    修正avi录像的长度(修改文件头里面的信息,把帧率修改为实际的帧率)
        * DWORD nSeconds        :    录像长度
        * DWORD nFrame          :    总帧数
        * LPCTSTR pszFile       :    
        **************************************************************************************************/
        static void ReviseAviFrameRate(DWORD nSeconds, DWORD nFrame, LPCTSTR pszFile)
        {
            auto_file f;
            if (!f.Open(pszFile, GENERIC_WRITE, FILE_SHARE_READ, OPEN_EXISTING, 0))
                return;
            SetFilePointer(f.m_hFile, 0x80, 0, FILE_BEGIN);
            DWORD scale = 1000;
            DWORD rate = nFrame * 1000 / nSeconds;
            f.OverWrite((LPBYTE)&scale, 4);
            f.OverWrite((LPBYTE)&rate, 4);
        }
    
        /**************************************************************************************************
        * static void              :    
        * ReviseAviFrameRate_ms    :    指定毫秒的版本
        * DWORD nMilliSeconds      :    录像长度毫秒
        * DWORD nFrame             :    帧率
        * LPCTSTR pszFile          :    录像文件
        **************************************************************************************************/
        static void ReviseAviFrameRate_ms(DWORD nMilliSeconds, DWORD nFrame, LPCTSTR pszFile)
        {
            auto_file f;
            if (!f.Open(pszFile, GENERIC_READ | GENERIC_WRITE, 0, OPEN_EXISTING, 0))
            {
                return;
            }
    
            if (nFrame == 0)
            {
                SetFilePointer(f.m_hFile, 0x8c, 0, FILE_BEGIN);
                if (!f.Read((LPBYTE)&nFrame, 4))
                    return;
            }
    
            SetFilePointer(f.m_hFile, 0x80, 0, FILE_BEGIN);
    
            DWORD scale = 1000;
    
            ULONGLONG a = nFrame;
    
            a *= 1000000;
    
            a /= nMilliSeconds;
    
            DWORD rate = (DWORD)a;
    
            f.OverWrite((LPBYTE)&scale, 4);
    
            f.OverWrite((LPBYTE)&rate, 4);
        }
    };
    
    #endif
    
    #ifndef __HSS_AUTO_AVI_HSS__
    #define __HSS_AUTO_AVI_HSS__
    
    #include <StringN.h>
    #include <HBuffer.H>
    
    class auto_avi_icc
    {
    public:
        auto_avi_icc()
        {
            __memzero(m_Com);
            __memzero(param):
            __memzero(strhdr);
            m_pFile = 0;
            tStartTime = 0;
            psz = 0;
        }
    
        ~auto_avi_icc()
        {
        }
    
        struct
        {
            BITMAPINFOHEADER bmi;
            BITMAPINFOHEADER bmo;
        }param;
    private:
        BOOL InitCompress()
        {
            //利用代码选择压缩器
            __memzero(m_Com);
    
            m_Com.cbSize = sizeof(m_Com);
            m_Com.dwFlags = ICMF_COMPVARS_VALID; 
    
            m_Com.fccType = ICTYPE_VIDEO;  
            m_Com.lFrame = 0;  
            m_Com.lKey = 3;        //关键帧
            m_Com.lKeyCount = 3; 
            m_Com.lDataRate = 780;
            m_Com.lpbiOut = (BITMAPINFO*)&m_OutInfo;  
            //压缩MPG4格式
            //m_Com.hic = ICOpen(ICTYPE_VIDEO, mmioFOURCC('M', 'P', '4', '2'), ICMODE_COMPRESS);
            //压缩DIVX
            //m_Com.hic = ICOpen(ICTYPE_VIDEO, mmioFOURCC('D', 'I', 'V', 'X'), ICMODE_COMPRESS);
            //压缩H264
            m_Com.hic = ICOpen(ICTYPE_VIDEO, mmioFOURCC('X', '2', '6', '4'), ICMODE_COMPRESS);
            m_Com.cbState = 1180;
            //ICCompressorChoose(NULL,ICMF_CHOOSE_ALLCOMPRESSORS ,(LPVOID)&m_InInfo,NULL,&m_Com,"选择压缩类型");
            ICCompressGetFormat(m_Com.hic, (LPBITMAPINFO)&param.bmi, (LPBITMAPINFO)&param.bmo);
            int ret = ICCompressBegin(m_Com.hic, (LPBITMAPINFO)&param.bmi, (LPBITMAPINFO)&param.bmo);
    
            if(ret != ICERR_OK )
            {
                //MessageBox(NULL, "视频压缩器无法启动!", "系统提示", MB_ICONSTOP);
                return FALSE;
            }
    
            return TRUE;
        }
    
        BOOL CreateAviFile(LPCTSTR pszFileName, LPBITMAPINFOHEADER pbi, LPBITMAPINFOHEADER pbo)
        {
            param.bmi = *pbi;
            param.bmo = *pbo;
    
            m_IndexFrame = 0 ;
            //AVI文件初始化
            AVIFileInit();
            //设置压缩参数
            if(!InitCompress())
            {
                AVIFileExit();
                return FALSE;
            }
            //打开文件
            m_pFile = NULL;
            HRESULT hr = ::AVIFileOpen(&m_pFile, pszFileName, OF_WRITE|OF_CREATE, NULL);   
            if(hr != 0)   
            {  
                AVIFileExit();
                //MessageBox(NULL, "无法创建视频文件!", "系统提示", MB_ICONSTOP);
                return 0;   
            }  
    
            memset(&strhdr, 0, sizeof(strhdr)) ;   
            strhdr.fccType = streamtypeVIDEO;//   stream   type   
            strhdr.fccHandler = 0;   
            strhdr.dwScale = 1;   
            strhdr.dwRate =  iLuxFrameRate;         //   25   fps  
            //int WIDTH = (m_InInfo.bmiHeader.biWidth * m_InInfo.bmiHeader.biBitCount + 31) / 32 * 4;
            //strhdr.dwSuggestedBufferSize = WIDTH * m_InInfo.bmiHeader.biHeight;
            strhdr.dwSuggestedBufferSize = m_InInfo.bmiHeader.biWidth * m_InInfo.bmiHeader.biHeight * 3;   
    
            SetRect(&strhdr.rcFrame, 
                0, 
                0,  
                m_InInfo.bmiHeader.biWidth,  
                m_InInfo.bmiHeader.biHeight);
    
            hr = AVIFileCreateStream(m_pFile, &ps, &strhdr); 
    
            if (hr != AVIERR_OK)
            {
                AVIFileExit();
                //MessageBox(NULL, "无法创建视频文件!", "系统提示", MB_ICONSTOP);
                return 0;   
            }
    
            tStartTime = GetTickCount();
    
            return true;
        }
    
        void CloseAviFile()
        {
            //结束数据压缩
            if (m_Com.hic)
            {
                ICCompressEnd(m_Com.hic);
    
                //关闭压缩句柄
                ICClose(m_Com.hic);
    
                if(ps) 
                    AVIStreamClose(ps);  
    
                if(m_pFile) 
                    AVIFileClose(m_pFile);
    
                AVIFileExit();
            }
        }
    
        BOOL AddFrame(LPBITMAPINFOHEADER pbih, LPBYTE pBits)
        {
                char* buffer = new char [NWIDTH * NHEIGHT * 3 + 1];
                memset(buffer, 0, NWIDTH * NHEIGHT * 3 + 1);
                DWORD dwCkID = 0;
                DWORD dwCompFlags = 0;
                DWORD dwQuality = 100;
                iLuxFrameRate = 25;
                DWORD m_RealFrame = ((GetTickCount() - tStartTime) * iLuxFrameRate + 500) / 1000;
                long cj = m_RealFrame - m_IndexFrame;
                for(long i = 0; i < cj + 1; i ++)
                {
                    //视频压缩
                    memset(buffer, 0, NWIDTH * NHEIGHT * 3 + 1);
                    if(ICCompress(m_Com.hic, 0, &m_OutInfo.bmiHeader, buffer,
                        &m_InInfo.bmiHeader, (unsigned char *)pBuffer, &dwCkID, &dwCompFlags, m_IndexFrame ++, 0, dwQuality, NULL, NULL) == ICERR_OK)
                    {
                        AVIStreamSetFormat(ps, m_IndexFrame, &m_OutInfo.bmiHeader, sizeof(m_OutInfo.bmiHeader));
                        VERIFY(0 == AVIStreamWrite(ps, //stream   pointer   
                            m_IndexFrame   , //time of this   frame   
                            1, //number   to   write   
                            (LPBYTE) buffer, //pBuffer,  
                            m_OutInfo.bmiHeader.biSizeImage, //size   of   this   frame   
                            AVIIF_KEYFRAME,   //   flags....   
                            NULL,   
                            NULL));
    
                        OutputDebugString(".");
                    }
                    else
                    {
                        VERIFY(0);
                    }
                }
                delete []buffer;
        }
    
    private:
        COMPVARS    m_Com;
        PAVIFILE    m_pFile; //AVI文件
        AVISTREAMINFO strhdr; //AVI流信息
        PAVISTREAM    ps; //AVI流指针
        DWORD        tStartTime;
        HBuffer        m_BufFrame;
    };
    
    
    #endif
    
    #ifndef __HSS_AVI_STREAM_HSS__
    #define __HSS_AVI_STREAM_HSS__
    
    
    /**************************************************************************************************
     *  2013-09-08
     新的监控录像类,自动持续录像,改变录像大小,叠加文字等,但是没有图像缓冲区
    
       auto_avi_stream avi;
    
      avi.SetConfigFile
    
      avi.Open(...
    
      avi.AddFrame
    
      avi.Close(
    
    
    **************************************************************************************************/
    
    #include <auto_x264.h>
    #include <rjpeg.h>
    #include <auto_IplImage.h>
    #include <HBuffer.h>
    #include <timemath.h>
    #include <overtext.h>
    #include <StringN.h>
    
    #define FCCX264            (*(DWORD*)"X264")
    
    class auto_avi_stream
    {
    public:
        struct
        {
        }param;
    
        struct
        {
            char                szFileName[_MAX_PATH];
            DWORD                fccHandler;
            RJPEG_OPEN            Param;
            BITMAPINFOHEADER    bih;
    
            ULONGLONG            lTickBegin;
            SYSTEMTIME            stBegin;
            ULONGLONG            lFrameIndex;    //下一帧的索引
            ULONGLONG            lFrameCount;
            ULONGLONG            lTickEnd;
            SYSTEMTIME            stEnd;
    
            BOOL                fFirstRun;
        }info;
    
        auto_x264        m_264;
    
        HBuffer            m_BufResized;
    
        HBuffer            m_BufOverlayText;
    
    public:
        auto_avi_stream()
        {
            __memzero(param);
            __memzero(info);
        }
    
        ~auto_avi_stream()
        {
        }
    
        /**************************************************************************************************
        * void               :    2013年9月8日 设置配置文件,x264会自动把后缀修改为 .x264.cfg
        * SetConfigFile      :    
        * LPCTSTR pszFile    :    
        **************************************************************************************************/
        void SetConfigFile(LPCTSTR pszFile)
        {
            __strcpy(m_264.param.szConfigFile, pszFile);
        }
    
        /**************************************************************************************************
        * BOOL      :    2013年9月8日 是否打开
        * IsOpen    :    
        **************************************************************************************************/
        BOOL IsOpen()
        {
            if (info.fccHandler == FCCX264)
                return m_264.IsOpen();
    
            return FALSE;
        }
    
        /**************************************************************************************************
        * BOOL                   :    2013年9月8日 打开录像
        * Open                   :    
        * LPCTSTR pszFile        :    文件名(可以是模板)
        * DWORD fccHandler       :    编码,*(DWORD*)"X264"(FCCX264)
        * RJPEG_OPEN* param      :    录像参数
        * DWORD dwTick = 0       :    开始时刻
        * SYSTEMTIME* pst = 0    :    开始时间
        **************************************************************************************************/
        BOOL Open(LPCTSTR pszFile, DWORD fccHandler, RJPEG_OPEN* param, DWORD dwTick = 0, SYSTEMTIME* pst = 0)
        {
            if (param->Format.nFrameRate <= 0)
                return FALSE;
    
            info.Param = *param;
            info.fccHandler = fccHandler;
            __strcpy(info.szFileName, pszFile);
    
            if (dwTick == 0 || pst == 0)
            {
                info.lTickBegin = ::GetTickCount();
                GetLocalTime(&info.stBegin);
            }
            else
            {
                info.lTickBegin = dwTick;
                info.stBegin = *pst;
            }
    
            info.lTickEnd = info.lTickBegin;
            info.stEnd = info.stBegin;
            info.lFrameCount = 0;
    
            BITMAPINFOHEADER bih = {0};
            info.bih.biBitCount = 24;
            info.bih.biWidth = info.Param.Format.biWidth;
            info.bih.biHeight = info.Param.Format.biHeight;
            info.bih.biPlanes = 1;
            info.bih.biSize = sizeof(info.bih);
            info.bih.biSizeImage = (info.bih.biWidth * info.bih.biBitCount + 31) / 32 * 4 * info.bih.biHeight;
    
            char szf[_MAX_PATH] = {0};
    
            GetFileName(szf, info.szFileName, &info.stBegin);
    
            return Open(szf);
        }
    
        /**************************************************************************************************
        * BOOL                       :    2013年9月8日 增加帧
        * AddFrame                   :    会自动停止等
        * DWORD dwTick               :    
        * LPBITMAPINFOHEADER pbih    :    
        * LPBYTE pBits               :    
        **************************************************************************************************/
        BOOL AddFrame(DWORD dwTick, LPBITMAPINFOHEADER pbih, LPBYTE pBits)
        {
            if (pbih->biBitCount != 24)
                return FALSE;
    
            ULONGLONG tick = GetTickCount(dwTick);
    
            //帧率控制
            double sec = (double)(LONGLONG)(tick - info.lTickBegin) / 1000.0;
    
            ULONGLONG index = (ULONGLONG)(LONGLONG)(sec * info.Param.Format.nFrameRate + 0.5);
            if (index <= info.lFrameIndex && info.lTickEnd != info.lTickBegin)
                return TRUE;
    
            info.lFrameIndex = index;
            info.lTickEnd = tick;
    
            SYSTEMTIME stold = info.stEnd;
            SYSTEMTIME st = info.stBegin;
            SystemTimeAdd(&st, (int)(LONGLONG)(tick - info.lTickBegin));
            info.stEnd = st;
    
            //先看看是否需要改变大小
            if (pbih->biWidth != info.bih.biWidth
                || pbih->biHeight != info.bih.biHeight
                )
            {
                int size = info.bih.biSizeImage;
    
                LPBYTE p = m_BufResized.GetBuffer(size);
                if (p == 0)
                    return FALSE;
    
                auto_IplImage src(pbih, pBits);
                if (!src)
                    return FALSE;
    
                auto_IplImage dst(&info.bih, p);
                if (!dst)
                    return FALSE;
    
                cvResize(src, dst, CV_INTER_LINEAR );
    
                pbih = &info.bih;
                pBits = p;
            }
    
            //叠加文字
            if (info.Param.oiText[0])
            {
                //第一步,如果没有改变大小,则要复制一下内存,防止改变了原始内存
                if (pBits != m_BufResized.m_pBuffer)
                {
                    int size = info.bih.biSizeImage;
    
                    LPBYTE p = m_BufResized.GetBuffer(size);
                    if (p == 0)
                        return FALSE;
    
                    ASSERT(info.bih.biSizeImage == pbih->biSizeImage);
    
                    memcpy(p, pBits, pbih->biSizeImage);
    
                    pBits = p;
                    pbih = &info.bih;
                }
    
                //下面做实际的叠加文字
                Overlay(pbih, pBits, info.stEnd, info.lFrameIndex);
            }
    
            //增加到录像
            if (!CompressFrame(tick, pbih, pBits))
                return FALSE;
    
            info.lFrameCount ++;
    
            BOOL bStop = 0;
    
            if (info.Param.dwFileEveryMinutes)
            {
                if (info.Param.dwFileEveryMinutes == 1)
                {
                    if (info.stEnd.wSecond < stold.wSecond)
                    {
                        double sec = GetSeconds();
    
                        if (sec > 30)
                        {
                            bStop = TRUE;
                        }
                    }
                }
                else if ((info.stEnd.wMinute % info.Param.dwFileEveryMinutes) == 0)
                {
                    double sec = GetSeconds();
    
                    if (sec > info.Param.dwFileEveryMinutes * 60.0 / 2.0)
                    {
                        bStop = TRUE;
                    }
                }
            }
            else if (info.Param.dwSecondsLimit)
            {
                double sec = GetSeconds();
    
                if (sec >= info.Param.dwSecondsLimit)
                {
                    bStop = TRUE;
                }
            }
    
            if (bStop)
            {
                //停止录像,开始新录像
                Stop();
    
                char szf[_MAX_PATH] = {0};
    
                if (0 == GetFileName(szf, info.szFileName, &info.stEnd))
                {
                    //非模板,直接关闭
                    return TRUE;
                }
    
                info.lTickBegin = tick;
                info.lTickEnd = tick;
                info.stBegin = info.stEnd;
    
                return Open(szf);
            }
    
            return TRUE;
        }
    
        /**************************************************************************************************
        * double        :    2013年9月8日 录像时间长度
        * GetSeconds    :    
        **************************************************************************************************/
        double GetSeconds()
        {
            double sec = (double)(LONGLONG)(info.lTickEnd - info.lTickBegin) / 1000.0;
    
            if (sec < 1.0)
                sec = 1.0;
    
            return sec;
        }
    
        /**************************************************************************************************
        * DWORD        :    2013年9月8日 录像多少帧
        * GetFrames    :    
        **************************************************************************************************/
        DWORD GetFrames()
        {
            return (DWORD)info.lFrameCount;
        }
    
        /**************************************************************************************************
        * void     :    2013年9月8日 关闭
        * Close    :    
        **************************************************************************************************/
        void Close()
        {
            Stop();
        }
    
        /**************************************************************************************************
        * void         :    2013年9月8日 配置
        * Config       :    
        * HWND hwnd    :    
        **************************************************************************************************/
        void Config(HWND hwnd)
        {
            if (info.fccHandler == FCCX264)
            {
                m_264.Config(hwnd);
            }
        }
    
        /**************************************************************************************************
        * LPCTSTR        :    2013年9月8日 获取文件名
        * GetFileName    :    
        **************************************************************************************************/
        LPCTSTR GetFileName()
        {
            if (info.fccHandler == FCCX264)
            {
                return m_264.info.szFile;
            }
    
            return "";
        }
    
        /**************************************************************************************************
        * double          :    2013年9月8日 获取实际的帧率
        * GetFrameRate    :    
        **************************************************************************************************/
        double GetFrameRate()
        {
            return GetFrames() / GetSeconds();
        }
    
        /**************************************************************************************************
        * void         :    2013年9月8日 获取当前录像的信息
        * GetInfo      :    
        * char* psz    :    
        * int cb       :    
        * int& n       :    
        **************************************************************************************************/
        void GetInfo(char* psz, int cb, int& n, int mode = 0)
        {
            double sec = GetSeconds();
            LPCTSTR stm = "秒";
    
            if (sec > 3600.0)
            {
                sec /= 3600.0;
                stm = "时";
            }
            else if (sec > 60.0)
            {
                sec /= 60.0;
                stm = "分";
            }
    
            if (mode == 0)
            {
                if (info.fccHandler == FCCX264)
                {
                    __snprintcat2(psz, cb, n), "%.1lf%s, 帧%d, 帧率%.1lfn#录像文件:%s%s%s",
                        sec, stm,
                        GetFrames(),
                        GetFrameRate(),
                        GetFileName(), 
                        m_264.info.szAsciiFile[0] ? "n#临时文件:" : "",
                        m_264.info.szAsciiFile
                        );
                }
                else
                {
                    __snprintcat2(psz, cb, n), "%s, %.1lf%s, 帧%d, 帧率%.1lf",
                        GetFileName(),
                        sec, stm,
                        GetFrames(),
                        GetFrameRate()
                        );
                }
            }
        }
    
    
    private:
    
        /**************************************************************************************************
        * void    :    2013年9月8日 停止
        * Stop    :    
        **************************************************************************************************/
        void Stop()
        {
            if (info.fccHandler == FCCX264)
            {
                m_264.Close();
            }
        }
    
        /**************************************************************************************************
        * BOOL                       :    2013年9月8日 压缩一帧
        * CompressFrame              :    
        * ULONGLONG dwTick           :    
        * LPBITMAPINFOHEADER pbih    :    
        * LPBYTE pBits               :    
        **************************************************************************************************/
        BOOL CompressFrame(ULONGLONG dwTick, LPBITMAPINFOHEADER pbih, LPBYTE pBits)
        {
            BOOL retval = 0;
    
            if (info.fccHandler == FCCX264)
            {
                retval = m_264.AddFrame(dwTick, pbih, pBits);
            }
    
            return retval;
        }
    
        /**************************************************************************************************
        * ULONGLONG       :    2013年9月8日 防止毫秒时刻转回来
        * GetTickCount    :    
        * DWORD dwTick    :    
        **************************************************************************************************/
        ULONGLONG GetTickCount(DWORD dwTick)
        {
            ULONGLONG t = dwTick;
            if (dwTick < info.lTickEnd)
            {
                t += 0x100000000;
            }
            return t;
        }
    
        /**************************************************************************************************
        * BOOL               :    2013年9月8日 内部使用打开录像文件
        * Open               :    
        * LPCTSTR pszFile    :    
        **************************************************************************************************/
        BOOL Open(LPCTSTR pszFile)
        {
            if (info.fccHandler == FCCX264)
                return m_264.Open(pszFile, &info.bih);
    
            return FALSE;
        }
    
        /**************************************************************************************************
        * int                    :    2013年9月8日 把文件模板转成真正的文件名
        * GetFileName            :    返回替换的模板个数
        * char* pszFile          :    
        * LPCTSTR pszTemplate    :    
        * SYSTEMTIME* pst        :    
        **************************************************************************************************/
        int GetFileName(char* pszFile, LPCTSTR pszTemplate, SYSTEMTIME* pst)
        {
            CString szf(pszTemplate);
    
            int nr = 0;
    
            char szi[8] = {0};
            __sprintf(szi), "%04d", pst->wYear);
            nr += szf.Replace("{y}", szi);
    
            __sprintf(szi), "%02d", pst->wMonth);
            nr += szf.Replace("{m}", szi);
    
            __sprintf(szi), "%02d", pst->wDay);
            nr += szf.Replace("{d}", szi);
    
            __sprintf(szi), "%02d", pst->wHour);
            nr += szf.Replace("{h}", szi);
    
            __sprintf(szi), "%d", pst->wHour);
            nr += szf.Replace("{H}", szi);
    
            __sprintf(szi), "%02d", pst->wMinute);
            nr += szf.Replace("{M}", szi);
    
            __sprintf(szi), "%02d", pst->wSecond);
            nr += szf.Replace("{s}", szi);
    
            __strncpy(pszFile, (LPCTSTR)szf, _MAX_PATH);
    
            return nr;
        }
    
        /**************************************************************************************************
        * LPBYTE                      :    2013年9月8日 叠加文字
        * Overlay                     :    
        * LPBITMAPINFOHEADER pdbih    :    
        * LPBYTE pdBits               :    
        * SYSTEMTIME st               :    
        * DWORD lFrameIndex           :    
        **************************************************************************************************/
        LPBYTE Overlay(LPBITMAPINFOHEADER pdbih, LPBYTE pdBits, SYSTEMTIME st, DWORD lFrameIndex)
        {
            //叠加文字
            if (info.Param.oiText[0])
            {
                //计算时间
    
                //把[T]替换为时间,把[F]替换为帧号[t]为简写时间
                char szt[64] = {0};
                char szT[64] = {0};
                char szm[64] = {0};
    
                __sprintf(szT), "%04d年%02d月%02d日 %02d:%02d:%02d",
                    st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond);
    
                __sprintf(szt), "%04d-%02d-%02d %02d:%02d:%02d",
                    st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond);
    
                __sprintf(szm), "%03d", st.wMilliseconds);
    
                char szf[32] = {0};
                __sprintf(szf), "%d", lFrameIndex);
    
                CString szOverlay(info.Param.oiText);
                szOverlay.Replace("[T]", szT);
                szOverlay.Replace("[t]", szt);
                szOverlay.Replace("[F]", szf);
                szOverlay.Replace("[m]", szm);
                szOverlay.Replace("[N]", "rn");
    
                if (_OT_GetTextBitmap(&m_BufOverlayText, &info.Param.oiFormat.lfFont, szOverlay, pdbih->biWidth))
                {
                    OT_FLAGS of = {0};
                    of.nPositionType = 0;                            //0 位置 1 下面水平条
                    of.nPositionX = info.Param.oiFormat.nPosX;            //位置坐标
                    of.nPositionY = info.Param.oiFormat.nPosY;            //位置坐标
                    of.lfFont.lfFont = info.Param.oiFormat.lfFont;        //字体和颜色(前景)
                    of.lfFont.rgbFont = info.Param.oiFormat.crColor;
                    of.nBkTransparent = 100 - info.Param.oiFormat.nBackGround * 25;
                    of.nEdgeWidth = info.Param.oiFormat.nEdgeWidth;            //边框宽度(用背景颜色)边框
                    of.crBackground = RGB(0, 0, 0);
                    of.nTransparent = 0;        //100 全透明 0 背景颜色(背景)
                    of.bAutoWhiteBlack = info.Param.oiFormat.bAutoWhiteBlack;    //2011年11月29日 自动黑白字
    
                    _OT_OverTextBitmap4(&m_BufOverlayText, pdbih, pdBits, pdbih->biSizeImage,
                        FALSE,
                        0,
                        0,
                        &of);
                }
            }
    
            return pdBits;
        }
    };
    
    
    
    #endif
    
    #ifndef __HSS_AVI_ENC_HSS__
    #define __HSS_AVI_ENC_HSS__
    
    /**************************************************************************************************
     *  2013-08-31
     新的压缩avi类,更简单,并且支持数据流(但是可能不理想,先展示不管了)
    
      关于配置文件的处理:
      可以设置配置文件,若没有设置配置文件,则使用缺省的配置,不进行配置的相关处理和调用
      因为很多编码器都可以保存配置,保存为缺省
      现在必须处理配置,是因为保存的位置可能被写保护,所以必须保存到其他地方
    
      (1) 若指定了配置文件,则自动装载配置文件,并检查配置文件是否匹配,如果匹配则使用,如果不匹配,则不使用
      (2) 若没有指定配置文件,则使用缺省
      (3) 若指定了配置文件,必须显式调用配置函数,否则不进行自动的配置
    
      配置:
          m_enc.param.fccHandler = *(DWORD*)"X264";//"XVID";
        m_enc.param.lKey = 3;
        m_enc.param.lFrameRate = 12;
        m_enc.param.szConfigFile...
    
        m_enc.Config(GetSafeHwnd());
    
      用法:
          m_enc.param.fccHandler = *(DWORD*)"X264";//"XVID";
        m_enc.param.lKey = 3;
        m_enc.param.lFrameRate = 12;
        m_enc.Open(pbih);
        m_enc.AddFrame(tick, pbih, pbits, &Buf);
        if (!Buf.IsEmpty())
        {
            //写入avi文件
        }
    
    **************************************************************************************************/
    
    
    
    #include <StringN.h>
    #include <auto_file.h>
    #include <mmsystem.h> 
    #include <vfw.h> 
    #include <__dbg.h>
    #include <HBuffer.h>
    #include <auto_folder.h>
    #include <auto_buffer.h>
    
    #pragma comment(lib, "vfw32.lib")
    
    typedef struct _AVIENC_CONFIGFILE
    {
        DWORD        mask;            //acfg
        COMPVARS    cv;
    }AVIENC_CONFIGFILE;
    
    class auto_avienc
    {
    public:
        struct
        {
            DWORD           fccHandler;        // handler of chosen compressor or
            long            lFrameRate;        // 帧率
            long            lKey;            // 关键帧数量
            long            lDataRate;        //码率
            long            lQ;                //质量
            char            szConfigFile[_MAX_PATH];    //文件
            DWORD            bChooseFccHandler : 1;        // 选择压缩编码器
        }param;
    
        struct
        {
            ULONGLONG        uTickBegin;            //开始帧的时刻
            ULONGLONG        uTickEnd;            //最后一帧时刻
            LONG            lFrameIndex;        //最后一帧索引
            BITMAPINFO        in;
            BITMAPINFO        out;
        }info;
    
        auto_buffer            m_Buf;                //压缩和状态内存, ICINFO, STATE
    
        HIC                    m_hic;                
        BOOL                m_bLoaded;            //是否装载过配置
    public:
    
        auto_avienc()
        {
            __memzero(param);
            __memzero(info);
    
            m_hic = 0;
            m_bLoaded = 0;
    
            param.fccHandler = *(DWORD*)"WMV3";
            param.lFrameRate = 15;
            param.lKey = 20;
            param.lDataRate = 0;
            param.bChooseFccHandler = 1;
        }
    
        ~auto_avienc()
        {
            Close();
        }
    
        /**************************************************************************************************
        * BOOL      :    2013年9月1日 是否打开
        * IsOpen    :    
        **************************************************************************************************/
        BOOL IsOpen()
        {
            return m_hic != 0;
        }
    
        /**************************************************************************************************
        * void          :    2013年9月1日 是否成功没有关系
        * LoadConfig    :    
        **************************************************************************************************/
        void LoadConfig()
        {
            if (param.szConfigFile[0] == 0 || m_bLoaded)
                return;
    
            if (!auto_file::Read(param.szConfigFile, &m_Buf))
                return;
    
            if (m_Buf.m_p == 0 || m_Buf.m_size == 0 || m_Buf.m_size < sizeof(ICINFO))
            {
                m_Buf.free();
                return;
            }
    
            ICINFO* pi = (ICINFO*)m_Buf.m_p;
            if (pi->dwSize != sizeof(ICINFO))
            {
                m_Buf.free();
                return;
            }
    
            if (param.fccHandler == 0 || param.bChooseFccHandler)    //使用保存的编码器类型
            {
                param.fccHandler = pi->fccHandler;
    
                __trace_file "usering %X", param.fccHandler);__trace_end;
            }
    
            m_bLoaded = TRUE;
        }
    
    
        /**************************************************************************************************
        * BOOL           :    2013年8月31日 这个检查是否配置正确,如果配置正确,则使用,不正确则不使用
        * CheckConfig    :    
        **************************************************************************************************/
        BOOL CheckConfig()
        {
            if (m_hic == 0)
                return FALSE;
    
            if (!m_Buf)
                return FALSE;
    
            ICINFO in = {0};
    
            if (0 == ICGetInfo(m_hic, &in, sizeof(in)))
            {
                __trace_file "");__trace_end;
                return FALSE;
            }
    
            ICINFO* pi = (ICINFO*)(LPBYTE)m_Buf;
            if (memcmp(pi, &in, sizeof(in)) != 0)
            {
                __trace_file "");__trace_end;
                return FALSE;
            }
    
            DWORD size = ICGetStateSize(m_hic);
    
            if (size != m_Buf.m_size - sizeof(ICINFO))
            {
                __trace_file "");__trace_end;
                return FALSE;
            }
    
            LPBYTE pState = (LPBYTE)(m_Buf.m_p) + sizeof(ICINFO);
    
            if (0 == ICSetState(m_hic, pState, size))
            {
                __trace_file "");__trace_end;
                return FALSE;
            }
    
            __trace_file "");__trace_end;
    
            return TRUE;
        }
    
        /**************************************************************************************************
        * BOOL         :    2013年8月31日 配置信息,导入以前保存的配置,如果导入的配置不对,则重新显示对话框配置
        * Config       :    
        * HWND hwnd    :    2013年9月1日 修改,如果fccHandler是0,则显示配置也选择的对话框。
        如果fccHandler指定,则只配置指定的
        **************************************************************************************************/
        BOOL Config(HWND hwnd)
        {
            LoadConfig();            //可能没装载就调用了Config
    
            //2013年9月1日
            HIC hic = 0;
            if (param.fccHandler == 0 || param.bChooseFccHandler)
            {
                COMPVARS cv = {0};
                cv.cbSize = sizeof(cv);
                cv.fccType = ICTYPE_VIDEO;
                cv.fccHandler = param.fccHandler;
                cv.dwFlags = ICMF_COMPVARS_VALID;
                if (!ICCompressorChoose(hwnd, ICMF_CHOOSE_ALLCOMPRESSORS|ICMF_CHOOSE_KEYFRAME|ICMF_CHOOSE_DATARATE, 0, 0, &cv, 0))
                {
                    __trace_file "%X", param.fccHandler);__trace_end;
                    return FALSE;
                }
    
                hic = cv.hic;
                param.fccHandler = cv.fccHandler;
                if (cv.lKey)
                    param.lKey = cv.lKey;
                if (cv.lDataRate)
                    param.lDataRate = cv.lDataRate;
            }
            else
            {
                hic = ICOpen(ICTYPE_VIDEO, param.fccHandler, ICMODE_COMPRESS|ICMODE_FASTCOMPRESS);
    
                if (hic == 0)
                    return FALSE;
    
                //下面这句话可能不对,因为XVID这个返回没有,但是实际上有对话框
                //if (ICERR_OK != ICQueryConfigure(hic))
                //    goto LABLE_CLOSE_HIC;
    
                if (ICERR_OK != ICConfigure(hic, hwnd))
                {
                    ICClose(hic);
                    return FALSE;
                }
            }
    
            //保存配置,用于下次使用
            BOOL bSucc = 0;
    
            int size = ICGetStateSize(hic);
    
            LPBYTE p = m_Buf.alloc(size + sizeof(ICINFO));
            if (p)
            {
                m_Buf.zero();
    
                if (0 != ICGetInfo(hic, (ICINFO*)p, sizeof(ICINFO)))
                {
                    p += sizeof(ICINFO);
    
                    if (ICERR_OK == ICGetState(hic, p, size))
                    {
                        if (param.szConfigFile[0])
                        {
                            auto_folder af(param.szConfigFile);
    
                            if (auto_file::Write(param.szConfigFile, &m_Buf))
                            {
                                bSucc = TRUE;
                            }
                        }
                        else
                        {
                            bSucc = TRUE;
                        }
                    }
                }
            }
    
            ICClose(hic);
    
            if (!bSucc)
            {
                m_Buf.free();
            }
    
            return bSucc;
        }
    
        /**************************************************************************************************
        * BOOL                       :    2013年8月31日 打开指定格式的录像,准备录像
        * Open                       :    
        * LPBITMAPINFOHEADER pbih    :    
        **************************************************************************************************/
        BOOL Open(LPBITMAPINFOHEADER pbih)
        {
            //关闭
            Close();
    
            info.in.bmiHeader = *pbih;
            info.out.bmiHeader = *pbih;
    
            //初始化压缩类型
            if (param.fccHandler == 0)
                param.fccHandler = *(DWORD*)"XVID";
    
            //装载配置,如果设置了 ,则自动更新为保存中的fccHandler
            //LoadConfig();
    
            m_hic = ICOpen(ICTYPE_VIDEO, param.fccHandler, ICMODE_COMPRESS|ICMODE_FASTCOMPRESS);
    
            if (m_hic == 0)
                return FALSE;
    
            __trace_file "fcc = %X", param.fccHandler);__trace_end;
    
            CheckConfig();
    
            if (ICERR_OK != ICCompressGetFormat(m_hic, &info.in, &info.out))
                return FALSE;
    
            if (ICERR_OK != ICCompressBegin(m_hic, &info.in, &info.out))
                return FALSE;
    
            return TRUE;
        }
    
        /**************************************************************************************************
        * BOOL                       :    增添一帧,根据时刻判断帧率,及是否抛弃
        * AddFrame                   :    
        * DWORD dwTick               :    
        * LPBITMAPINFOHEADER pbih    :    
        * LPBYTE pBits               :    
        * HBuffer* pBufOut           :    
        **************************************************************************************************/
        BOOL AddFrame(DWORD dwTick, LPBITMAPINFOHEADER pbih, LPBYTE pBits, HBuffer* pBufOut)
        {
            if (m_hic == 0)
                return FALSE;
    
            if (pbih->biWidth != info.in.bmiHeader.biWidth
                || pbih->biHeight != info.in.bmiHeader.biHeight
                || pbih->biBitCount != info.in.bmiHeader.biBitCount
                )
            {
                return FALSE;
            }
    
            if (dwTick == 0)
            {
                if (info.uTickBegin == 0)
                {
                    info.uTickBegin = GetTickCount();
                    info.uTickEnd = info.uTickBegin;
                    info.lFrameIndex = 0;
                }
                else
                {
                    info.lFrameIndex ++;
                }
            }
            else
            {
                ULONGLONG tick_end = 0;
                if (info.uTickBegin == 0)
                {
                    info.uTickBegin = dwTick;
                    tick_end = dwTick;
                }
                else if (dwTick < info.uTickEnd)
                {
                    //循环了
                    tick_end = dwTick + 0x100000000;
                }
                else
                {
                    tick_end = dwTick;
                }
    
                int dIndex = (int)(double((LONGLONG)(tick_end - info.uTickBegin)) / 1000.0 * param.lFrameRate + 0.5);
                if (dIndex && dIndex <= info.lFrameIndex)
                {
                    return TRUE;
                }
    
                info.uTickEnd = tick_end;
                info.lFrameIndex = dIndex;
            }
    
            LPBYTE pOut = pBufOut->GetBuffer(__max(info.out.bmiHeader.biSizeImage, info.in.bmiHeader.biSizeImage));
            if (pOut == 0)
                return FALSE;
    
            DWORD dwCkID = 0;
            DWORD dwCompFlags = 0;
            DWORD dwQuality = 0;
    
            if(ICCompress(m_hic, 
                ((info.lFrameIndex % param.lKey) == 0 ? ICCOMPRESS_KEYFRAME : 0), 
                &info.out.bmiHeader, 
                pOut,
                pbih, 
                (unsigned char *)pBits, 
                &dwCkID, 
                &dwCompFlags, 
                (LONG)info.lFrameIndex, 
                0, 
                dwQuality, 
                NULL, 
                NULL
                ) != ICERR_OK)
            {
                return FALSE;
            }
    
            //__trace_file "size=%drn", info.out.bmiHeader.biSizeImage);__trace_end;
    
            pBufOut->m_nBuffer = info.out.bmiHeader.biSizeImage;
    
            return TRUE;
        }
    
        /**************************************************************************************************
        * void     :    2013年8月31日 关闭
        * Close    :    
        **************************************************************************************************/
        void Close()
        {
            if (m_hic)
            {
                ICCompressEnd(m_hic);
    
                ICClose(m_hic);
    
                m_hic = 0;
            }
        }
    
    };
    
    
    #endif
    

    本文由澳门新葡4473网站发布于热门贴子,转载请注明出处:关于 AVI 的一些代码

    关键词:

上一篇:没有了

下一篇:没有了