libswscale库功能主要包括高度优化的图像缩放、颜色空间和像素格式转换操作。

以下是测试代码(test_ffmpeg_libswscale.cpp):

#include "funset.hpp"
#include <string.h>
#include <iostream>
#include <string>
#include <memory>
#include <fstream>#include <opencv2/opencv.hpp>#ifdef __cplusplus
extern "C" {
#endif#include <libswscale/swscale.h>
#include <libavutil/mem.h>
#include <libavutil/imgutils.h>#ifdef __cplusplus
}
#endifint test_ffmpeg_libswscale_bgr_yuv()
{
#ifdef _MSC_VERconst char* image_name = "E:/GitCode/OpenCV_Test/test_images/lena.png";
#elseconst char* image_name = "test_images/lena.png";
#endifcv::Mat mat = cv::imread(image_name, 1);if (!mat.data || mat.channels() != 3) {fprintf(stdout, "fail to read image: %s\n", image_name);return -1;}int width = mat.cols, height = mat.rows;std::unique_ptr<unsigned char[]> data(new unsigned char[width * height * 3 / 2]);std::unique_ptr<unsigned char[]> data2(new unsigned char[width * height * 3 / 2]);{ // bgr --> yuv420pint align = 1;uint8_t *bgr_data[4], *yuv420p_data[4];int bgr_linesize[4], yuv420p_linesize[4];int bytes1 = av_image_alloc(bgr_data, bgr_linesize, width, height, AV_PIX_FMT_BGR24, align);memcpy(bgr_data[0], mat.data, width*height * 3);int bytes2 = av_image_alloc(yuv420p_data, yuv420p_linesize, width, height, AV_PIX_FMT_YUV420P, align);fprintf(stdout, "bgr size: %d, linesize: %d, %d, %d, yuv420p size: %d, linesize: %d, %d, %d\n",bytes1, bgr_linesize[0], bgr_linesize[1], bgr_linesize[2], bytes2, yuv420p_linesize[0], yuv420p_linesize[1], yuv420p_linesize[2]);if (bytes1 < 0 || bytes2 < 0) {fprintf(stderr, "bgr or yuv420p alloc buffer failed: %d, %d\n", bytes1, bytes2);return -1;}SwsContext* sws_ctx = sws_getContext(width, height, AV_PIX_FMT_BGR24, width, height, AV_PIX_FMT_YUV420P, 0, nullptr, nullptr, nullptr);if (!sws_ctx) {fprintf(stderr, "fail to sws_getContext\n");return -1;}sws_scale(sws_ctx, bgr_data, bgr_linesize, 0, height, yuv420p_data, yuv420p_linesize);#ifdef _MSC_VERconst char* name = "E:/GitCode/OpenCV_Test/test_images/512w_512h.yuv420p";
#elseconst char* name = "test_images/512w_512h.yuv420p";
#endifstd::ofstream fout(name, std::ios::out | std::ios::binary);if (!fout.is_open()) {fprintf(stderr, "fail to open file: %s\n", name);return -1;}memcpy(data.get(), yuv420p_data[0], width*height);memcpy(data.get() + width*height, yuv420p_data[1], width*height / 4);memcpy(data.get() + width*height * 5 / 4, yuv420p_data[2], width*height / 4);fout.write((char*)data.get(), width * height * 3 / 2);fout.close();av_freep(&bgr_data[0]);av_freep(&yuv420p_data[0]);sws_freeContext(sws_ctx);
}{ // yuv420p --> bgr24int align = 1;uint8_t *bgr_data[4], *yuv420p_data[4];int bgr_linesize[4], yuv420p_linesize[4];int bytes1 = av_image_alloc(bgr_data, bgr_linesize, width, height, AV_PIX_FMT_BGR24, align);int bytes2 = av_image_alloc(yuv420p_data, yuv420p_linesize, width, height, AV_PIX_FMT_YUV420P, align);memcpy(yuv420p_data[0], data.get(), width*height);memcpy(yuv420p_data[1], data.get() + width*height, width*height / 4);memcpy(yuv420p_data[2], data.get() + width*height * 5 / 4, width*height / 4);fprintf(stdout, "bgr size: %d, linesize: %d, %d, %d, yuv420p size: %d, linesize: %d, %d, %d\n",bytes1, bgr_linesize[0], bgr_linesize[1], bgr_linesize[2], bytes2, yuv420p_linesize[0], yuv420p_linesize[1], yuv420p_linesize[2]);if (bytes1 < 0 || bytes2 < 0) {fprintf(stderr, "bgr or yuv420p alloc buffer failed: %d, %d\n", bytes1, bytes2);return -1;}SwsContext* sws_ctx = sws_getContext(width, height, AV_PIX_FMT_YUV420P, width, height, AV_PIX_FMT_BGR24, 0, nullptr, nullptr, nullptr);if (!sws_ctx) {fprintf(stderr, "fail to sws_getContext\n");return -1;}sws_scale(sws_ctx, yuv420p_data, yuv420p_linesize, 0, height, bgr_data, bgr_linesize);#ifdef _MSC_VERconst char* name = "E:/GitCode/OpenCV_Test/test_images/yuv420ptobgr24.jpg";
#elseconst char* name = "test_images/yuv420ptobgr24.jpg";
#endifcv::Mat dst(height, width, CV_8UC3, bgr_data[0]);cv::imwrite(name, dst);av_freep(&bgr_data[0]);av_freep(&yuv420p_data[0]);sws_freeContext(sws_ctx);
}{ // bgr --> nv12int align = 1;uint8_t *bgr_data[4], *nv12_data[4];int bgr_linesize[4], nv12_linesize[4];int bytes1 = av_image_alloc(bgr_data, bgr_linesize, width, height, AV_PIX_FMT_BGR24, align);memcpy(bgr_data[0], mat.data, width*height * 3);int bytes2 = av_image_alloc(nv12_data, nv12_linesize, width, height, AV_PIX_FMT_NV12, align);fprintf(stdout, "bgr size: %d, linesize: %d, %d, %d, nv12 size: %d, linesize: %d, %d, %d\n",bytes1, bgr_linesize[0], bgr_linesize[1], bgr_linesize[2], bytes2, nv12_linesize[0], nv12_linesize[1], nv12_linesize[2]);if (bytes1 < 0 || bytes2 < 0) {fprintf(stderr, "bgr or nv12 alloc buffer failed: %d, %d\n", bytes1, bytes2);return -1;}SwsContext* sws_ctx = sws_getContext(width, height, AV_PIX_FMT_BGR24, width, height, AV_PIX_FMT_NV12, 0, nullptr, nullptr, nullptr);if (!sws_ctx) {fprintf(stderr, "fail to sws_getContext\n");return -1;}sws_scale(sws_ctx, bgr_data, bgr_linesize, 0, height, nv12_data, nv12_linesize);#ifdef _MSC_VERconst char* name = "E:/GitCode/OpenCV_Test/test_images/512w_512h.nv12";
#elseconst char* name = "test_images/512w_512h.nv12";
#endifstd::ofstream fout(name, std::ios::out | std::ios::binary);if (!fout.is_open()) {fprintf(stderr, "fail to open file: %s\n", name);return -1;}memcpy(data2.get(), nv12_data[0], width*height);memcpy(data2.get() + width*height, nv12_data[1], width*height / 2);fout.write((char*)data2.get(), width * height * 3 / 2);fout.close();av_freep(&bgr_data[0]);av_freep(&nv12_data[0]);sws_freeContext(sws_ctx);
}{ // nv12 --> bgr24int align = 1;uint8_t *bgr_data[4], *nv12_data[4];int bgr_linesize[4], nv12_linesize[4];int bytes1 = av_image_alloc(bgr_data, bgr_linesize, width, height, AV_PIX_FMT_BGR24, align);int bytes2 = av_image_alloc(nv12_data, nv12_linesize, width, height, AV_PIX_FMT_NV12, align);memcpy(nv12_data[0], data2.get(), width*height);memcpy(nv12_data[1], data2.get() + width*height, width*height / 2);fprintf(stdout, "bgr size: %d, linesize: %d, %d, %d, nv12 size: %d, linesize: %d, %d, %d\n",bytes1, bgr_linesize[0], bgr_linesize[1], bgr_linesize[2], bytes2, nv12_linesize[0], nv12_linesize[1], nv12_linesize[2]);if (bytes1 < 0 || bytes2 < 0) {fprintf(stderr, "bgr or nv12 alloc buffer failed: %d, %d\n", bytes1, bytes2);return -1;}SwsContext* sws_ctx = sws_getContext(width, height, AV_PIX_FMT_NV12, width, height, AV_PIX_FMT_BGR24, 0, nullptr, nullptr, nullptr);if (!sws_ctx) {fprintf(stderr, "fail to sws_getContext\n");return -1;}sws_scale(sws_ctx, nv12_data, nv12_linesize, 0, height, bgr_data, bgr_linesize);#ifdef _MSC_VERconst char* name = "E:/GitCode/OpenCV_Test/test_images/nv12tobgr24.jpg";
#elseconst char* name = "test_images/nv12tobgr24.jpg";
#endifcv::Mat dst(height, width, CV_8UC3, bgr_data[0]);cv::imwrite(name, dst);av_freep(&bgr_data[0]);av_freep(&nv12_data[0]);sws_freeContext(sws_ctx);
}return 0;
}int test_ffmpeg_libswscale_scale()
{// bgr to rgb and resize
#ifdef _MSC_VERconst char* image_name = "E:/GitCode/OpenCV_Test/test_images/lena.png";
#elseconst char* image_name = "test_images/lena.png";
#endifcv::Mat src = cv::imread(image_name, 1); if (!src.data || src.channels() != 3) {fprintf(stderr, "fail to read image: %s\n", image_name);return -1;}int width_src = src.cols, height_src = src.rows;int width_dst = width_src / 1.5, height_dst = height_src / 1.2;std::unique_ptr<uint8_t[]> data(new uint8_t[width_dst * height_dst * 3]);SwsContext* ctx = sws_getContext(width_src, height_src, AV_PIX_FMT_BGR24, width_dst, height_dst, AV_PIX_FMT_RGB24, SWS_FAST_BILINEAR, nullptr, nullptr, nullptr);if (!ctx) {fprintf(stderr, "fail to sws_getContext\n");return -1;}const uint8_t* p1[1] = {(const uint8_t*)src.data};uint8_t* p2[1] = {data.get()};int src_stride[1] = {width_src * 3};int dst_stride[1] = {width_dst * 3};sws_scale(ctx, p1, src_stride, 0, height_src, p2, dst_stride);
#ifdef _MSC_VERconst char* result_image_name = "E:/GitCode/OpenCV_Test/test_images/lena_resize_rgb_libswscale.png";
#elseconst char* result_image_name = "test_images/lena_resize_rgb_libswscale.png";
#endifcv::Mat dst(height_dst, width_dst, CV_8UC3, (unsigned char*)data.get());cv::imwrite(result_image_name, dst);sws_freeContext(ctx);return 0;
}int test_ffmpeg_libswscale_colorspace()
{fprintf(stdout, "swscale configuration: %s\n", swscale_configuration());fprintf(stdout, "swscale license: %s\n", swscale_license());AVPixelFormat pix_fmt = AV_PIX_FMT_YUV420P;fprintf(stdout, "is supported input:: %d\n", sws_isSupportedInput(pix_fmt));pix_fmt = AV_PIX_FMT_BGR24;fprintf(stdout, "is supported output: %d\n", sws_isSupportedOutput(pix_fmt));pix_fmt = AV_PIX_FMT_GRAY8;fprintf(stdout, "is supported endianness conversion: %d\n", sws_isSupportedEndiannessConversion(pix_fmt));// bgr to gray
#ifdef _MSC_VERconst char* image_name = "E:/GitCode/OpenCV_Test/test_images/lena.png";
#elseconst char* image_name = "test_images/lena.png";
#endifcv::Mat src = cv::imread(image_name, 1); if (!src.data || src.channels() != 3) {fprintf(stderr, "fail to read image: %s\n", image_name);return -1;}int width = src.cols, height = src.rows;std::unique_ptr<uint8_t[]> data(new uint8_t[width * height]);SwsContext* ctx = sws_getContext(width, height, AV_PIX_FMT_BGR24, width, height, AV_PIX_FMT_GRAY8, 0, nullptr, nullptr, nullptr);if (!ctx) {fprintf(stderr, "fail to sws_getContext\n");return -1;}const uint8_t* p1[1] = {(const uint8_t*)src.data};uint8_t* p2[1] = {data.get()};int src_stride[1] = {width*3};int dst_stride[1] = {width};sws_scale(ctx, p1, src_stride, 0, height, p2, dst_stride);
#ifdef _MSC_VERconst char* result_image_name = "E:/GitCode/OpenCV_Test/test_images/lena_gray_libswscale.png";
#elseconst char* result_image_name = "test_images/lena_gray_libswscale.png";
#endifcv::Mat dst(height, width, CV_8UC1, (unsigned char*)data.get());cv::imwrite(result_image_name, dst);sws_freeContext(ctx);return 0;
}

其中test_ffmpeg_libswscale_scale的执行结果如下:

GitHub:https://github.com/fengbingchun/OpenCV_Test

FFmpeg中libswscale库简介及测试代码相关推荐

  1. FFmpeg中libswresample库简介及测试代码

    libswresample库功能主要包括高度优化的音频重采样.rematrixing和样本格式转换操作. 以下是测试代码(test_ffmpeg_libswresample.cpp),对音频了解较少, ...

  2. FFmpeg中libavutil库简介及测试代码

    libavutil是一个实用库,用于辅助多媒体编程.此库包含安全的可移植字符串函数.随机数生成器.数据结构.附加数学函数.加密和多媒体相关功能(如像素和样本格式的枚举).libavcodec和liba ...

  3. FFmpeg中RTSP客户端拉流测试代码

    之前在https://blog.csdn.net/fengbingchun/article/details/91355410中给出了通过LIVE555实现拉流的测试代码,这里通过FFmpeg来实现,代 ...

  4. FFmpeg实现获取USB摄像头视频流测试代码

    通过USB摄像头(注:windows7/10下使用内置摄像头,linux下接普通的usb摄像头(Logitech))获取视频流用到的模块包括avformat和avdevice.头文件仅include ...

  5. 人脸识别引擎SeetaFaceEngine中Detection模块使用的测试代码

    人脸识别引擎SeetaFaceEngine中Detection模块用于人脸检测,以下是测试代码: int test_detection() {std::vector<std::string> ...

  6. Windows/Linux TCP Socket网络编程简介及测试代码

    典型的网络应用是由一对程序(即客户程序和服务器程序)组成的,它们位于两个不同的端系统中.当运行这两个程序时,创建了一个客户进程和一个服务器进程,同时它们通过从套接字(socket)读出和写入数据在彼此 ...

  7. 人脸识别引擎SeetaFaceEngine中Identification模块使用的测试代码

    人脸识别引擎SeetaFaceEngine中Identification模块用于比较两幅人脸图像的相似度,以下是测试代码: int test_recognize() {const std::strin ...

  8. 人脸识别引擎SeetaFaceEngine中Alignment模块使用的测试代码

    人脸识别引擎SeetaFaceEngine中Alignment模块用于检测人脸关键点,包括5个点,两个眼的中心.鼻尖.两个嘴角,以下是测试代码: int test_alignment() {std:: ...

  9. c++中STL库 简介 及 使用说明

    致谢:http://www.cppblog.com/bhjjkg/articles/94514.html 该文章讲的很清楚! 作为C++标准不可缺少的一部分,STL应该是渗透在C++程序的角角落落里的 ...

最新文章

  1. QGIS打印布局cheatsheet
  2. javascript 对象方法、类方法、原型方法
  3. 最短路径(SPFA算法)
  4. placeholder的兼容处理方法
  5. 【PHP】xampp配置多个监听端口和不同的网站目录(转)
  6. CAP 3.0 版本正式发布
  7. java collection详解_java 7 collection 详解(一)
  8. 贝叶斯线性回归方法的解释和优点
  9. 开发应用层的需要了解 framework层吗?---不需要!!!!
  10. 怎么查看任天堂账号是哪个服务器的,科普:任天堂账号和NS的本地用户有什么区别?...
  11. 前端那些事之Nuxt.js
  12. IDEA运行test出现 Failed to execute goal org.codehaus.mojo:exec-maven-plugin:16.0.0:exec (default-cli) on
  13. jquery 获取子元素的限制jquery
  14. NYOJ题目171-聪明的kk(dp)
  15. Juno: 字体缩放
  16. 杀毒软件误删文件了怎么办?如何恢复被杀毒软件删除的文件
  17. 魔兽争霸显示比例调整的问题
  18. 办公室装修的五要四不要
  19. 使用xlsxwriter简单的将截图插入excel表格中
  20. 使用freesurfer进行海马亚区分割学习笔记

热门文章

  1. C 语言 结构体_finddata_t _findfirst, _findnext, _findclose 函数讲解
  2. sdk没有登录什么意思_不需要接入SDK的第三方登录及分享
  3. 机器阅读理解(MRC)零基础入门级综述(一)
  4. 使用Vue的filters(本地)或filter(全局)过滤常用数据类型
  5. C语言编译全过程(转贴)
  6. Rocksdb 的优秀代码(二)-- 工业级 打点系统 实现分享
  7. SHELL 技能树(持续更新)
  8. C语言网络编程:多路IO select实现多客户端
  9. 在Proteus中添加标号
  10. .NET泛型解析(下)