(1)先转QT中.pro原文档的写法
1. 注释
从“ #” 开始,到这一行结束。
2. 指定源文件
SOURCES = *.cpp
对于多源文件,可用空格分开,如: SOURCES = 1.cpp 2.cpp3.cpp
或者每一个文件可以被列在一个分开的行里面,通过反斜线另起一行,就像这样 :
SOURCES = hello.cpp
main.cpp
一个更冗长的方法是单独地列出每一个文件,就像这样:
SOURCES+= hello.cpp
SOURCES +=main.cpp
这种方法中使用“ +=” 比“ =” 更安全,因为它只是向已有的列表中添加新的文件,而不是替换整个列表。
3. 指定头文件
HEADERS = hello.h 或者 HEADERS += hello.h
列出源文件的任何一个方法对头文件也都适用。
4. 配置信息
CONFIG 用来告诉 qmake 关于应用程序的配置信息。
CONFIG+= qt warn_on release
在这里使用“ +=” ,是因为我们添加我们的配置选项到任何一个已经存在中。这样做比使用“ =” 那样替换已经指定的所有选项是更安全的。
A> qt 部分告诉 qmake 这个应用程序是使用 Qt 来连编的。这也就是说 qmake 在连接和为编译添加所需的包含路径的时候会考虑到 Qt 库的。
B> warn_on 部分告诉 qmake 要把编译器设置为输出警告信息的。
C> release 部分告诉 qmake 应用程序必须被连编为一个发布的应用程序。在开发过程中,程序员也可以使用 debug 来替换 release
5. 指定目标文件名
TARGET = filename
如果不设置该项目,目标名会被自动设置为跟项目文件一样的名称
6. 添加界面文件 (ui)
INTERFACES = filename.ui
7. 平台相关性处理
我们在这里需要做的是根据 qmake 所运行的平台来使用相应的作用域来进行处理。为 Windows 平台添加的依赖平台的文件的简单的作用域看起来就像这样:
win32 {
SOURCES += hello_win.cpp
}
所以如果 qmake 运行在 Windows 上的时候,它就会把 hello_win.cpp 添加到源文件列表中。如果 qmake 运行在其它平台上的时候,它会很简单地把这部分忽略。
8. 如果一个文件不存在,停止 qmake
如果某一个文件不存在的 时候,你也许不想生成一个 Makefile 。我们可以通过使用 exists() 函数来检查一个文件是否存在。我们可以通过使用 error() 函数把正在运 行的 qmake 停下来。这和作用域的工作方式一样。只要很简单地用这个函数来替换作用域条件。对 main.cpp 文件的检查就像这样:
!exists( main.cpp ) {
error( "No main.cpp file found")
}
“!” 用来否定这个测试,比如,如果文件存在, exists( main.cpp) 是真,如果文件不存在, !exists( main.cpp ) 是真。
9. 检查多于一个的条件
假设你使用 Windows 并且当你在命令 行运行你的应用程序的时候你想能够看到 qDebug() 语句。除非你在连编你的程序的时候使用 console 设置,你不会看到输出。我们可以很容易地把 console 添加到 CONFIG 行中,这样在 Windows 下, Makefile 就会有这个设置。但是如果告诉你我们只是想在当我们的应用程序运行在 Windows 下并且当 debug 已经在 CONFIG 行中的时候,添加 console 。这需要两个嵌套的作用域;只要生成一个作用域,然后在它里面再生成
另一个。把设置放在最里面的作用域里,就像这样:
win32 {
debug {
CONFIG += console
}
}
嵌套的作用域可以使用冒号连接起来,像这样:
win32:debug {
CONFIG += console
}
10. 摸板
模板变量告诉 qmake 为这个应用程序生成哪种 makefile 。下面是可供使用的选择:
A> app - 建立一个应用程序的 makefile 。这是默认值,所以如果模板没有被指定,这个将被使用。
B> lib - 建立一个库的 makefile 。
C> vcapp - 建立一个应用程序的 VisualStudio 项目文件。
D> vclib - 建立一个库的 VisualStudio 项目文件。
E> subdirs - 这是一个特殊的模板,它可以创建一个能够进入特定目录并且为一个项目文件生成 makefile 并且为它调用 make 的 makefile 。
11. 生成 Makefile
当你已经创建好你的项目文件,生成 Makefile 就很容易了,你所要做的就是先到你所生成的项目文件那里然后输入:
Makefile 可以像这样由“ .pro” 文件生成:
qmake -oMakefile hello.pro
对于 VisualStudio 的用户, qmake 也可以生成“ .dsp” 文件,例如:
qmake -tvcapp -o hello.dsp hello.pro
源文档 <http://blog.csdn.net/metasearch/archive/2008/03/05/2148207.aspx >
Qmake 不仅仅只用于QT其他地方也用到了,根据模板的值可以生成app,lib,vclib等待makefile文件
(2)声明其他的库
如果你需要在工程中使用其他的库 , 需要在工程文件里面指定
让 qmake 找到库的路径和相应需要连接的库 , 可以在 LIBS 变量里面添加 . 库的路径要给出 , 或者常见的 unix 样式的符号来指定库和库的路径
例如下面的展示了如何使用指定的库
LIBS += -L/usr/local/lib -lmath
可以用类似的方法来指定头文件的路径 , 不过是使用 INCLUDEPATH 变量 , 如下面可能添加好几个头文件的路径
INCLUDEPATH = c:/msdev/include d:/stl/include
不过我的习惯是下面这样的 , 比较清晰还有 , 最好 windows 的路径不要有空格 , 中文也不要有 , 斜杠也推荐用 / 而不是 windows 的 \ 因为跟分行符号 \ 相同了 / 可以在 unix 和 windows 用 , 但是 \ 貌似到了 unix 或 linux 就不行了 , 所以用 / 是通用的
INCLUDEPATH = c:/msdev/include \
d:/stl/include
见别人是这样添加到
在 .pro文件中添加LIBS += -lavformat -lavcodec -lavutil lz -lavutil -lm `sdl-config --cflags --libs`
(3)因为ffmpeg是c程序,所以在编译的时候需要在头文件中加入
extern "C" {
#include <ffmpeg/avcodec.h>
#include <ffmpeg/avformat.h>
}
注:这里的C是大写。我之前好久没动手编程,这也查了蛮久,打击自信心啊!!!!
解释如下:
1.extern 是 C/C++ 语言中表明函数和全局变量作用范围(可见性)的关键字,该关键字告诉编译器 其声明的函数和变量可以在本模块或其它模块中使用;
2.与 extern 对应的关键字是 static ,被它修饰的全局变量和函数只能在本模块中使用。因此,一个函数或变量只可能被本模块使用时,其不可能被 extern “C” 修饰;
3. 被 extern "C" 修饰的变量和函数是按照 C 语言方式编译和连接的;
4.C编译器和c++编译器对函数的翻译不一样,如:int root(int a,int b);c对应的是_root,c++对应的是_root_int_int,因为c不支持重载而c++支持,因此需要识别函数的参数。
(4)直接运行可执行文件出现缺少minwm10.dll错误提示,将D:\Qt\2009.05\mingw\bin;D:\Qt\2009.05\qt\bin添加到环境变量就可以了。
(5)因为现在比较熟悉opencv,就用opencv+qt尝试qt连接库
INCLUDEPATH += C:\OpenCV\cv\include \
C:\OpenCV\cvaux\include \
C:\OpenCV\cxcore\include \
C:\OpenCV\otherlibs\highgui
LIBS += C:\OpenCV\lib\cv.lib \
C:\OpenCV\lib\cvaux.lib \
C:\OpenCV\lib\cxcore.lib \
C:\OpenCV\lib\highgui.lib \
程序可以编译运行,但是出现could not initialize ole的错误,不知道该怎么解决,在网上没查到有用的信息 !以后用的时候再解决这个问题,反正现在也可以编译了。
(6)接着用同样的方法改下.pro文件,添加头文件和库文件
INCLUDEPATH +=
D:\Qt\2009.05\ffmpeg\include\libavcodec \
D:\Qt\2009.05\ffmpeg\include\libavdevice \
D:\Qt\2009.05\ffmpeg\include\libavfilter \
D:\Qt\2009.05\ffmpeg\include\libavformat \
D:\Qt\2009.05\ffmpeg\include\libavutil \
D:\Qt\2009.05\ffmpeg\include\libswscale \
D:\Qt\2009.05\ffmpeg\include \
LIBS +=
D:\Qt\2009.05\ffmpeg\lib\avcodec.lib \
D:\Qt\2009.05\ffmpeg\lib\avdevice.lib \
D:\Qt\2009.05\ffmpeg\lib\avfilter.lib \
D:\Qt\2009.05\ffmpeg\lib\avformat.lib \
D:\Qt\2009.05\ffmpeg\lib\avutil.lib \
D:\Qt\2009.05\ffmpeg\lib\swscale.lib \
(7)添加Sdl库
同理在文件中添加
D:\Qt\2009.05\SDL\include \
D:\Qt\2009.05\SDL\lib\SDL.lib \
D:\Qt\2009.05\SDL\lib\SDLmain.lib \
并加入头文件
#include <SDL.h>
#include <SDL_thread.h>
编译会出现一个错误
undefined reference to `qMain(int, char**)'
这是因为sdl中的 SDL _main.h已经定义了main,加上#undef main就可以解决了
(8)在av_register_all();时遇到 exited with code -1073741515错误
这是因为ffmpeg没有配置好,出现这个错误的原因是没有找到dll,dll一般是放在C:\WINDOWS\system32目录下的,我把他ffmpeg的库
复制到该目录下就ok了 ×— —×
(9)将tutorial02.c的代码改改,如下:
#include <QtGui/QApplication>
#include "mainwindow.h"
#include <stdio.h>
#include <QLabel>
#include <QWidget>
extern "C"{
#include <avcodec.h>
#include <avformat.h>
#include <swscale.h>
#include <SDL.h>
#include <SDL_thread.h>
}
#ifdef __MINGW32__
#undef main /* Prevents SDL from overriding main() */
#endif
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
AVFormatContext *pFormatCtx;
int i, videoStream;
AVCodecContext *pCodecCtx;
AVCodec *pCodec;
AVFrame *pFrame;
AVPacket packet;
int frameFinished;
float aspect_ratio;
static struct SwsContext *img_convert_ctx;
static int sws_flags = SWS_BICUBIC;
SDL_Overlay *bmp;
SDL_Surface *screen;
SDL_Rect rect;
SDL_Event event;
MainWindow w;
QLabel *frame_pre;
frame_pre = new QLabel;
QWidget *widget_player;
widget_player = new QWidget();
widget_player->setAttribute(Qt::WA_PaintOnScreen);
widget_player->setAttribute(Qt::WA_NoSystemBackground);
widget_player->show();
w.show();
frame_pre->show();
av_register_all();
/*set sdl env*/
char variable[64];
#ifdef Q_OS_WIN
sprintf(variable, "SDL_WINDOWID=0x%lx", widget_player->winId());
#else
sprintf(variable, "SDL_WINDOWID=0x%lx", this->winId());
#endif
putenv(variable);
if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER)) {
fprintf(stderr, "Could not initialize SDL - %s\n", SDL_GetError());
exit(1);
}
// Open video file
if(av_open_input_file(&pFormatCtx, "D:\\Flyhigh.wmv", NULL, 0, NULL)!=0)
return -1; // Couldn't open file
// Retrieve stream information
if(av_find_stream_info(pFormatCtx)<0)
return -1; // Couldn't find stream information
// Dump information about file onto standard error
dump_format(pFormatCtx, 0, "D:\\Flyhigh.wmv", 0);
// Find the first video stream
videoStream=-1;
for(i=0; i<pFormatCtx->nb_streams; i++)
if(pFormatCtx->streams[i]->codec->codec_type==CODEC_TYPE_VIDEO) {
videoStream=i;
break;
}
if(videoStream==-1)
return -1; // Didn't find a video stream
// Get a pointer to the codec context for the video stream
pCodecCtx=pFormatCtx->streams[videoStream]->codec;
// Find the decoder for the video stream
pCodec=avcodec_find_decoder(pCodecCtx->codec_id);
if(pCodec==NULL) {
fprintf(stderr, "Unsupported codec!\n");
return -1; // Codec not found
}
// Open codec
if(avcodec_open(pCodecCtx, pCodec)<0)
return -1; // Could not open codec
// Allocate video frame
pFrame=avcodec_alloc_frame();
// Make a screen to put our video
#ifndef __DARWIN__
screen = SDL_SetVideoMode(pCodecCtx->width, pCodecCtx->height, 0, 0);
#else
screen = SDL_SetVideoMode(pCodecCtx->width, pCodecCtx->height, 24, 0);
#endif
if(!screen) {
fprintf(stderr, "SDL: could not set video mode - exiting\n");
exit(1);
}
// Allocate a place to put our YUV image on that screen
bmp = SDL_CreateYUVOverlay(pCodecCtx->width,
pCodecCtx->height,
SDL_YV12_OVERLAY,
screen);
// Read frames and save first five frames to disk
i=0;
while(av_read_frame(pFormatCtx, &packet)>=0) {
// Is this a packet from the video stream?
if(packet.stream_index==videoStream) {
// Decode video frame
avcodec_decode_video(pCodecCtx, pFrame, &frameFinished,
packet.data, packet.size);
// Did we get a video frame?
if(frameFinished) {
SDL_LockYUVOverlay(bmp);
AVPicture *pict;
pict = new AVPicture;
pict->data[0] = bmp->pixels[0];
pict->data[1] = bmp->pixels[2];
pict->data[2] = bmp->pixels[1];
pict->linesize[0] = bmp->pitches[0];
pict->linesize[1] = bmp->pitches[2];
pict->linesize[2] = bmp->pitches[1];
// Convert the image into YUV format that SDL uses
if (pCodecCtx->pix_fmt == PIX_FMT_YUV420P) {
/* as we only generate a YUV420P picture, we must convert it
to the codec pixel format if needed */
img_convert_ctx = sws_getContext(pCodecCtx->width, pCodecCtx->height,
pCodecCtx->pix_fmt,
pCodecCtx->width, pCodecCtx->height,
PIX_FMT_YUV420P,
sws_flags, NULL, NULL, NULL);
if (img_convert_ctx == NULL) {
fprintf(stderr, "Cannot initialize the conversion context\n");
exit(1);
}
sws_scale(img_convert_ctx, pFrame->data, pFrame->linesize,
0, pCodecCtx->height, pict->data, pict->linesize);
}
// img_convert(&pict, PIX_FMT_YUV420P,
// (AVPicture *)pFrame, pCodecCtx->pix_fmt,
// pCodecCtx->width, pCodecCtx->height);
SDL_UnlockYUVOverlay(bmp);
rect.x = 0;
rect.y = 0;
rect.w = pCodecCtx->width;
rect.h = pCodecCtx->height;
SDL_DisplayYUVOverlay(bmp, &rect);
}
}
// Free the packet that was allocated by av_read_frame
av_free_packet(&packet);
SDL_PollEvent(&event);
switch(event.type) {
case SDL_QUIT:
SDL_Quit();
exit(0);
break;
default:
break;
}
}
// Free the YUV frame
av_free(pFrame);
// Close the codec
avcodec_close(pCodecCtx);
// Close the video file
av_close_input_file(pFormatCtx);
return a.exec();
}
就可以看到图像了,哈哈。
转自:http://blog.chinaunix.net/uid-8210028-id-338118.html
分享到:
相关推荐
Qt+FFMPEG+SDL实现的视频播放器 包含源代码和可执行程序
QT + ffmpeg + sdl音频播放器, 利用ffmpeg解码,sdl播放声音。
基于C++ Qt+FFMPEG+SDL2写的视频播放器源代码,可以播放本地视频
功能:基于Qt+FFmpeg设计的视频播放器 解码器:FFMPEG4.2.2 音频输出:SDL2.0 平台支持:windows、Linux 均测试通过。
课程设计C++开发基于Qt+FFmpeg+SDL实现的音视频播放器源码+详细注释 - 不懂运行,下载完可以私聊问,可远程教学 该资源内项目源码是个人的毕设,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,...
QT工程,ffmpeg+SDL显示h264文件
这是QT+FFMPEG设计的流媒体播放器完整源码 1. 支持RTMP流播放 2. 支持RTSP流播放 3. 支持音频播放 4. 支持视频播放 编译器: MinGW 32位 QT版本: 5.12.6
Qt+FFMPEG+SDL实现的视频播放器 包含源代码和可执行程序 Qt+FFMPEG+SDL实现的视频播放器 包含源代码和可执行程序
qt使用FFmPeg+SDL2.0+QOpenGLWidget实现的视频播放器,FFmPeg+SDL2.0解码音视频,视频图像解码为YUV420的格式,然后使用QOpenGLWidget进行显示。亲测在windows和Linux下都可使用,附带FFmPeg+SDL2.0第三方库
71,SDL处理音频,ffmpeg处理编解码音视频文件,qt做ui界面2,使用多线程双缓冲队列播放音视频3,使用视频追逐音频的策略实现音视频同步4,支持视频镜像操作,黑白彩色转换
这是Qt的工程,建议使用Qt Creator 打开 从零开始学习音视频编程技术(二十二) 录屏软件开发之BUG修复 FFMPEG的版本是2.5.2 SDL的版本是2.04 记得将ffmpeg/bin目录下的dll文件拷贝到编译生成的exe所在的目录下...
是一个Windows下使用FFMPEG解码视频 并使用QPaint绘制到QWidget上 FFMPEG的版本是2.5.2 记得将ffmpeg/bin目录下的dll文件拷贝到编译生成的exe所在的目录下,否则会无法运行。 关于代码的解释 请参考: ...
QTFFmpegSDLPlayer_qt+ffmpeg_qtffmpeg_QtPlayer_qt播放器_Qt+FFMPEG+SDL_源码.rar.rar
基于OpenCV+FFmpeg+SDL+Qt完成的实时会议的通信软件源码+文档说明,适合毕业设计、课程设计、项目开发。项目源码已经过严格测试,可以放心下载使用~ 基于OpenCV+FFmpeg+SDL+Qt完成的实时会议的通信软件源码+文档...
功能: 1. 从摄像头拉rtmp裸h264流 2. 实时播放 3. 断线重连 4. ffmpeg版本4.3,包括在源码中 5. 作为学习够用了
采用 QT 编程进行客户端的 UI 的设计,全工程使用了 IMtoolBOX 的抽屉类,和 UserItem 类实现了好友列表和视屏窗口;服务器使用 Threadpoll+epoll 模型实现数据交互、业务处理,最大连接数可达几十万。
qt使用FFmPeg+SDL2.0+QOpenGLWidget实现的视频播放器,FFmPeg+SDL2.0解码音视频,视频图像解码为YUV420的格式,然后使用QOpenGLWidget进行显示。亲测在windows和Linux下都可使用,附带FFmPeg+SDL2.0第三方库 支持...
qt基于ffmpeg 实现保存网络流到本地文件,网络流包括flV,rtmp、rtsp等形式,本地存储文件格式包括MP4、flv、avi等格式,可以根据需要进行修改,附带ffmpeg+SDL第三方库,windows64位以及linux库
├── fdk-aac-2.0.2│ ├── include│ │ └── fdk-aac│ └── lib│ └── pkgconfig├── FFmpeg-n5.1.2│ ├── bin│ ├── include│ │ ├── libavcodec│ │ ├── libavdevice│...