1. 获取像素格式转换的上下文

sws_getCachedContext

2. 像素转换

sws_scale

#include <iostream>
#include <thread>using namespace std;//测试解封装
extern "C"{
#include "libavformat/avformat.h"
#include "libavcodec/avcodec.h"
#include "libswscale/swscale.h"
}//引用库
#pragma comment(lib,"avformat.lib")
#pragma comment(lib,"avutil.lib")
#pragma comment(lib,"avcodec.lib")
#pragma comment(lib,"swscale.lib")//static修饰的分数转浮点函数,避免功能性函数重定义
static double r2d(AVRational r)
{return (r.den == 0) ? 0 : (double)r.num/(double)r.den;
}void XSleep(int ms)
{// c++11chrono::milliseconds du(ms);this_thread::sleep_for(du);
}int main(int argc, char* argv[])
{cout << "Test Demux FFmpeg.club" << endl;//初始化封装库av_register_all();//初始化网络库 可以打开rtsp rtmp http 协议的流媒体视频)avformat_network_init();//注册解码器avcodec_register_all();//参数设置AVFormatContext *ic = NULL;const char* path = "abc.mp4";AVDictionary *opts = NULL;//NULL表示使用默认配置//设置rtsp流,以tcp协议打开//av_dict_set(&opts, "rtsp_transport", "tcp", 0);//设置网络延时时间//av_dict_set(&opts, "max_delay", "500", 0);//解封装上下文int ret = avformat_open_input(&ic,path,     //视频源0,         //0表示自动选择解封装器&opts      //参数设置,比如rtsp的延时时间);if (ret != 0){char buff[1024] = { 0 };av_strerror(ret, buff, sizeof(buff) - 1);cout << "open " << path << " failed ! :" << buff << endl;getchar();return -1;}cout << "open " << path << " succeed !" << endl;//获取流信息ret = avformat_find_stream_info(ic, 0);//总时长int totalTime = ic->duration/AV_TIME_BASE;cout << path << " total time is " << totalTime << " s." << endl;//打印视频流详细信息av_dump_format(ic, 0, path, 0);//音视频索引,用于读取时区分音视频数据int audioStream = 0;int videoStream = 1;//获取音视频流信息 (通过遍历,或函数获取)//遍历方式for (int i = 0; i < ic->nb_streams; i++){AVStream *as = ic->streams[i];cout << "format = " << as->codecpar->format << endl;cout << "codec_id = " << as->codecpar->codec_id << endl;//音频if (as->codecpar->codec_type == AVMEDIA_TYPE_AUDIO){audioStream = i;cout << i << "音频信息" << endl;cout << "sample_rate = " <<as->codecpar->sample_rate << endl;//AVSampleFormatcout << "channels = " << as->codecpar->channels << endl;//一帧数据:单通道样本数cout << "frame size = " << as->codecpar->frame_size << endl;}//视频if (as->codecpar->codec_type == AVMEDIA_TYPE_VIDEO){videoStream = i;cout << i << "视频信息" << endl;//这里边可能没有宽高参数cout << "width = " << as->codecpar->width << endl;cout << "height = " << as->codecpar->height << endl;//帧率 fps cout << "video FPS = " << r2d(as->avg_frame_rate) << endl;}}//函数方式获取audioStream = av_find_best_stream(ic, AVMEDIA_TYPE_AUDIO, -1, -1, NULL, 0);/////视频解码器打开//找到解码器AVCodec *vcodec = avcodec_find_decoder(ic->streams[videoStream]->codecpar->codec_id);if (!vcodec){cout << "couldn't found the codec, codec_id is " << ic->streams[videoStream]->codecpar->codec_id << endl;getchar();return -1;}cout << "video AVCodec id is :" << ic->streams[videoStream]->codecpar->codec_id << endl;//创建解码器上下文AVCodecContext *vc = avcodec_alloc_context3(vcodec);//配置解码器上下文参数(由streams中的配置复制过来)avcodec_parameters_to_context(vc, ic->streams[videoStream]->codecpar);//8线程解码vc->thread_count = 8;//打开解码器上下文ret = avcodec_open2(vc, 0, 0);if (ret != 0){char buff[1024] = { 0 };av_strerror(ret, buff, sizeof(buff) - 1);cout << "avcodec_open2 error ! " << buff << endl;getchar();return -1;}cout << "video avcodec_open2 succeed ! " << endl;getchar();/////音频解码器打开//找到解码器AVCodec *acodec = avcodec_find_decoder(ic->streams[audioStream]->codecpar->codec_id);if (!acodec){cout << "couldn't found the codec, codec_id is " << ic->streams[audioStream]->codecpar->codec_id << endl;getchar();return -1;}cout << "audio AVCodec id is :" << ic->streams[audioStream]->codecpar->codec_id << endl;//创建解码器上下文AVCodecContext *ac = avcodec_alloc_context3(acodec);//配置解码器上下文参数(由streams中的配置复制过来)avcodec_parameters_to_context(ac, ic->streams[audioStream]->codecpar);//8线程解码vc->thread_count = 8;//打开解码器上下文ret = avcodec_open2(ac, 0, 0);if (ret != 0){char buff[1024] = { 0 };av_strerror(ret, buff, sizeof(buff) - 1);cout << "avcodec_open2 error ! " << buff << endl;getchar();return -1;}cout << "audio avcodec_open2 succeed ! " << endl;getchar();//AVPacket 申请空间、初始化AVPacket *pkt = av_packet_alloc();//AVFrame 申请空间、初始化AVFrame *frame = av_frame_alloc();//像素格式转换上下文SwsContext *vctx = NULL;unsigned char *rgb = NULL;while (1){int ret = av_read_frame(ic, pkt);if (ret){//读到结尾cout << "==============end==============" << endl;//跳转到3秒位置int ms = 3000;//3秒,根据时间基数转换int64_t pos = (double)ms / (double)1000 * r2d(ic->streams[pkt->stream_index]->time_base);av_seek_frame(ic, 0, pos, AVSEEK_FLAG_BACKWARD | AVSEEK_FLAG_FRAME);cout << " \\ \\ \\ \\ \\ \\ \\ \\ at 3 ms" << endl;continue;}cout << "pkt->size = " << pkt->size << endl;//显示的时间cout << "pkt->pts = " << pkt->pts << endl;cout << "pkt->pts ms = " << pkt->pts * (r2d(ic->streams[pkt->stream_index]->time_base) * 1000) << endl;//XSleep(500);//解码的时间cout << "pkt->dts = " << pkt->dts << endl;//解码上下文AVCodecContext *cc = 0;if (pkt->stream_index == videoStream){cc = vc;cout << "图像" << endl;}if (pkt->stream_index == audioStream){cc = ac;cout << "音频" << endl;}///解码视频//发送packet到线程解码,发完立即返回ret = avcodec_send_packet(cc, pkt);//释放库内部单次使用的内存,并将引用计数-1av_packet_unref(pkt);if (ret != 0){char buff[1024] = { 0 };av_strerror(ret, buff, sizeof(buff) - 1);cout << " avcodec_send_packet error, " << buff << endl;continue;}while (1){//从线程中拿解码后的数据,一次send可能对应多次receiveret = avcodec_receive_frame(cc, frame);if (ret != 0){break;}cout << " recv frame " << frame->format << " " << frame->linesize[0] << endl;//视频像素转换if (cc == vc){//创建或拿到转换上下文vctx = sws_getCachedContext(vctx,        //传递NULL会新创建frame->width, frame->height,  //输入的宽高(AVPixelFormat)frame->format,     //输入的格式frame->width, frame->height,   //输出的宽高AV_PIX_FMT_RGBA,             //输出格式RGBASWS_BILINEAR,                 //转换的算法0,0,0);if (vctx){cout << " 像素格式尺寸转换上下文创建或者获取成功 ! " << endl;if (rgb == NULL){rgb = new unsigned char[frame->width*frame->height * 4];}uint8_t *data[2] = { 0 };data[0] = rgb;int lines[2] = { 0 };lines[0] = frame->width * 4;//调用像素转换sws_scale(vctx,frame->data,     //输入数据frame->linesize,   //输入行大小0,frame->height,      //输入高度data,             //输出的数据和大小lines);}else{cout << " 像素格式尺寸转换上下文创建或者获取失败 ! " << endl;}}}}//释放空间av_frame_free(&frame);av_packet_free(&pkt);if (ic){//释放封装上下文,并把ic并置0avformat_close_input(&ic);}getchar();return 0;
}

FFmpeg学习之视频像素和尺寸转换相关推荐

  1. 【专题3:电子工程师 之 上位机】 之 【44.使用ffmpeg对视频解码、视频像素和尺寸转换、重采样】

    嵌入式工程师成长之路 系列文章 总目录 希望本是无所谓有,无所谓无的,这正如脚下的路,其实地上本没有路,走的人多了,也便成了路 原创不易,文章会持续更新 文章会同步到作者个人公众号上,感谢扫码关注 所 ...

  2. FFMPEG学习----打印视频信息

    FFMPEG学习资料少之又少,在此推荐雷神的博客: http://blog.csdn.net/leixiaohua1020 在这里,我们把打印视频里的相关信息作为学习FFMPEG的 Hello Wor ...

  3. ffmpeg学习十三:图像数据格式的转换与图像的缩放

    一.实现图像数据格式转换与图像缩放的三个重要函数 ffmpeg实现图像数据格式的转换以及图片的缩放的功能,主要使用swscale.h中的三个函数: sws_getContext() sws_scale ...

  4. FFMPEG学习----解码视频

    基础概念 我们平时看到的视频文件有许多格式,比如 avi, mkv, rmvb, mov, mp4等等,这些被称为容器(Container), 不同的容器格式规定了其中音视频数据的组织方式(也包括其他 ...

  5. 解码(五):sws_getContext和sws_scale像素格式和尺寸转换函数详解

    视频像素格式和尺寸转换 sws_getContext(像素格式转换上下文),提供了两个函数 sws_getContext像素格式上下文初始化代码演示 如下代码: //表示是视频if (cc == vc ...

  6. FFmpeg 像素格式转换和尺寸转换

    Demo FFmpeg 可以实现像素格式转换和尺寸转换,但是性能开销非常大,对视频帧率影响比较大,实际开发中最好用 Shader来实现,FFmpeg的优势转换接口比较简单. 像素格式转换上下文 Sws ...

  7. ffmpeg学习日记612-指令-转换视频格式

    ffmpeg学习日记612-指令-转换视频格式 mkv转mp4 ffmpeg -i LostInTranslation.mkv -codec copy LostInTranslation.mp4 Li ...

  8. ffmpeg学习日记602-指令-转换视频的分辨率

    ffmpeg学习日记602-指令-转换视频的分辨率 指令如下 ffmpeg -i video_1920.mp4 -vf scale=640:360 video_640.mp4 -hide_banner

  9. FFmpeg学习(音视频理论知识)

    文章目录 1. 音视频理论知识 1.1 基本概念 1.1.1 音视频必备的基本概念 常用的视频封装格式 常用的视频编码器 常用的音频编程器: 视频流 裸数据YUV 1.1.2 音视频常见处理 采集 处 ...

最新文章

  1. shell清除日志小脚本
  2. 学python工资高吗-现在Python就业薪资高吗?
  3. win2012中让IIS同时支持多版本ASP.NET 3.5/4.0/4.5的方法
  4. 创新实训个人记录:metric k-center
  5. 弱引用什么时候被回收_Java引用类型有哪些
  6. Zero Copy 简介
  7. python跟谁学_Python 应该怎么学?
  8. RTX5 | 时间延时
  9. php serialize和json_encode哪个更快_学习PHP的10个技巧
  10. unity UI如何开启(显示)或者关闭(隐藏)Panel界面最好?
  11. 化学人学python有前途吗-用Python解析化学公式
  12. 超全面UI基础设计规范
  13. 项目领导力与决策管理
  14. 【NOI OJ】1818 红与黑
  15. html基本标签斜体,请选择产生斜体字的HTML标签:
  16. 【前端春招】前端春招实习+秋招心路历程
  17. 工作站(集群)使用说明及相关工具
  18. 基于JAVA传统文化知识竞赛系统计算机毕业设计源码+系统+数据库+lw文档+部署
  19. Vue实现一键复制文本内容
  20. 南方的X-Men看过来〜Cocos2d-x开发者沙龙(广州站)即将举办!

热门文章

  1. CDH修改静态资源池配置,NodeManager重启失败问题
  2. 电动汽车有序充电调度优化
  3. Linux more命令
  4. HTML5+CSS3 - 视频背景的实现
  5. 支付宝:你当前操作的设备存在异常,请尝试使用经常登录的手机操作
  6. 学习笔记(2):走近智慧医疗,探索物联网创新应用新方向-智慧医疗 健康管理解块方案自助体检解决方案
  7. 电子电路课程设计——8位数字抢答器设计论文
  8. java 计算周_java – Joda时间周计算推理
  9. 概率论与数理统计习题——第五讲——等可能概型(古典概型)
  10. h5 获取当前地理位置信息