ffmpeg av_interleaved_write_frame 在磁盘满的情况下报错,提示除数为0

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.

 

 


 

你可能感兴趣的:(FFMPEG,流媒体开源技术)