博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
关于获取yuv帧数问题
阅读量:4055 次
发布时间:2019-05-25

本文共 4324 字,大约阅读时间需要 14 分钟。

读yuv文件的时候需要获取yuv文件的帧数,以便建立循环一帧一帧读取,这时候要获取yuv的帧数。

方法:首先用fopen函数打开一个yuv文件,接着用fseek(   fYUV,   0L,   SEEK_END   ),再接着用ftell来获取文件的大小size,由于用的是yuv420,因此用size/(WIDTH*HEIGHT*1.5)即获得了yuv文件的总帧数。

需要注意的是:fseek函数已把指向yuv文件的开始的指针改变了位置,即此时的指针已指向文件的结尾处,由于接着要进行文件的读写,这时候应该用rewind()函数把指针直接重新指到文件开始处。

 

ps:获得文件大小的几种方法

 

#include 
<
iostream
>
#include 
<
io.h
>
#include 
<
sys/stat.h
>
#include 
<
afx.h
>
#define
 _AFXDLL
using
 
namespace
 std;
void
 main()
{
    
//
 此文件在工程打开状态下为不可访问
    
char
*
 filepath 
=
 
"
..//test.ncb
"
;
    
//
 方法一
    
struct
 _stat info;
    _stat(filepath, 
&
info);
    
int
 size 
=
 info.st_size;
    cout
<<
size
<<
endl;
    
//
 方法二
    FILE
*
 file 
=
 fopen(filepath, 
"
rb
"
);
    
if
 (file)
    {
        
int
 size 
=
 filelength(fileno(file));
        cout
<<
size
<<
endl;
        fclose(file);
    }
    
//
 方法三
    CFile cfile;
    
if
 (cfile.Open(filepath, CFile::modeRead))
    {
        
int
 size 
=
 cfile.GetLength();
        cout
<<
size
<<
endl;
    }
    
//
 方法四
    HANDLE handle 
=
 CreateFile(filepath, FILE_READ_EA, FILE_SHARE_READ, 
0
, OPEN_EXISTING, 
0
0
);
    
if
 (handle 
!=
 INVALID_HANDLE_VALUE)
    {
        
int
 size 
=
 GetFileSize(handle, NULL);
        cout
<<
size
<<
endl;
        CloseHandle(handle);
    }
}

 

 

VS2005:若编译链接不通过,需要修改工程设置:

(1) Configuration Properties -> C/C++ -> Code Generation -> Runtime Library, 选择"Multi-threaded Debug(/MTd)"

(2) Configuration Properties -> Linker -> Input -> Ignore Specific Library, 输入"msvcprtd.lib"

 

例子中,由于在工程打开状态下,test.ncb文件无法打开,所以方法二、三无法获取文件大小,因此推荐使用方法一、四。

 

另:文件的随机读写

前面介绍了对文件的顺序读写操作,这些操作都是从文件的第一个有效数据(或某个位置)开始的,依照数据在文件存储设备中的先后次序进行读写,在读写过程中,文件位置指针自动移动。但在实际应用中,往往需要对文件中某个特定位置处的数据进行处理,换言之,就是读完一个字节的内容后,并不一定要读写其后续的字节数据,可能会强制性地将文件位置指针移动到用户所希望的特定位置,读取该位置上的数据,这就是随机读写文件。

C语言提供了对文件的随机读写功能。在随机方式下,系统并不按数据在文件中的物理顺序进行读写,而是可以读取文件任何有效位置上的数据,也可以将数据写入到任意有效的位置。

C语言通过提供文件定位函数来实现随机读写功能。

1. 获取文件位置指针当前值的函数ftell()

ftell()函数的功能是获得并返回文件位置指针的当前值。ftell()函数的原型定义为:

long ftell(FILE * fp);

其中参数fp是文件型指针,指向当前操作的文件。

rewind()函数的返回值为文件位置指针的当前位置。如果rewind()函数执行时出现错误,则返回长整型的-1(即-1L)。

2. 重置文件位置指针的函数rewind()

rewind()函数的功能是使文件的位置指针移到文件的开头处。rewind()函数的原型定义为:

void rewind(FILE * fp);

其中参数fp是文件型指针,指向当前操作的文件。

rewind()函数没有返回值,其作用在于:如果要对文件进行多次读写操作,可以在不关闭文件的情况下,将文件位置指针重新设置到文件开头,从而能够重新读写此文件。如果没有rewind()函数,每次重新操作文件之前,需要将该文件关闭后再重新打开,这种方式不仅效率低下,而且操作也不方便。使用rewind()函数便能克服这一缺陷。

 

【例11.7  有一个文本文件file1.dat,两次读写它的内容,第一次将它的内容显示在屏幕上,第二次将它的内容复制到另一个文件fiel2.dat上。以下为实现该功能的程序代码。

 

#include "stdio.h"

void main()

{

FILE *fp1,*fp2;

fp1=fopen("file1.dat","r");

fp2=fopen("fiel2.dat","w");

while(!feof(fp1))

putchar(getc(fp1));

rewind(fp1);

while(!feof(fp1))

putc(getc(fp1),fp2);

fclose(fp1);

fclose(fp2);

}

3. 移动文件位置指针的函数fseek()

函数fseek()可以实现改变文件位置指针到指定位置的操作。fseek()函数的原型定义为:

int fseek(FILE * fp,long offset,int origin);

即:int fseek(文件类型指针,位移量,起始点);

其中fp为打开的文件指针,参数offset为文件位置指针移动的位移量(单位为字节),参数origin指示出文件位置指针移动的起始点(或称基点)位置。当执行fseek()函数后,文件位置指针新的位置是以起始点为基准,向后(offset为正值)/或向前(offset为负值)移动offset个字节。文件位置指针的新位置可以用公式“origin+offset”来计算得出。

二进制文件的基点origin 可以取以下三个常量值之一:

⑴SEEK_SET(也可直接用数字0表示):此时文件位置指针从文件的开始位置进行移动;

⑵SEEK_CUP(对应值为1): 此时文件位置指针从文件的当前位置进行移动;

⑶SEEK_END(对应值为2): 此时文件位置指针从文件的结束位置进行移动。

文本文件的基点origin只能取SEEK_SET常量值(或取0值),而origin的值应为0。

fseek()函数常用于二进制文件中,对于文本文件则不常使用,因为文本文件要进行字符的转换,这会为文件位置指针的计算带来混乱。fseek()函数的调用形式为:

fseek()函数返回一个整形值。如果函数执行成功,返回0值;否则,返回一个非0值。

下面给出fseek()函数调用的两个例子:

①fseek(fp,50L,1),将fp指向的文件的位置指针向后移动到离当前位置50个字节处;

②fseek(fp,-100L,2),将fp指向的文件的位置指针从文件末尾处向前回退100个字节。

4. 应用实例

【例11.8 在当前目录下有一二进制文件information.dat,文件中存储有学生信息数据。编程实现按指定位置读取该文件中的数据,显示到屏幕上,并统计文件的总字节数目,也显示到屏幕上。

以下为实现该功能的程序代码。

 

#include "stdio.h"

struct student

{

char name[20];int num;

};

/*主函数*/

main()

{

int i=0;

long n=0;

FILE *fp=NULL;

struct  student a = {0};

fp = fopen("information.dat","rb");

if(fp==NULL)

{

printf("Can't open!/n");

exit(0);

}

printf("Record in file information.dat:/n");

for(i=1;i<5;i+=2)

{

fseek(fp,i*sizeof(struct student),SEEK_SET);  /*定位文件位置指针*/

n=ftell(fp);   /*获取文件位置指针当前值*/

fread(&a,sizeof(struct student),1,fp);   /*读取数据块*/

printf("current:%ldth byte,%dth record:%s  %d/n",n,i+1,a.name,a.num);

fseek(fp,-3l*sizeof(struct student),2);  /*重新定位文件位置指针*/

n=ftell(fp);   /*重新读取数据块*/

fread(&a,sizeof(struct student),1,fp);

printf("current:%ldth btype,record is:%s  %d/n",n,a.name,a.num);

rewind(fp);   /*重置文件位置指针到文件开始*/

n=ftell(fp);  /*获取文件位置指针当前值*/

fread(&a,sizeof(struct student),1,fp);

printf("current:%ldth btype,frist record :%s  %d/n",n,a.name,a.num);

/*重新定位文件位置指针到文件尾部*/

fseek(fp,-0l*sizeof(struct student),2);

n=ftell(fp);    /*计算文件总字节数目*/

printf("total bytes:%ld/n",n);   /*显示文件总字节数目*/

fclose(fp);

}

getch();

}

转载地址:http://auqci.baihongyu.com/

你可能感兴趣的文章
01Java基础语法-16. while循环结构
查看>>
01Java基础语法-19. 循环跳转控制语句
查看>>
Django框架全面讲解 -- Form
查看>>
今日互联网关注(写在清明节后):每天都有值得关注的大变化
查看>>
”舍得“大法:把自己的优点当缺点倒出去
查看>>
[今日关注]鼓吹“互联网泡沫,到底为了什么”
查看>>
[互联网学习]如何提高网站的GooglePR值
查看>>
[关注大学生]求职不可不知——怎样的大学生不受欢迎
查看>>
[关注大学生]读“贫困大学生的自白”
查看>>
[互联网关注]李开复教大学生回答如何学好编程
查看>>
[关注大学生]李开复给中国计算机系大学生的7点建议
查看>>
[茶余饭后]10大毕业生必听得歌曲
查看>>
VC++ MFC SQL ADO数据库访问技术使用的基本步骤及方法
查看>>
VUE-Vue.js之$refs,父组件访问、修改子组件中 的数据
查看>>
Python自动化之pytest常用插件
查看>>
Python自动化之pytest框架使用详解
查看>>
【正则表达式】以个人的理解帮助大家认识正则表达式
查看>>
性能调优之iostat命令详解
查看>>
性能调优之iftop命令详解
查看>>
非关系型数据库(nosql)介绍
查看>>