linux下图像采集 如何使用ffmpeg录制成视频?

奋斗的小Q 2011-10-06 10:27:24
正在做一个linux下的视频监控项目,使用Qt开发,想从摄像头采集图像实时显示出来并同时录制成视频文件
现在已完成从摄像头采集图像到内存,如何实现显示和视频录制呢?

查里很多资料建议说是使用ffmpeg,这个东东完全没有接触过

有那位大虾可以指导以下ffmpeg的编译安装和结合qt的使用呢?或者有更简单好用的,给些建议,感激不禁~~~
资料越详细越好,有个例子最好。发链接也行,大家多多捧场哈~~~

还有就是录制视频时需要编码,linux下如何查看系统所支持的编码格式呢?这个编码器如何安装呢?安装ffmpeg时会附带安装编码器么?

求高手~求指导~
望加好友、留联系方式当面请教~~~ 先谢谢拉
...全文
1816 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
Ericz 2013-08-14
  • 打赏
  • 举报
回复
用v4l2做
HsjLove 2013-08-13
  • 打赏
  • 举报
回复
我调用这句代码codec = avcodec_find_encoder(CODEC_ID_H264);总是返回空指正,但是如果换成codec = avcodec_find_encoder(CODEC_ID_MPEG1VIDEO);就可以成功运行。我在编译ffmpeg的时候把编码器都包含了,为啥运行的时候找不到H264编码器呢?楼主遇到过这个问题吗?是如何解决的?
cxy20121005 2013-02-27
  • 打赏
  • 举报
回复
你是用什么采集到的?可以交流一下,QQ:1049568282
kongrenxin 2011-12-10
  • 打赏
  • 举报
回复
我也做过一个ffmpeg的项目,主要功能就是对TS流数据进行解码,然后编码,最后又打包成TS流

学习过程就是下载ffmpeg源码包,编译安装直接查看源码包里的INSTALL文件就可以了。然后看ffmpeg.c的源代码,找出处理流程,我看了将近20天源码,才理清里面的基本关系,还差得很远,不过已经解决了工作所需了。由于ffmpeg自带的打包TS流接口都是基于文件操作的,想要生成TS流数据在内存中,需要自己修改源码,添加上对应的接口,再重新编译即可得到自己定制的库文件。

源码包doc/example/encoding-example.c是一个关于编解码的简单示例,不过没什么用处。
int main(int argc, char **argv)
{
const char *filename;

/* must be called before using avcodec lib */
avcodec_init();

/* register all the codecs */
avcodec_register_all();
av_register_all();
if (argc <= 1) {
//audio_encode_example("/tmp/test.mp2");
//audio_decode_example("/tmp/test.sw", "/tmp/test.mp2");

video_encode_example("/tmp/test.mpg");
filename = "/tmp/test.mpg";
} else {
filename = argv[1];
}

// audio_decode_example("/tmp/test.sw", filename);
//video_decode_example("/tmp/test%d.pgm", filename);

return 0;
}
video_encode_example(const char *filename)
{
AVFormatContext *oc;
AVStream *st;
///////////////////////////
AVCodec *codec;
AVCodecContext *c= NULL;
int i, out_size, size, x, y, outbuf_size;
FILE *f;
AVFrame *picture;
uint8_t *outbuf, *picture_buf;

printf("Video encoding\n");
avformat_alloc_output_context2(&oc, NULL, "mpegts", filename);
st = av_new_stream(oc, 0);
if (!st) {
fprintf(stderr, "Could not alloc stream %s@%d\n",__FILE__,__LINE__);
exit(1);
}
/*if((avio_open(&oc->pb, filename, AVIO_FLAG_WRITE)) < 0)
{
fprintf(stderr,"avio_open failed. %s@%d\n",__FILE__,__LINE__);
exit(1);
}*/
/* find the mpeg1 video encoder */
//codec = avcodec_find_encoder(CODEC_ID_MPEG1VIDEO);
codec = avcodec_find_encoder(CODEC_ID_H264);
//codec = avcodec_find_encoder_by_name("libx264");
if (!codec) {
fprintf(stderr, "codec not found %s@%d\n",__FILE__,__LINE__);
exit(1);
}

c = st->codec;

picture= avcodec_alloc_frame();
c->codec_type = AVMEDIA_TYPE_VIDEO;
/* put sample parameters */
c->bit_rate = 400000;
/* resolution must be a multiple of two */
c->width = 704;
c->height = 576;
/* 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;
c->partitions= X264_PART_I8X8;
c->b_quant_factor= 1.30f;
c->i_quant_factor= 1.0 / 1.40f;
c->qcompress=0.9;
/* open it */
if (avcodec_open(c, codec) < 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);
}

if (!(oc->flags & AVFMT_NOFILE))
{
if(url_fopen(&oc->pb,"/tmp/x.ts",URL_WRONLY)<0)
{
av_log(c, AV_LOG_INFO, "can't open the output file");
exit(0);
}
}

if(!oc->nb_streams)
{
av_log(c, AV_LOG_INFO, "output file dose not contain any stream\n");
exit(0);
}

if(av_write_header(oc)<0)
{
av_log(c, AV_LOG_INFO, "Could not write header for output file\n");
exit(1);
}/*
if(hite_avformat_header(oc,NULL)<0)
{
av_log(c, AV_LOG_INFO, "Could not write header for output file\n");
exit(1);
}*/
/* alloc image and output buffer */
outbuf_size = 100000;
outbuf = malloc(outbuf_size);
size = c->width * c->height;
picture_buf = malloc((size * 3) / 2); /* size for YUV 420 */

picture->data[0] = picture_buf;
picture->data[1] = picture->data[0] + size;
picture->data[2] = picture->data[1] + size / 4;
picture->linesize[0] = c->width;
picture->linesize[1] = c->width / 2;
picture->linesize[2] = c->width / 2;
AVPacket pkt;
FILE *fp = fopen("test.yuv","r");

/* encode 1 second of video */
for(i=0;i<2500;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;
}
}
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;
}
}*/
if(fread(picture->data[0],1,size*3/2,fp) <=0) break;
picture->pts++;
/* encode the image */
out_size = avcodec_encode_video(c, outbuf, outbuf_size, picture);
if(out_size > 0)
{
av_init_packet(&pkt);
pkt.pts= av_rescale_q(c->coded_frame->pts, c->time_base, st->time_base);
pkt.flags = 1;
pkt.stream_index= st->index;
pkt.data= outbuf;
pkt.size= out_size;
//*
if(av_write_frame(oc, &pkt)!=0)
{
av_log(c, AV_LOG_INFO, "while write video frame error\n");
exit(0);
} //*/
//convert2ts(oc,&pkt);
fwrite(outbuf, 1, out_size, f);
fflush(f);
}
}
fclose(fp);
/* 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);
if(out_size == 0)
continue;
av_init_packet(&pkt);
pkt.pts= av_rescale_q(c->coded_frame->pts, c->time_base, st->time_base);
pkt.flags = 1;
pkt.stream_index= st->index;
pkt.data= outbuf;
pkt.size= out_size;
//*
if(av_write_frame(oc, &pkt)!=0)
{
av_log(c, AV_LOG_INFO, "while write video frame error\n");
exit(0);
} //*/
//convert2ts(oc,&pkt);
fwrite(outbuf, 1, out_size, f);
}
fclose(f);
free(picture_buf);
free(outbuf);

avcodec_close(c);
av_free(c);
av_free(picture);
printf("\n");
}
李迟 2011-12-07
  • 打赏
  • 举报
回复
ffmpeg有两个例子代码,不过在新版本我是找不到在哪里,你用关键字ffmpeg apiexample output_example搜索一下,主要看里面的初始化、编码、解码用到的API函数。

编码格式应该说是FFMPEG支持,而不是Linux系统。编译ffmpeg后,会生成很多个库(动态库),其中有一个avcodec.dll(这是windows下的,Linux下的可能是avcodec.so,但我没编译过),里面就是编码解码库,如果包括所有的库,这个文件有5MB或6MB那么大。

下面是一个示例:

采集-->内存-->编码(FFMPEG,生成某一种格式,如H264),采一帧保存一帧,这过程都有API函数

显示:
读编码的帧-->解码-->显示(解码出来是YUV420P,可以转换成RGB,用位图显示,QT应该有相关的类,我是用SDL来显示的)

最近恰好在搞FFMPEG,搜索了一点资料,上面的是大约思路,因为这是我工作中搞的,因此,只能透露一下网上的资料。
SMJ019835 2011-12-07
  • 打赏
  • 举报
回复
是啊,哥们,你代表了我们遇到这些问题的人,问了这个问题!
奋斗的小Q 2011-10-11
  • 打赏
  • 举报
回复
楼上仁兄,太感谢你了~~~~
请问源码找到了么?
linux_6 2011-10-09
  • 打赏
  • 举报
回复
两年之前我做个和这非常类似的一个软件, 不过现在早就忘了。 我找找那个源代码吧,不知道还在不在。 找到后发给你。

23,125

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 应用程序开发区
社区管理员
  • 应用程序开发区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧