未定义的引用,在Ubuntu 64位系统上使用FFMpeg库(AvCodec) [英] Undefined reference, using FFMpeg-library (AvCodec) on Ubuntu, 64-bits system

查看:213
本文介绍了未定义的引用,在Ubuntu 64位系统上使用FFMpeg库(AvCodec)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在运行最新的FFMpeg库的示例代码。
我将示例代码插入到文件 videofecencoder.c 中:

  / * 
* copyright(c)2001 Fabrice Bellard
*
*此文件是Libav的一部分。
*
* Libav是免费软件;您可以根据自由软件基金会发布的GNU Lesser General Public
*许可证的条款重新分配和/或
*进行修改;
*版本2.1的许可证,或(在您的选择)任何更高版本。
*
* Libav是分发的,希望它将是有用的,
*但没有任何保证;甚至没有暗示的保证
*适销性或适用于特定用途。有关详细信息,请参阅GNU
*较小的通用公共许可证。
*
*您应该已经收到了与Libav一起的GNU Lesser General Public
*许可证的副本;如果没有,写信给自由软件
* Foundation,Inc.,51 Franklin Street,Fifth Floor,Boston,MA 02110-1301 USA
* /
#pragma GCC诊断被忽略-Wdeprecated -Declarations


#include< stdlib.h>
#include< stdio.h>
#include< string.h>

#ifdef HAVE_AV_CONFIG_H
#undef HAVE_AV_CONFIG_H
#endif

#includelibavutil / imgutils.h
#includelibavutil / opt.h
#includelibavcodec / avcodec.h
#includelibavutil / mathematics.h
#includelibavutil / samplefmt.h

#define INBUF_SIZE 4096
#define AUDIO_INBUF_SIZE 20480
#define AUDIO_REFILL_THRESH 4096

/ *
*视频编码示例
* /
static void video_encode_example(const char * filename,int codec_id)
{
AVCodec * codec;
AVCodecContext * c = NULL;
int i,out_size,size,x,y,outbuf_size;
FILE * f;
AVFrame *图片;
uint8_t * outbuf;
int nrOfFramesPerSecond = 25;
int nrOfSeconds = 1;


printf(视频编码\);

/ *找到mpeg1视频编码器* /
codec = avcodec_find_encoder((CodecID)codec_id);
if(!codec){
fprintf(stderr,codec not found\\\
);
exit(1);
}

c = avcodec_alloc_context3(codec);
picture = avcodec_alloc_frame();

/ * put sample parameters * /
c-> bit_rate = 400000;
/ *分辨率必须是*的两倍* /
c-> width = 352;
c-> height = 288;
/ *每秒帧数* /
c-> time_base =(AVRational){1,25};
c-> gop_size = 10; / *每十帧发出一个帧内* /
c-> max_b_frames = 1;
c-> pix_fmt = PIX_FMT_YUV420P;

if(codec_id == CODEC_ID_H264)
av_opt_set(c-> priv_data,preset,slow,0);

/ *打开它* /
if(avcodec_open2(c,codec,NULL)< 0){
fprintf(stderr,can not open codec\\\
);
exit(1);
}

f = fopen(filename,wb);
if(!f){
fprintf(stderr,can not open%s\\\
,filename);
exit(1);
}

/ * alloc图像和输出缓冲区* /
outbuf_size = 100000;
outbuf =(uint8_t *)malloc(outbuf_size);

/ *可以通过任何方式分配图像,av_image_alloc()是
*只要使用av_malloc()才使用最方便的方式* /
av_image_alloc(图片 - > data,picture-> linesize,
c-> width,c-> height,c-> pix_fmt,1);

/ *编码视频的1秒* /
int nrOfFramesTotal = nrOfFramesPerSecond * nrOfSeconds; (i = 0; i< nrOfFramesTotal; i ++){
fflush(stdout);

/ *编码视频的1秒* /

/ *准备一个虚拟图像* /
/ * Y * /
for(y = 0; y< c-> height; y ++){
for(x = 0; x c- width; x ++){
picture-> data [0] [y * picture-> linesize [0] + x] = x + y + i * 3;
}
}

/ * Cb和Cr * /
for(y = 0; y< c-> height / 2; y ++){$ b (x = 0; x c- width / 2; x ++){
picture-> data [1] [y * picture-> linesize [1] + x] = 128 + y + i * 2;
picture-> data [2] [y * picture-> linesize [2] + x] = 64 + x + i * 5;
}
}

/ *编码图像* /
out_size = avcodec_encode_video(c,outbuf,outbuf_size,picture);
printf(encoding frame%3d(size =%5d)\\\
,i,out_size);
fwrite(outbuf,1,out_size,f);
}

/ *获取延迟帧* /
for(; out_size; i ++){
fflush(stdout);

out_size = avcodec_encode_video(c,outbuf,outbuf_size,NULL);
printf(write frame%3d(size =%5d)\\\
,i,out_size);
fwrite(outbuf,1,out_size,f);
}

/ *添加序列结束代码以具有真正的mpeg文件* /
outbuf [0] = 0x00;
outbuf [1] = 0x00;
outbuf [2] = 0x01;
outbuf [3] = 0xb7;
fwrite(outbuf,1,4,f);
fclose(f);
免费(outbuf);

avcodec_close(c);
av_free(c);
av_free(picture-> data [0]);
av_free(picture);
printf(\\\
);
}

int main(int argc,char ** argv)
{
const char * filename;

/ *注册所有的编解码器* /
avcodec_register_all();

if(argc <= 1){

video_encode_example(/ grb_1.mpg,CODEC_ID_MPEG1VIDEO);
} else {
filename = argv [1];
}


返回0;
}

当我运行 gcc videofecencoder.cc -lavcodec 我收到以下错误消息:

  /tmp/ccJg8IDy.o:在函数`video_encode_example const *,int)':
videofecencoder.cc:(.text+0x35):未定义的引用`avcodec_find_encoder(CodecID)'
videofecencoder.cc:(.text+0x74):undefined reference to` avcodec_alloc_context3(AVCodec *)'
videofecencoder.cc:(.text+0x7d):未定义的引用`avcodec_alloc_frame()'
videofecencoder.cc:(.text+0x113):未定义的引用`av_opt_set void *,char const *,char const *,int)'
videofecencoder.cc:(.text+0x12b):未定义的引用到`avcodec_open2(AVCodecContext *,AVCodec *,AVDictionary **)'
videofecencoder.cc:(.text+0x1f0):未定义的引用`av_image_alloc(unsigned char **,int *,int,int,PixelFormat,int)'
videofecencoder.cc:(.text+0x35c):undefined引用`avcodec_encode_video(AVCodecContext *,unsigned char *, int AVFrame const *)'
videofecencoder.cc:(.text+0x3cf):未定义的引用到`avcodec_encode_video(AVCodecContext *,unsigned char *,int,AVFrame const *)'
videofecencoder.cc: (.text + 0x47c):未定义的引用`avcodec_close(AVCodecContext *)'
videofecencoder.cc:(.text+0x488):未定义的引用`av_free(void *)'
videofecencoder.cc: (.text + 0x497):未定义的引用`av_free(void *)'
videofecencoder.cc:(.text+0x4a3):未定义的引用`av_free(void *)'
/ tmp / ccJg8IDy .o:在函数`main'中:
videofecencoder.cc:(.text+0x4c3):未定义的引用`avcodec_register_all()'
collect2:ld returnerade avslutningsstatus 1

命令 nm libavcodec.a | grep avcodec_find 结果:

  00000000000008e0 T avcodec_find_best_pix_fmt 
0000000000000740 T avcodec_find_best_pix_fmt2
U avcodec_find_encoder
0000000000002ca0 T avcodec_find_decoder
0000000000002cf0 T avcodec_find_decoder_by_name
0000000000002bd0 T avcodec_find_encoder
0000000000002c30 T avcodec_find_encoder_by_name

我还有另一个类似的错误:
尽管在OpenFEC库中进行链接但未定义参考



我的系统:Ubuntu 11,64位机器



我的下一步是尝试使用Ubuntu 32位(在Windows操作系统上运行)在VirtualBox上编译。

解决方案

我是(终于!!)参考了FFMpeg邮件列表中的解决方案:
http://ffmpeg.org/faq .html#I_0027m-using-FFmpeg-from-in-my-C_002b_002b-application-but-the-linker-complains-about-missing-symbols-which-looks-to-be-available_002e



引用:FFmpeg是一个纯C项目,因此要使用C ++应用程序中的库,您需要明确声明您正在使用C库。你可以通过包含你的FFmpeg包括使用externC来做到这一点。


I am running the example code of the latest FFMpeg-library. I have inserted the example code into the file videofecencoder.c:

/*
* copyright (c) 2001 Fabrice Bellard
*
* This file is part of Libav.
*
* Libav is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* Libav is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with Libav; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"


#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#ifdef HAVE_AV_CONFIG_H
#undef HAVE_AV_CONFIG_H
#endif

#include "libavutil/imgutils.h"
#include "libavutil/opt.h"
#include "libavcodec/avcodec.h"
#include "libavutil/mathematics.h"
#include "libavutil/samplefmt.h"

#define INBUF_SIZE 4096
#define AUDIO_INBUF_SIZE 20480
#define AUDIO_REFILL_THRESH 4096

/*
* Video encoding example
*/
static void video_encode_example(const char *filename, int codec_id)
{
   AVCodec *codec;
   AVCodecContext *c= NULL;
   int i, out_size, size, x, y, outbuf_size;
   FILE *f;
   AVFrame *picture;
   uint8_t *outbuf;
   int nrOfFramesPerSecond  =25;
   int nrOfSeconds =1;


   printf("Video encoding\n");

   /* find the mpeg1 video encoder */
   codec = avcodec_find_encoder((CodecID) codec_id);
   if (!codec) {
       fprintf(stderr, "codec not found\n");
       exit(1);
   }

   c = avcodec_alloc_context3(codec);
   picture= avcodec_alloc_frame();

   /* put sample parameters */
   c->bit_rate = 400000;
   /* resolution must be a multiple of two */
   c->width = 352;
   c->height = 288;
   /* frames per second */
   c->time_base= (AVRational){1,25};
   c->gop_size = 10; /* emit one intra frame every ten frames */
   c->max_b_frames=1;
   c->pix_fmt = PIX_FMT_YUV420P;

   if(codec_id == CODEC_ID_H264)
       av_opt_set(c->priv_data, "preset", "slow", 0);

   /* open it */
   if (avcodec_open2(c, codec, NULL) < 0) {
       fprintf(stderr, "could not open codec\n");
       exit(1);
   }

   f = fopen(filename, "wb");
   if (!f) {
       fprintf(stderr, "could not open %s\n", filename);
       exit(1);
   }

   /* alloc image and output buffer */
   outbuf_size = 100000;
   outbuf = (uint8_t*) malloc(outbuf_size);

   /* the image can be allocated by any means and av_image_alloc() is
    * just the most convenient way if av_malloc() is to be used */
   av_image_alloc(picture->data, picture->linesize,
                  c->width, c->height, c->pix_fmt, 1);

   /* encode 1 second of video */
   int nrOfFramesTotal = nrOfFramesPerSecond * nrOfSeconds;

   /* encode 1 second of video */
   for(i=0;i < nrOfFramesTotal; i++) {
       fflush(stdout);
       /* prepare a dummy image */
       /* Y */
       for(y=0;y<c->height;y++) {
           for(x=0;x<c->width;x++) {
               picture->data[0][y * picture->linesize[0] + x] = x + y + i * 3;
           }
       }

       /* Cb and Cr */
       for(y=0;y<c->height/2;y++) {
           for(x=0;x<c->width/2;x++) {
               picture->data[1][y * picture->linesize[1] + x] = 128 + y + i * 2;
               picture->data[2][y * picture->linesize[2] + x] = 64 + x + i * 5;
           }
       }

       /* encode the image */
       out_size = avcodec_encode_video(c, outbuf, outbuf_size, picture);
       printf("encoding frame %3d (size=%5d)\n", i, out_size);
       fwrite(outbuf, 1, out_size, f);
   }

   /* get the delayed frames */
   for(; out_size; i++) {
       fflush(stdout);

       out_size = avcodec_encode_video(c, outbuf, outbuf_size, NULL);
       printf("write frame %3d (size=%5d)\n", i, out_size);
       fwrite(outbuf, 1, out_size, f);
   }

   /* add sequence end code to have a real mpeg file */
   outbuf[0] = 0x00;
   outbuf[1] = 0x00;
   outbuf[2] = 0x01;
   outbuf[3] = 0xb7;
   fwrite(outbuf, 1, 4, f);
   fclose(f);
   free(outbuf);

   avcodec_close(c);
   av_free(c);
   av_free(picture->data[0]);
   av_free(picture);
   printf("\n");
}

int main(int argc, char **argv)
{
   const char *filename;

   /* register all the codecs */
   avcodec_register_all();

   if (argc <= 1) {

       video_encode_example("/grb_1.mpg", CODEC_ID_MPEG1VIDEO);
   } else {
       filename = argv[1];
   }


   return 0;
}

When I run gcc videofecencoder.cc -lavcodec I get the following error messages:

/tmp/ccJg8IDy.o: In function `video_encode_example(char const*, int)':
videofecencoder.cc:(.text+0x35): undefined reference to `avcodec_find_encoder(CodecID)'
videofecencoder.cc:(.text+0x74): undefined reference to `avcodec_alloc_context3(AVCodec*)'
videofecencoder.cc:(.text+0x7d): undefined reference to `avcodec_alloc_frame()'
videofecencoder.cc:(.text+0x113): undefined reference to `av_opt_set(void*, char const*, char const*, int)'
videofecencoder.cc:(.text+0x12b): undefined reference to `avcodec_open2(AVCodecContext*, AVCodec*, AVDictionary**)'
videofecencoder.cc:(.text+0x1f0): undefined reference to `av_image_alloc(unsigned char**, int*, int, int, PixelFormat, int)'
videofecencoder.cc:(.text+0x35c): undefined reference to `avcodec_encode_video(AVCodecContext*, unsigned char*, int, AVFrame const*)'
videofecencoder.cc:(.text+0x3cf): undefined reference to `avcodec_encode_video(AVCodecContext*, unsigned char*, int, AVFrame const*)'
videofecencoder.cc:(.text+0x47c): undefined reference to `avcodec_close(AVCodecContext*)'
videofecencoder.cc:(.text+0x488): undefined reference to `av_free(void*)'
videofecencoder.cc:(.text+0x497): undefined reference to `av_free(void*)'
videofecencoder.cc:(.text+0x4a3): undefined reference to `av_free(void*)'
/tmp/ccJg8IDy.o: In function `main':
videofecencoder.cc:(.text+0x4c3): undefined reference to `avcodec_register_all()'
collect2: ld returnerade avslutningsstatus 1

The command nm libavcodec.a | grep avcodec_find results in:

00000000000008e0 T avcodec_find_best_pix_fmt
0000000000000740 T avcodec_find_best_pix_fmt2
                 U avcodec_find_encoder
0000000000002ca0 T avcodec_find_decoder
0000000000002cf0 T avcodec_find_decoder_by_name
0000000000002bd0 T avcodec_find_encoder
0000000000002c30 T avcodec_find_encoder_by_name

I also have another similar error with another library: Undefined reference despite linking in OpenFEC-library

My system: Ubuntu 11, 64-bits machine

My next step is to try to compile it on VirtualBox with Ubuntu 32 bits (running on a Windows-OS).

解决方案

I was (finally!!) referred to the solution in the FFMpeg-mailing list: http://ffmpeg.org/faq.html#I_0027m-using-FFmpeg-from-within-my-C_002b_002b-application-but-the-linker-complains-about-missing-symbols-which-seem-to-be-available_002e

Quote: "FFmpeg is a pure C project, so to use the libraries within your C++ application you need to explicitly state that you are using a C library. You can do this by encompassing your FFmpeg includes using extern "C"."

这篇关于未定义的引用,在Ubuntu 64位系统上使用FFMpeg库(AvCodec)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆