DrGraph图形博士

导航

在CB2010中调用ffmpeg(2)

DrGraph, QQ:282397369

2014-03-02

 

  1. 第一个测试程序

从网上找到一个例子,测试获取媒体文件的信息功能是否OK,以此来调试一下FFMPEG。

  1. 新建工程

新建工程,工程名称为ffmpegTest,把所有的DLL拷贝到可执行文件目录下。

  1. 测试代码

一个按钮单击事件处理:

void __fastcall TFFMPEGTestForm::Button1Click(TObject *Sender) {

    av_register_all();

    AVFormatContext * pFormatCtx = NULL;

    int err = 0;

    const char *fileName = "c:\\test.mp4";

    err = av_open_input_file(&pFormatCtx, fileName, NULL, 0, NULL);

    if (err != 0) {

        // break ;

    }

    err = av_find_stream_info(pFormatCtx);

    if (err < 0) {

        // break ;

    }

    for (uint32_t i = 0; i < pFormatCtx->nb_streams; i++) {

        // stream 结构数据

        AVStream *pStream = pFormatCtx->streams[i];

        // 帧率信息

        AVRational frameRate = pStream->r_frame_rate;

        // 时间单位比率

        AVRational timeBase = pStream->time_base;

        // stream duration

        int64_t duration = pStream->duration;

 

        // 获取Codec数据结构

        AVCodecContext *pCodecCtx = pStream->codec;

        AVMediaType codecType = pCodecCtx->codec_type;

 

        AVCodecID codecId = pCodecCtx->codec_id;

        // enum AVCodecID codec_id; /* see AV_CODEC_ID_xxx */

 

        if (codecType == AVMEDIA_TYPE_VIDEO) {

            // 获取Video基本信息

            int width = pCodecCtx->width;

            int height = pCodecCtx->height;

            PixelFormat pixelFormat = pCodecCtx->pix_fmt;

        }

        else if (codecType == AVMEDIA_TYPE_AUDIO) {

            // 获取Audio基本信息

            int channels = pCodecCtx->channels;

            int sample_rate = pCodecCtx->sample_rate;

            AVSampleFormat sampleFmt = pCodecCtx->sample_fmt;

        }

    }

    // 释放

    if (pFormatCtx != NULL) {

        av_close_input_file(pFormatCtx);

        pFormatCtx = NULL;

    }

}

  1. 头文件

编译会发现一大堆的未定义错误,加入头文件

extern "C" {

#include "libavcodec/avcodec.h"

#include "libavformat/avformat.h"

#include "libavutil/avutil.h"

#include "libavutil/mem.h"

#include "libavutil/fifo.h"

#include "libswscale/swscale.h"

}

  1. Inttypes.h

然后会提示[BCC32 Error] common.h(34): E2209 Unable to open include file 'inttypes.h'

在include目录下新建一个文本文件,命名为inttypes.h,其内容:

#ifndef _INTTYPES_H_ALL_

#define _INTTYPES_H_ALL_

 

// _INTTYPES_H_SYS_: 编译器是否提供了<inttypes.h>

#undef _INTTYPES_H_SYS_

#if defined(__GNUC__) // GCC.

#define _INTTYPES_H_SYS_

#elif defined(_MSC_VER) // MSVC. VC2010仍不支持.

#elif defined(__BORLANDC__) // BCB. BCB6仍不支持.

#else

#define _INTTYPES_H_SYS_ // 假设其他编译器支持C99.

#endif // _INTTYPES_H_SYS_

 

 

#ifdef _INTTYPES_H_SYS_

// 使用编译器提供的<inttypes.h>

#include <inttypes.h>

#else

// 采用自定义的inttypes.h. 参考了 msinttypes: http://code.google.com/p/msinttypes/

 

#ifndef _MSC_INTTYPES_H_ // [

#define _MSC_INTTYPES_H_

 

#include "stdint.h"

 

// 7.8 Format conversion of integer types

 

typedef struct {

intmax_t quot;

intmax_t rem;

} imaxdiv_t;

 

// 7.8.1 Macros for format specifiers

 

#if !defined(__cplusplus) || defined(__STDC_FORMAT_MACROS) // [ See footnote 185 at page 198

 

// The fprintf macros for signed integers are:

#define PRId8 "d"

#define PRIi8 "i"

#define PRIdLEAST8 "d"

#define PRIiLEAST8 "i"

#define PRIdFAST8 "d"

#define PRIiFAST8 "i"

 

#define PRId16 "hd"

#define PRIi16 "hi"

#define PRIdLEAST16 "hd"

#define PRIiLEAST16 "hi"

#define PRIdFAST16 "hd"

#define PRIiFAST16 "hi"

 

#if defined(_MSC_VER) && _MSC_VER<=1200 // VC6

#define PRId32 "d"

#define PRIi32 "i"

#define PRIdLEAST32 "d"

#define PRIiLEAST32 "i"

#define PRIdFAST32 "d"

#define PRIiFAST32 "i"

#else

#define PRId32 "I32d"

#define PRIi32 "I32i"

#define PRIdLEAST32 "I32d"

#define PRIiLEAST32 "I32i"

#define PRIdFAST32 "I32d"

#define PRIiFAST32 "I32i"

#endif

 

#define PRId64 "I64d"

#define PRIi64 "I64i"

#define PRIdLEAST64 "I64d"

#define PRIiLEAST64 "I64i"

#define PRIdFAST64 "I64d"

#define PRIiFAST64 "I64i"

 

#define PRIdMAX "I64d"

#define PRIiMAX "I64i"

 

#define PRIdPTR "Id"

#define PRIiPTR "Ii"

 

// The fprintf macros for unsigned integers are:

#define PRIo8 "o"

#define PRIu8 "u"

#define PRIx8 "x"

#define PRIX8 "X"

#define PRIoLEAST8 "o"

#define PRIuLEAST8 "u"

#define PRIxLEAST8 "x"

#define PRIXLEAST8 "X"

#define PRIoFAST8 "o"

#define PRIuFAST8 "u"

#define PRIxFAST8 "x"

#define PRIXFAST8 "X"

 

#define PRIo16 "ho"

#define PRIu16 "hu"

#define PRIx16 "hx"

#define PRIX16 "hX"

#define PRIoLEAST16 "ho"

#define PRIuLEAST16 "hu"

#define PRIxLEAST16 "hx"

#define PRIXLEAST16 "hX"

#define PRIoFAST16 "ho"

#define PRIuFAST16 "hu"

#define PRIxFAST16 "hx"

#define PRIXFAST16 "hX"

 

#if defined(_MSC_VER) && _MSC_VER<=1200 // VC6

#define PRIo32 "o"

#define PRIu32 "u"

#define PRIx32 "x"

#define PRIX32 "X"

#define PRIoLEAST32 "o"

#define PRIuLEAST32 "u"

#define PRIxLEAST32 "x"

#define PRIXLEAST32 "X"

#define PRIoFAST32 "o"

#define PRIuFAST32 "u"

#define PRIxFAST32 "x"

#define PRIXFAST32 "X"

#else

#define PRIo32 "I32o"

#define PRIu32 "I32u"

#define PRIx32 "I32x"

#define PRIX32 "I32X"

#define PRIoLEAST32 "I32o"

#define PRIuLEAST32 "I32u"

#define PRIxLEAST32 "I32x"

#define PRIXLEAST32 "I32X"

#define PRIoFAST32 "I32o"

#define PRIuFAST32 "I32u"

#define PRIxFAST32 "I32x"

#define PRIXFAST32 "I32X"

#endif

 

#define PRIo64 "I64o"

#define PRIu64 "I64u"

#define PRIx64 "I64x"

#define PRIX64 "I64X"

#define PRIoLEAST64 "I64o"

#define PRIuLEAST64 "I64u"

#define PRIxLEAST64 "I64x"

#define PRIXLEAST64 "I64X"

#define PRIoFAST64 "I64o"

#define PRIuFAST64 "I64u"

#define PRIxFAST64 "I64x"

#define PRIXFAST64 "I64X"

 

#define PRIoMAX "I64o"

#define PRIuMAX "I64u"

#define PRIxMAX "I64x"

#define PRIXMAX "I64X"

 

#define PRIoPTR "Io"

#define PRIuPTR "Iu"

#define PRIxPTR "Ix"

#define PRIXPTR "IX"

 

// The fscanf macros for signed integers are:

#define SCNd8 "d"

#define SCNi8 "i"

#define SCNdLEAST8 "d"

#define SCNiLEAST8 "i"

#define SCNdFAST8 "d"

#define SCNiFAST8 "i"

 

#define SCNd16 "hd"

#define SCNi16 "hi"

#define SCNdLEAST16 "hd"

#define SCNiLEAST16 "hi"

#define SCNdFAST16 "hd"

#define SCNiFAST16 "hi"

 

#define SCNd32 "ld"

#define SCNi32 "li"

#define SCNdLEAST32 "ld"

#define SCNiLEAST32 "li"

#define SCNdFAST32 "ld"

#define SCNiFAST32 "li"

 

#define SCNd64 "I64d"

#define SCNi64 "I64i"

#define SCNdLEAST64 "I64d"

#define SCNiLEAST64 "I64i"

#define SCNdFAST64 "I64d"

#define SCNiFAST64 "I64i"

 

#define SCNdMAX "I64d"

#define SCNiMAX "I64i"

 

#ifdef _WIN64 // [

# define SCNdPTR "I64d"

# define SCNiPTR "I64i"

#else // _WIN64 ][

# define SCNdPTR "ld"

# define SCNiPTR "li"

#endif // _WIN64 ]

 

// The fscanf macros for unsigned integers are:

#define SCNo8 "o"

#define SCNu8 "u"

#define SCNx8 "x"

#define SCNX8 "X"

#define SCNoLEAST8 "o"

#define SCNuLEAST8 "u"

#define SCNxLEAST8 "x"

#define SCNXLEAST8 "X"

#define SCNoFAST8 "o"

#define SCNuFAST8 "u"

#define SCNxFAST8 "x"

#define SCNXFAST8 "X"

 

#define SCNo16 "ho"

#define SCNu16 "hu"

#define SCNx16 "hx"

#define SCNX16 "hX"

#define SCNoLEAST16 "ho"

#define SCNuLEAST16 "hu"

#define SCNxLEAST16 "hx"

#define SCNXLEAST16 "hX"

#define SCNoFAST16 "ho"

#define SCNuFAST16 "hu"

#define SCNxFAST16 "hx"

#define SCNXFAST16 "hX"

 

#define SCNo32 "lo"

#define SCNu32 "lu"

#define SCNx32 "lx"

#define SCNX32 "lX"

#define SCNoLEAST32 "lo"

#define SCNuLEAST32 "lu"

#define SCNxLEAST32 "lx"

#define SCNXLEAST32 "lX"

#define SCNoFAST32 "lo"

#define SCNuFAST32 "lu"

#define SCNxFAST32 "lx"

#define SCNXFAST32 "lX"

 

#define SCNo64 "I64o"

#define SCNu64 "I64u"

#define SCNx64 "I64x"

#define SCNX64 "I64X"

#define SCNoLEAST64 "I64o"

#define SCNuLEAST64 "I64u"

#define SCNxLEAST64 "I64x"

#define SCNXLEAST64 "I64X"

#define SCNoFAST64 "I64o"

#define SCNuFAST64 "I64u"

#define SCNxFAST64 "I64x"

#define SCNXFAST64 "I64X"

 

#define SCNoMAX "I64o"

#define SCNuMAX "I64u"

#define SCNxMAX "I64x"

#define SCNXMAX "I64X"

 

#ifdef _WIN64 // [

# define SCNoPTR "I64o"

# define SCNuPTR "I64u"

# define SCNxPTR "I64x"

# define SCNXPTR "I64X"

#else // _WIN64 ][

# define SCNoPTR "lo"

# define SCNuPTR "lu"

# define SCNxPTR "lx"

# define SCNXPTR "lX"

#endif // _WIN64 ]

 

#endif // __STDC_FORMAT_MACROS ]

 

// 7.8.2 Functions for greatest-width integer types

 

// 7.8.2.1 The imaxabs function

#define imaxabs _abs64

 

// 7.8.2.2 The imaxdiv function

 

#ifdef _MSC_VER

// This is modified version of div() function from Microsoft's div.c found

// in %MSVC.NET%\crt\src\div.c

#ifdef STATIC_IMAXDIV // [

static

#else // STATIC_IMAXDIV ][

_inline

#endif // STATIC_IMAXDIV ]

imaxdiv_t __cdecl imaxdiv(intmax_t numer, intmax_t denom)

{

imaxdiv_t result;

 

result.quot = numer / denom;

result.rem = numer % denom;

 

if (numer < 0 && result.rem > 0) {

// did division wrong; must fix up

++result.quot;

result.rem -= denom;

}

 

return result;

}

#endif // #ifdef _MSC_VER

 

// 7.8.2.3 The strtoimax and strtoumax functions

#define strtoimax _strtoi64

#define strtoumax _strtoui64

 

// 7.8.2.4 The wcstoimax and wcstoumax functions

#define wcstoimax _wcstoi64

#define wcstoumax _wcstoui64

 

 

#endif // _MSC_INTTYPES_H_ ]

 

#endif // #ifdef _INTTYPES_H_SYS_

 

#endif // #ifndef _INTTYPES_H_ALL_

  1. av_open_input_file

现在会提示错误[BCC32 Error] Unit2.cpp(33): E2268 Call to undefined function 'av_open_input_file'

原因是新版本中不用这个函数了,改为avformat_open_input函数,替换为

    err = avformat_open_input(&pFormatCtx, fileName, NULL, 0);

  1. CodecID

继续,出错的是[BCC32 Error] Unit2.cpp(54): E2451 Undefined symbol 'CodecID'

到头文件中一看,定义改为了AVCodecID,更改之。

  1. 库文件

再编译,会提示函数未实现

[ILINK32 Error] Error: Unresolved external '_av_register_all' referenced from D:\EXENOBJ\OBJ\FFMPEG\UNIT2.OBJ

将库加入到工程中,当然,可以把所有的LIB加进来,肯定是没问题的。

我通过TDUMP看了下各个LIB,结果发现avformat.lib中有这些函数,只加了这一个LIB,还是比较清爽的。

至少现在编译链接通过了。

  1. 试运行

运行,点击按钮,发现出错

单步调试,发现

    const char *fileName = "c:\\test.mp4";

    err = avformat_open_input(&pFormatCtx, fileName, NULL, 0);

运行后,err为-2

简单看了一下说明,该函数

* @return 0 on success, a negative AVERROR on failure.

那说明有问题,至于-2是什么意思,暂不追究。不过从这两行代码猜得出,应该是文件c:\\test.mp4不存在,找一个存在的。刚好有一个路灯安装视频street light installation.mp4,拷贝为c:\\test.mp4

运行居然还是-2,而pFormatCtx为NULL。

是不是WIN7的权限问题,C盘不让访问?直接换成D:\\test.mp4,运行发现err = 0,OK

运行过程中的各个变量值:

取得了文件的各种信息,初步OK。

posted on 2014-03-02 10:40  drgraph  阅读(765)  评论(0编辑  收藏  举报