编码为H264裸流并写文件一
为什么说是裸流呢,因为这篇只讲到把视频编码后写入文件,得到的是一个后缀应该为“.h264”的文件,只能用PotPlayer等功能强大的播放器才能打开,因为它没有容器信息,需要装在MP4、MKV之类的容器中,才是一个真正的视频文件。但这一篇只讲编码后直接写入文件,以生成一个H264裸流文件。
代码是从FFMPEG的2.8版本的官方示例中搬运的:https://ffmpeg.org/doxygen/2.8/decoding_encoding_8c-example.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 |
static void video_encode_example(const char *filename, int codec_id) { AVCodec *codec; AVCodecContext *c= NULL; int i, ret, x, y, got_output; FILE *f; AVFrame *frame; AVPacket pkt; uint8_t endcode[] = { 0, 0, 1, 0xb7 }; printf("Encode video file %s\n", filename); /* find the mpeg1 video encoder */ codec = avcodec_find_encoder(codec_id); if (!codec) { fprintf(stderr, "Codec not found\n"); exit(1); } c = avcodec_alloc_context3(codec); if (!c) { fprintf(stderr, "Could not allocate video codec context\n"); exit(1); } /* 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}; /* emit one intra frame every ten frames * check frame pict_type before passing frame * to encoder, if frame->pict_type is AV_PICTURE_TYPE_I * then gop_size is ignored and the output of encoder * will always be I frame irrespective to gop_size */ c->gop_size = 10; c->max_b_frames = 1; c->pix_fmt = AV_PIX_FMT_YUV420P; if (codec_id == AV_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); } frame = av_frame_alloc(); if (!frame) { fprintf(stderr, "Could not allocate video frame\n"); exit(1); } frame->format = c->pix_fmt; frame->width = c->width; frame->height = c->height; /* 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 */ ret = av_image_alloc(frame->data, frame->linesize, c->width, c->height, c->pix_fmt, 32); if (ret < 0) { fprintf(stderr, "Could not allocate raw picture buffer\n"); exit(1); } /* encode 1 second of video */ for (i = 0; i < 25; i++) { av_init_packet(&pkt); pkt.data = NULL; // packet data will be allocated by the encoder pkt.size = 0; fflush(stdout); /* prepare a dummy image */ /* Y */ for (y = 0; y < c->height; y++) { for (x = 0; x < c->width; x++) { frame->data[0][y * frame->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++) { frame->data[1][y * frame->linesize[1] + x] = 128 + y + i * 2; frame->data[2][y * frame->linesize[2] + x] = 64 + x + i * 5; } } frame->pts = i; /* encode the image */ ret = avcodec_encode_video2(c, &pkt, frame, &got_output); if (ret < 0) { fprintf(stderr, "Error encoding frame\n"); exit(1); } if (got_output) { printf("Write frame %3d (size=%5d)\n", i, pkt.size); fwrite(pkt.data, 1, pkt.size, f); av_free_packet(&pkt); } } /* get the delayed frames */ for (got_output = 1; got_output; i++) { fflush(stdout); ret = avcodec_encode_video2(c, &pkt, NULL, &got_output); if (ret < 0) { fprintf(stderr, "Error encoding frame\n"); exit(1); } if (got_output) { printf("Write frame %3d (size=%5d)\n", i, pkt.size); fwrite(pkt.data, 1, pkt.size, f); av_free_packet(&pkt); } } /* add sequence end code to have a real mpeg file */ fwrite(endcode, 1, sizeof(endcode), f); fclose(f); avcodec_close(c); av_free(c); av_freep(&frame->data[0]); av_frame_free(&frame); printf("\n"); } |
将上述代码中的AVFrame改为从摄像头获取的AVFrame,就实现了摄像头数据编码为H264裸流了,但有几点要注意。
- 代码中的av_opt_set(c->priv_data, "preset", "slow", 0)声明了编码速度,值有ultrafast、superfast、veryfast、faster、fast、medium、slow、slower、veryslow、placebo,越快视频质量则越差,但如果想实现实时编码(即编码速度不慢于输入速度),还要加一句av_opt_set(pOutputVideoCodecCtx->priv_data, "tune", "zerolatency", 0)。
- 每个packet的pts非常重要,当然也比较简单,设置好帧率(time_base)之后,pts累加即可。
- 最后的“get the delayed frames”也叫作“flush encoder”,意思是编码器中一般会缓存一些数据,最后要取出来。第1点中提到的编码速度越快,编码器中缓存的Packet也会越少,反之则越多。
编码为H264裸流并写文件一相关推荐
- ffmpeg封装h264裸流为mp4文件,视频播放速度特别慢-解决
计算实际帧率时,需要从mp4的moov box中的mvhd中取得timescale和duration,将两者相除得到文件总时长, 再从stsz box中取得sample总数,即总帧数sample_co ...
- ffmpeg封装h264裸流为mp4文件,视频播放速度特别慢
计算实际帧率时,需要从mp4的moov box中的mvhd中取得timescale和duration,将两者相除得到文件总时长, 再从stsz box中取得sample总数,即总帧数sample_co ...
- FFmpeg解码H264裸流并转换成opencv Mat
感谢雷霄骅博士的在中文视频编解码的付出,http://blog.csdn.net/leixiaohua1020 最近要搞一些视频推流的事情,要解析H264裸流并且获取opencv格式的Mat数据给算法 ...
- ffmpeg实现将H264裸流封装成.mp4或.avi文件
ffmpeg学习历程 由于我是移植到arm-linux环境(海思HI3521A),H264裸流直接从海思的编码模块VENC获取. H264数据流序列: SPS, PPS, SEI, I, P, ...
- RTSP再学习 -- 利用FFmpeg 将 rtsp 获取H264裸流并保存到文件中
如需转载请注明出处:https://blog.csdn.net/qq_29350001/article/details/78214267 既然已经可以通过 RTSP 获取h264 裸流了.那么通过 F ...
- 音视频开发(17)---RTSP再学习 -- 利用FFmpeg 将 rtsp 获取H264裸流并保存到文件中
RTSP再学习 -- 利用FFmpeg 将 rtsp 获取H264裸流并保存到文件中 https://blog.csdn.net/qq_29350001/article/details/7821426 ...
- h264 裸流打包成mp4 注意事项
需求: Android 端把网络摄像头的一段正在播放的视频流,截取保存成mp4(按录像按钮时开始录像). 实现: ffmpeg + x264 + sdl; h264 裸流 打包成MP4,在网上也有一大 ...
- 【嵌入式开发】用 VLC 显示 树莓派摄像头 H264 裸流
首先树莓派连上网络,并和电脑在同一网段. 树莓派的IP是: 192.168.3.13 电脑的IP是: 192.168.3.6 1.在树莓派上采集 H264裸流,并用UDP发送到电脑. pi@Neil- ...
- java rtp 分片_RTP 协议解包为 H264 裸流
RTP 协议解包为 H264裸流 一. 为什么使用 RTP 协议? TCP 传输流媒体数据由于其可靠性,会造成很大的网络延时和卡顿. UDP 传输由于其不可靠性,会导致丢帧,如果是关键帧,则会花屏一个 ...
最新文章
- Macbook air 键盘标点符号怎么输出?
- att格式汇编指令_ARM汇编伪指令介绍.
- VS调试时怎么跳过for循环?
- Jmeter将JDBC Request查询结果作为下一个接口参数方法
- [水煮 ASP.NET Web API2 方法论](1-6)Model Validation
- python3.6.5安装tensorflow_Win10下用Anaconda安装TensorFlow(图文教程)
- 【CVPR2019】Workshops 研讨会列表及链接
- pom.xml 如果使用 mvn exec:exec 命令运行项目
- 平安夜福利,送3本《从0到1搭建自动化测试框架》
- MapServer使用笔记(二)
- eXeScope的应用
- 深度学习模型---稀疏编码 Sparse Coding
- exosip 对比osip
- Python计算某年某月某日天数
- Go 语言开发工具 LiteIDE x22 发布
- c语言找最大数字,C语言: 键盘输入任意10个整数,找出最大数及最大数的序号。...
- 查询oracle数据库表名和中文名
- CSDN博客运营团队2022年H2总结
- 阿朵洒洒的撒多撒多撒啊
- 2021四川高考成绩等位分查询,2021年四川高考位次排名查询,四川高考位次所对应的学校...
热门文章
- 微信公众号 php支付代码,微信支付PHPSDK之微信公众号支付代码详解
- oracle分类函数总结,oracle中分组排序函数用法
- 网付资讯:刷脸支付代理是正规的吗?
- 2021年暑假数学建模第一次模拟赛:新冠疫情预测(插值,时间序列,微分方程建模)
- Undefined symbol longjmp
- Mac,Linux中用mkdir同时创建多个文件夹
- 谈谈端到端测试(End-to-End Testing)
- RTT-KEIL-AC6编译问题
- Excel 多个单元格合并到一个单元格中的函数
- 开源的python有限元软件_Python与有限元--基于Python编程的有限元分析及应用扩展...