int |
avformat_write_header (AVFormatContext *s,AVDictionary **options) |
|
Allocate the stream private data and write the stream header to an output media file. |
|
|
int |
av_write_frame (AVFormatContext *s,AVPacket *pkt) |
|
Write a packet to an output media file. |
|
|
int |
av_interleaved_write_frame (AVFormatContext *s,AVPacket *pkt) |
Write a packet to an output media file ensuring correct interleaving.
测试发现当硬盘空间不足时,av_interleaved_write_frame函数奔溃,解决办法,首先需要对ffmpeg写avi的函数的每个返回值都进行处理,比如avformat_write_header失败后,不要在调用av_interleaved_write_frame进行录像了,另外增加一个对磁盘空间进行判断的函数,GetDiskFreeSpace函数或GetDiskFreeSpaceEx函数;GetDiskFreeSpace函数计算得到的大小不正确;所以最好使用GetDiskFreeSpaceEx函数;这两个函数的调用方法如下:
int RecordGetDiskFreeSpace(std::string strDiskPartition)
{
DWORD sector,byte,cluster,free;
int freespace;
std::string substring;
int pos=strDiskPartition.find_first_of(":");
substring=strDiskPartition.substr(0,pos+1);
substring=substring.append("\\");
CString strDisk=string2CString(substring);
GetDiskFreeSpace(strDisk,§or,&byte,&free,&cluster);
freespace=(free)*(byte)*(sector)/1024/1024;
return freespace;
}
其中strDiskPartition为传入的路径;
GetDiskFreeSpaceEx调用方法如下:
// testFreeDiskSpace.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include
#include
#include
typedef BOOL (WINAPI *PGETDISKFREESPACEEX)(LPCSTR,
PULARGE_INTEGER, PULARGE_INTEGER, PULARGE_INTEGER);
HANDLE m_ThreadExitEvent = CreateEvent(NULL,FALSE,FALSE,NULL);
BOOL MyGetDiskFreeSpaceEx(LPCSTR pszDrive,int &spaceDiskSize)
{
PGETDISKFREESPACEEX pGetDiskFreeSpaceEx;
__int64 i64FreeBytesToCaller, i64TotalBytes, i64FreeBytes=0;
DWORD dwSectPerClust,
dwBytesPerSect,
dwFreeClusters,
dwTotalClusters;
BOOL fResult;
pGetDiskFreeSpaceEx = (PGETDISKFREESPACEEX) GetProcAddress(
GetModuleHandle(_T("kernel32.dll")),
"GetDiskFreeSpaceExA");
if (pGetDiskFreeSpaceEx)
{
fResult = pGetDiskFreeSpaceEx (pszDrive,
(PULARGE_INTEGER)&i64FreeBytesToCaller,
(PULARGE_INTEGER)&i64TotalBytes,
(PULARGE_INTEGER)&i64FreeBytes);
// Process GetDiskFreeSpaceEx results.
if(fResult)
{
//printf("Total free bytes = %I64d\n", i64FreeBytes);
spaceDiskSize=(int)(i64FreeBytes>>20);
}
return fResult;
}
else
{
fResult = GetDiskFreeSpaceA (pszDrive,
&dwSectPerClust,
&dwBytesPerSect,
&dwFreeClusters,
&dwTotalClusters);
// Process GetDiskFreeSpace results.
if(fResult)
{
//printf("Total free bytes = I64d\n", dwFreeClusters*dwSectPerClust*dwBytesPerSect);
spaceDiskSize=(int)(i64FreeBytes>>20);
}
return fResult;
}
}
void ComputeDiskFreeSizeThread(void *arg)
{
while (1)
{
int iDiskspace=0;
MyGetDiskFreeSpaceEx ("F:\\",iDiskspace);
printf("disk free space=%d\n",iDiskspace);
Sleep(1000*60);
}
SetEvent(m_ThreadExitEvent);
}
void WaitForThreadExit(HANDLE ExitEvent)
{
DWORD dwRet = 0;
MSG msg;
while (TRUE)
{
//wait for m_hThread to be over,and wait for
//QS_ALLINPUT(Any message is in the queue)
dwRet = MsgWaitForMultipleObjects (1, &ExitEvent, FALSE, INFINITE, QS_ALLINPUT);
switch(dwRet)
{
case WAIT_OBJECT_0:
break; //break the loop
case WAIT_OBJECT_0 + 1:
//get the message from Queue
//and dispatch it to specific window
PeekMessage(&msg, NULL, 0, 0, PM_REMOVE);
DispatchMessage(&msg);
continue;
default:
break; // unexpected failure
}
break;
}
return;
}
int _tmain(int argc, _TCHAR* argv[])
{
_beginthread(ComputeDiskFreeSizeThread, 0, NULL);
WaitForThreadExit(m_ThreadExitEvent);
return 0;
}
参考msdn:
GetDiskFreeSpaceEx Function
Retrieves information about the amount of space that is available on a disk volume, which is the total amount of space, the total amount of free space, and the total amount of
free space available to the user that is associated with the calling thread.
BOOL WINAPI GetDiskFreeSpaceEx(
__in LPCTSTR lpDirectoryName,
__out PULARGE_INTEGER lpFreeBytesAvailable,
__out PULARGE_INTEGER lpTotalNumberOfBytes,
__out PULARGE_INTEGER lpTotalNumberOfFreeBytes
);
Parameters
lpDirectoryName
A directory on the disk.
If this parameter is NULL, the function uses the root of the current disk.
If this parameter is a UNC name, it must include a trailing backslash, for example,\\MyServer\MyShare\.
This parameter does not have to specify the root directory on a disk. The function accepts any directory on a disk.
The calling application must have FILE_LIST_DIRECTORY access rights for this directory.
lpFreeBytesAvailable
A pointer to a variable that receives the total number of free bytes on a disk that are available to the user who is associated with the calling thread.
This parameter can be NULL.
If per-user quotas are being used, this value may be less than the total number of free bytes on a disk.
lpTotalNumberOfBytes
A pointer to a variable that receives the total number of bytes on a disk that are available to the user who is associated with the calling thread.
This parameter can be NULL.
If per-user quotas are being used, this value may be less than the total number of bytes on a disk.
To determine the total number of bytes on a disk or volume, use IOCTL_DISK_GET_LENGTH_INFO.
lpTotalNumberOfFreeBytes
A pointer to a variable that receives the total number of free bytes on a disk.
This parameter can be NULL.
Return Value
If the function succeeds, the return value is nonzero.
If the function fails, the return value is zero (0). To get extended error information, call GetLastError.
Remarks
The values obtained by this function are of the type ULARGE_INTEGER. Do not truncate these values to 32 bits.
The GetDiskFreeSpaceEx function returns zero (0) for lpTotalNumberOfFreeBytes and lpFreeBytesAvailable for all CD requests unless the disk is an unwritten CD in a CD-RW drive.
Symbolic link behavior—If the path points to a symbolic link, the operation is performed on the target.
GetDiskFreeSpace Function
Retrieves information about the specified disk, including the amount of free space on the disk.
The GetDiskFreeSpace function cannot report volume sizes that are greater than 2 gigabytes (GB). To ensure that your application works with large capacity hard drives, use the
GetDiskFreeSpaceEx function.
BOOL WINAPI GetDiskFreeSpace(
__in LPCTSTR lpRootPathName,
__out LPDWORD lpSectorsPerCluster,
__out LPDWORD lpBytesPerSector,
__out LPDWORD lpNumberOfFreeClusters,
__out LPDWORD lpTotalNumberOfClusters
);
Parameters
lpRootPathName
The root directory of the disk for which information is to be returned. If this parameter is NULL, the function uses the root of the current disk. If this parameter is a UNC
name, it must include a trailing backslash (for example, \\MyServer\MyShare\). Furthermore, a drive specification must have a trailing backslash (for example, C:\). The calling
application must have FILE_LIST_DIRECTORY access rights for this directory.
lpSectorsPerCluster
A pointer to a variable that receives the number of sectors per cluster.
lpBytesPerSector
A pointer to a variable that receives the number of bytes per sector.
lpNumberOfFreeClusters
A pointer to a variable that receives the total number of free clusters on the disk that are available to the user who is associated with the calling thread.
If per-user disk quotas are in use, this value may be less than the total number of free clusters on the disk.
lpTotalNumberOfClusters
A pointer to a variable that receives the total number of clusters on the disk that are available to the user who is associated with the calling thread.
If per-user disk quotas are in use, this value may be less than the total number of clusters on the disk.
Return Value
If the function succeeds, the return value is nonzero.
If the function fails, the return value is zero. To get extended error information, call GetLastError.
Remarks
The GetDiskFreeSpaceEx function lets you avoid some of the arithmetic that is required by the GetDiskFreeSpace function.
Symbolic link behavior—If the path points to a symbolic link, the operation is performed on the target.