yuv源码解读.doc_第1页
yuv源码解读.doc_第2页
yuv源码解读.doc_第3页
yuv源码解读.doc_第4页
yuv源码解读.doc_第5页
已阅读5页,还剩6页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

(1):以从到下逐步来解读这个软件,由YUVviewer.cpp逐步向下进行拓展:1.stdafx.h#if !defined(AFX_STDAFX_H_51FE175E_2896_4B95_82AC_E834A7145FC1_INCLUDED_)#define AFX_STDAFX_H_51FE175E_2896_4B95_82AC_E834A7145FC1_INCLUDED_#if _MSC_VER 1000#pragma once/这条预编译指令的作用是保证头文件只是被编译一次,在VC平台上使用,但是考虑到兼容性,使用还不是很多#endif / _MSC_VER 1000#define VC_EXTRALEAN/ Exclude rarely-used stuff from Windows headers#include / MFC core and standard components#include / MFC extensions#include / MFC support for Internet Explorer 4 Common Controls#ifndef _AFX_NO_AFXCMN_SUPPORT#include / MFC support for Windows Common Controls#endif / _AFX_NO_AFXCMN_SUPPORT/AFX_INSERT_LOCATION/ Microsoft Visual C+ will insert additional declarations immediately before the previous line.#endif/此处有稍许的不解,为什么这里的#endif的颜色是灰色的呢?/ !defined(AFX_STDAFX_H_51FE175E_2896_4B95_82AC_E834A7145FC1_INCLUDED_)这个函数库作为这个简易软件预编译的第一个库函数,作用是把一个project中使用的一些MFC标准头文件(如windows.h,afxwin.h)预先编译,以后该工程编译时,不在编译这部分头文件,仅仅使用预编译的结果。这样的好处就是能够加快编译的速度,节省时间和效率。2.stdafx.h的实例化:这个预编译的文件是通过编译stdafx.cpp生成,以工程命名。预编译头文件通过编译stdafx.cpp生成,以工程名命名,由于预编译的头文件的后缀是“pch”,所以编译结果文件是projectname.pch。译器通过一个头文件stdafx.h来使用预编译头文件。另外,编译器会认为,所有在指令#include ”stdafx.h前的代码都是预编译的,因此,所有CPP实现文件的第一条语句都是:#include “stdafx.h”3.#ifdef _DEBUG#undef THIS_FILEstatic char THIS_FILE = _FILE_;#endif这个预编译语句,是几乎每一个文件CPP都包含的语句。表示如果生成调试版本,要指定当前文件的名称。_FILE_是一个宏,在编译器过程中给它赋值为当前正在编译的文件名称。VC.NET默认情况下使用预编译头(/Yu),不明白的在加入新.h文件后编译时总出现fatal error C1010: 在查找预编译头指令时遇到意外的文件结尾的错误。解决方法是在include头文件的地方加上#include stdafx.h,或者打项目属性,找到“C/C+”文件夹,单击“预编译头”属性页。修改“创建/使用预编译头”属性为“不使用预编译头”。4.#if条件编译主要是进行编译时进行有选择性的挑选,注释掉一些指定的代码,以达到版本控制,防止对文件重复包含的功能。#if表达式非零就对代码进行编译。其他的一些预编译指令有:#define 宏定义#undef 未定义宏#include 文本包含#ifdef 如果宏被定义就进行编译#ifndef 如果宏未被定义就进行编译#endif 结束编译块的控制#if 表达式非零就对代码进行编译#else 作为其他预处理的剩余选项进行编译#elif 这是一种#else和#if的组合选项 /后面有例子的#line 改变当前的行数和文件名称#error 输出一个错误信息#pragma 为编译程序提供非常规的控制流信息5.#pragma once语句:#pragma语句也是我们应用预处理的一个重要的方面,主要功能是为编译程序提供非常规的控制流信息。#pragma once 的含义是在头文件最开始加入这条指令荷藕就能够保证头文件被编译一次,这条指令在VC6中便已经存在,但是基于平台兼容性的考虑,在正常的编程中不是使用很多。6.关于与的区别问题,.h格式的头文件早在98年就已经被丢弃了,iostream组件全部放入namespace std中,防止了名字污染。7.#if !defined(AFX_STDAFX_H_51FE175E_2896_4B95_82AC_E834A7145FC1_INCLUDED_)/预编译#define AFX_STDAFX_H_51FE175E_2896_4B95_82AC_E834A7145FC1_INCLUDED_这个语句的确是想了很久,还不是很明白是什么意思。主要的疑惑是:#define 后面的字符串并没有赋予一个具体的值!一种说法是AFX_STDAFX_H_51FE175E_2896_4B95_82AC_E834A7145FC1_INCLUDED_是一个文件的名称,这样用来防止重复编译的问题。重复包含(重复定义) 由于头文件包含可以嵌套,那么C文件就有可能包含多次同一个头文件,就可能出现重复定义的问题的。 通过条件编译开关来避免重复包含(重复定义) 例如 #ifndef _headerfileXXX_ define _headerfileXXX_ 文件内容 #endif8.stdafx.h下的库函数:afxwin.h:该类包括了Cwnd、CWinApp以及各种控件类,是与窗口有关的类。afxwin.h是MFC编程的必需文件,其中包含如CString,CEdit类运行所必需的头文件,最好保证该句在头文件首行;它还会调用windows.h,改头文件包含有数据类型的定义、API入口点定义和其它有用的参数信息; afx.h内定义了Cobject及其派生类,还有文件类,时间类,异常类等等,都是与窗口无关的类。afxext.h:/ Classes declared in this file/CObject/CCmdTarget;/CWnd /CButton class CBitmapButton; / Bitmap button (self-draw) class CControlBar; / control bar class CStatusBar; / status bar class CToolBar; / toolbar class CDialogBar; / dialog as control bar class CReBar; / ie40 dock bar class CSplitterWnd; / splitter manager /CView /CScrollView class CFormView; / view with a dialog template class CEditView; / simple text editor view/CDCclass CMetaFileDC; / a metafile with proxyclass CRectTracker; / tracker for rectangle objectsafxdtctl.h:封装新的日期/时间选取器控件/月历控件,用于显示一个用户可选择日期的日历afxcmn.h:afxcmn.h中声明了MFC常用的一些控件类(CListCtrl、CProgressCtrl、CToolTipCtrl等)最后附上一个比较完整的MFC类目录以及头文件:/v/mfcshouce/Class/ClassList.htm(2):YUVviewer.h 源码:/ YUVviewer.h : main header file for the YUVVIEWER application/#if !defined(AFX_YUVVIEWER_H_4E0633F3_1519_4B6F_9EF8_C0739CEC5085_INCLUDED_)#define AFX_YUVVIEWER_H_4E0633F3_1519_4B6F_9EF8_C0739CEC5085_INCLUDED_#if _MSC_VER 1000#pragma once#endif / _MSC_VER 1000#ifndef _AFXWIN_H_#error include stdafx.h before including this file for PCH#endif#include resource.h/ main symbols/ CYUVviewerApp:/ See YUVviewer.cpp for the implementation of this class/class CYUVviewerApp : public CWinApp/ WinApp是一个基类,你通过它来继承Windows应用程序对象。应用程序对象为你提供了初始化应用程序(以及它的每一/个实例)和运行应用程序所需的成员函数。public:CYUVviewerApp();/ Overrides/ ClassWizard generated virtual function overrides/AFX_VIRTUAL(CYUVviewerApp)public:virtual BOOL InitInstance();/AFX_VIRTUAL/ Implementation/AFX_MSG(CYUVviewerApp)/ NOTE - the ClassWizard will add and remove member functions here./ DO NOT EDIT what you see in these blocks of generated code !/AFX_MSGDECLARE_MESSAGE_MAP()/此处没有分号主要是由于这个表达式本身就是一个宏,是包含分号的,这个宏的定义见下面:;#define DECLARE_MESSAGE_MAP() /其中一个斜杠的作用是表示下面一行是上面一行的延续,表示处在同一行private: static const AFX_MSGMAP_ENTRY _messageEntries; protected: static AFX_DATA const AFX_MSGMAP messageMap; static const AFX_MSGMAP* PASCAL _GetBaseMessageMap(); virtual const AFX_MSGMAP* GetMessageMap() const; /AFX_INSERT_LOCATION/ Microsoft Visual C+ will insert additional declarations immediately before the previous line.#endif / !defined(AFX_YUVVIEWER_H_4E0633F3_1519_4B6F_9EF8_C0739CEC5085_INCLUDED_)(3):YUVviewerDlg.cpp文件的分析-主要的文件1.uint 类的使用:uint类提供使用表示 32 位无符号整数的数据类型的方法。 因为无符号整数只能为正,所以其最大值是 int 类最大值的两倍。由 uint 类表示的值的范围介于 0 到 4,294,967,295 (232-1) 之间。可以通过声明 uint 类型的变量并为变量赋予文本值来创建 uint 对象。 uint 类型变量的默认值为 0。uint 类主要用于像素颜色值(ARGB 和 RGBA)和 int 数据类型无法很好工作的其它情况。 例如,数字 0xFFFFFFFF 表示 Alpha 值为 255 的白色颜色值,它无法用 int 数据类型表示,因为它不在有效的 int 值范围内。2.m_sFrame是CString类型的数据,故而要采用atoi函数将其转化为整形数据,这样便于整形的运算。另外,string和CString均是字符串模板类,string为标准模板类(STL)定义的字符串类,已经纳入C+标准之中;CString(typedef CStringT CString)为Visual C+中最常用的字符串类,继承自CSimpleStringT类,主要应用在MFC和ATL编程中,主要数据类型有char(应用于ANSI),wchar_t(unicode),TCHAR(ANSI与unicode均可);char*为C编程中最常用的字符串指针,一般以0为结束标志;3.seek函数的应用:在stdio.h中定义了三个常量:0是seek_set,1是seek_cur,2是seek_end,作为三个常量来使用4.UpdateData 的使用 UpdateData(true); 用窗体上控件中的内容来更新和控件相关连的变量的值(只能更新value类型的变量) 例如:你在你的窗体中有一个Edit控件,为这个控件关联了CString类型的变量m_strName; 你在控件中添入内容之后,必须调用UpdateData(true);才能把你添入的内容传给m_strName这个变量UpdateData(false); 和上面的正好相反,还是以上面的Edit为例,当你在程序中改变了m_strName变量的内容的时候,如果你想让那个Edit也显示更新后的 m_strName,就必须调用UpdateData(false); 这样在你的Edit中才能显示更新完的变量的值!5.afx_msg 很多的消息处理函数都是以这个为开头的,afx_msg宏表示声明的是一个消息响应函数。 消息响应函数,对于类向导来说,它是一个消息处理函数的前缀,类向导生成的消息函数,分发函数,事件响应函数都以这个为前缀,如果去掉,向导将不能识别。(4):CHildWindow.cpp文件的分析1.LPBITMAPINFO的使用其定义是:typedef struct tagBITMAPINFO BITMAPINFOHEADER bmiHeader; RGBQUAD bmiColors1; BITMAPINFO; 内部的bmiheader的定义是:typedef struct tagBITMAPINFOHEADER DWORD biSize; LONG biWidth; LONG biHeight; WORD biPlanes; WORD biBitCount DWORD biCompression; DWORD biSizeImage; LONG biXPelsPerMeter; LONG biYPelsPerMeter; DWORD biClrUsed; DWORD biClrImportant; BITMAPINFOHEADER; 内部bmicolors1的定义是:typedef struct tagRGBQUAD BYTE rgbBlue; BYTE rgbGreen; BYTE rgbRed; BYTE rgbReserved; RGBQUAD;备注:对于多一个LP的原因是为了和16位的系统兼容而产生的,其实作用是相同的。2.memcpy函数的使用Void *memcpy(void *dest, void *src, unsigned int count); 用法:#include 功能:由src所指内存区域复制count个字节到dest所指内存区域。 说明:src和dest所指内存区域不能重叠,函数返回指向dest的指针。备注:这些都是对内存的直接操作3.每个像素所占的字节问题ShowGrayImage()中每个像素占用8个Bit,从而产生的图像自然是只有灰度的灰度图像;而在ShowImage()中美没个图像占用24个bit,RGB三色元素各占8个bit,这样就是彩色的图像输出4.一个关键性的绘图函数:StretchDIBits();这个函数的目的是The StretchDIBits function copies the color data for a rectangle of pixels in a DIB, JPEG, or PNG image to the specified destination rectangle. If the destination rectangle is larger than the source rectangle, this function stretches the rows and columns of color data to fit the destination rectangle. If the destination rectangle is smaller than the source rectangle, this function compresses the rows and columns by using the specified raster operation.该函数将DIB中矩形区域内像素使用的颜色数据拷贝到指定的目标矩形中。如果目标矩形比源矩形大小要大,那么函数对颜色数据的行和列进行拉伸,以与目标矩形匹配。如果目标矩形大小要比源矩形小,那么该函数通过使用指定的光栅操作对行列进行压缩。具体实现:StretchDIBits(pDC-m_hDC,0,0,iWidth,iHeight,/目标矩形的x,y(左上角),以及宽度和高度0,0,iWidth,iHeight,/源矩形的x,y(左上角),以及宽度和高度lpBuf,BmpInfo, DIB_RGB_COLORS,SRCCOPY); /m_hDc指向目标设备环境的句柄,m_hDC is equal to m_hAttribDC, the other device context wrapped by CDC/lpBuf分别是指向DIB位的指针,这些位按字节存储(DIB:设备无关位图文件,通过BITMAPINFO结构体进行描述)/bmpinfo是指向BITMAPINFO结构的指针,该结构包含有关DIB方面的信息。/RGB_COLORS表示是否提供了BITMAPINFO结构中的成员bmiColors,如果提供了,那么该bmiColors是否包含了明确的RGB值或索引。/SRCCOPY指定源像素点、目标设备环境的当前刷子和目标像素点是如何组合形成新的图像。5.CenterWindow()函数,rect类对象用来存储一个矩形框的左上角坐标、宽度和高度。6.OnPaint函数:当Windows或应用程序请求重画应用程序窗口的一部分时,框架调用这个成员函数。WM_PAINT在调用UpdateWindow或RedrawWindow成员函数时发出。当设置了RDW_INTERNALPAINT标志并调用RedrawWindow成员函数时,窗口可能会接收到内部重画消息。在这种情况下,窗口可能没有更新区域。应用程序必须调用GetUpdateRect成员函数以确定窗口是否具有更新区域。如果GetUpdateRect返回0,则应用程序不应调用BeginPaint和EndPaint成员函数。应用程序负责检查是否需要内部重画或更新,这可通过查看每条WM_PAINT消息的内部数据结构来完成,因为一条WM_PAINT可能是由于一个无效区域或由于使用RDW_INTERNALPAINT标志调用了RedrawWindow成员函数而引起的。7.OnCreate()函数:不产生窗口,只是在窗口显示前设置窗口的属性如风格、位置等,create()负责注册并产生窗口。create()不是对应于消息wm_create的,oncreate()才是。create()只用于产生窗口,像动态创建控件中的create()一样。(5):YUK源码分析概述:YUV是被欧洲电视系统所采用的一种颜色编码方法(属于PAL),是PAL和SECAM模拟彩色电视制式采用的颜色空间。 采用YUV色彩空间的重要性是它的亮度信号Y和色度信号U、V是分离的。 。其中“Y”表示明亮度(Luminance或Luma),也就是灰阶值;而“U”和“V” 表示的则是色度(Chrominance或Chroma),作用是描述影像色彩及饱和度,用于指定像素的颜色。“ “亮度”是透过RGB输入信号来建立的,方法是将RGB信号的特定部分叠加到一起。“色度”则定义了颜色的两个方面色调与饱和度,分别用Cr和CB来表示。其中,Cr反映了RGB输入信号红色部分与RGB信号亮度值之间的差异。而Cb反映的是RGB输入信号蓝色部分与RGB信号亮度值之同的差异。 在DirectShow中,常见的RGB格式有RGB1、RGB4、RGB8、RGB565、RGB555、RGB24、RGB32、ARGB32等;常见的YUV格式有YUY2、YUYV、YVYU、UYVY、AYUV、Y41P、Y411、Y211、IF09、IYUV、YV12、YVU9、YUV411、YUV420等。 主要的采样格式有YCbCr 4:2:0、YCbCr 4:2:2、YCbCr 4:1:1和 YCbCr 4:4:4。其中YCbCr 4:1:1 比较常用,其含义为:每个点保存一个 8bit 的亮度值(也就是Y值),每 2x2 个点保存一个 Cr 和Cb 值, 图像在肉眼中的感觉不会起太大的变化。 1.StdAfx.h,头文件是工程编译时将MFC的头文件进行预编译,这样以后使用时就可以免于编译,以加速编译速度,节省时间和效率。而且此头文件通过StdAfx.cpp来具体的实现。其中包括afxwin.h(各种控件和窗口类),afxext.h(MFC一些扩展类,包括按钮等一些控件),afxdtctl.h(封装新的日期/时间选取器控件/月历控件,用于显示一个用户可选择日期的日历 ),afxcmn.h(MFC常用控件类)。2.Resource.h,此头文件中定义了宏,来代替相应的数据,增加可读性;3.Convert.h,此头文件中定义了一个颜色空间转换类ColorSpaceConversions,定义了类的四个转换函数,分别是:RGB24_to_YV1;YV12_to_RGB24();YVU9_to_YV12();YUY2_to_YV12();YV12_to_YVU9();YV12_to_YUY2();4.YUVviewer.h,定义了一个继承自CWinApp的类CYUVviewerApp;5.ChildWindow.h,CChildWindow继承自CFrameWnd,是窗口类,其中类内的元素有:iWidth,iHeight,m_nzoom,bColorImage,对象句柄hloc,*inSeqName,整型的 m_iCount等等,定义了两个函数ShowImage()和showGrayImage()以及函数CenterWindow();以及作为消息处理的OnPaint();OnCreate(LPCREATESTRUCT lpCreateStruct);6.CYUVviewerDlg.h,该类继承自CDialog,用于包含控件窗口的对话框对象,加入了各种控件。该类中包含了各种控件的对象,CButton,CComboBox,m_cmbSize等,还用afx_msg定义了消息处理函数OnOpenfile(),OnNext(),OnCancel()等等,定义了CChildWindow *m_pWnd36;inSeqName3664,inSeqence36_MAX_PATH,字符串类型m_sFrameRate, 定义句柄hPlayTemp;还定义了CFile *m_pFile36文件。这个类的作用定义了需要的控件以及消息处理函数。7.ChildWindow.cpp,此文件时对ChildWindow.h头文件中的函数的具体实现。CChildWindow()是构造函数,这里定义为空的函数;CChildWindow()是析构函数,释放相应的内存;重载的构造函数,通过参数传值,获取width,height,以及bool类型的bColor,并通过传值获取一个CFrameWnd *pParentWnd(CFrameWnd是CChildWindow的父类),此构造函数通过malloc申请相应的字节空间,并且判断是否有足够的空间分配给RGB以及RGBbuf,如果分配空间失败,显示“Couldnt allocate memory for RGBbuf”。ShowGrayImage()中每个像素占用8个Bit,从而产生的图像自然是只有灰度的灰度图像;而在ShowImage()中美没个图像占用24个bit,RGB三色元素各占8个bit,这样就是彩色的图像输出。通过SetStretchBltMode ()函数设置位图扩展后的状态或者说对像素的处理方式。函数StretchDIBits()作用是画图,将矩形区域内像素使用的颜色数据拷贝到指定的目标矩形中。 CenterWindow()函数,该函数将输出

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论