IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> ffmpeg h64编码 -> 正文阅读

[C++知识库]ffmpeg h64编码

#include <fstream>
#include <iostream>

extern "C"
{
#include <libavcodec/avcodec.h>
}


#define print(x) std::cout << x << std::endl

void print_av_err(int ret)
{
    char buf[1024] = {0};
    av_strerror(ret, buf, sizeof(buf) - 1);
    std::cerr << buf << std::endl;
}

#define H264

int main(int argc, char **argv)
{
    // 一定要注册,不然会找不到编码器!!!!!!!!!!!!!!!!!
    avcodec_register_all();
    AVCodecID codec_id = AV_CODEC_ID_H264;
    std::string filename = "400_300_25.h264";
   

    // std::ifstream ifs;
    // ifs.open("/workspace/ffmpeg_tutorials/tutorials/ch02/resource/400_300_25.yuv", std::ios::binary);
    // if (!ifs)
    // {
    //     std::cerr << "file1 open failed!" << std::endl;
    //     return -1;
    // }

    std::ofstream ofs;
    ofs.open(filename, std::ios::binary);
    if (!ofs)
    {
        std::cerr << "file2 open failed!" << std::endl;
        return -1;
    }

    // 1.查找编码器
    AVCodec *codec = avcodec_find_encoder(codec_id);
    if (!codec)
    {
        std::cerr << "codec not found!" << std::endl;
        return -1;
    }

    // 2.编码上下文
    AVCodecContext *ctx = avcodec_alloc_context3(codec);
    if (!ctx)
    {
        std::cerr << "context alloc failed!" << std::endl;
        return -1;
    }

    // 3.设定上下文参数
    ctx->width = 400;
    ctx->height = 300;
    ctx->pix_fmt = AV_PIX_FMT_YUV420P;
    ctx->time_base = {1, 25}; //帧时间戳单位,pts帧id,每帧时间=pts*1/25
    ctx->thread_count = 8;    //编码线程数,可以用过调用系统接口获得cpu核心数量

    // 4.打开编码上下文
    auto ret = avcodec_open2(ctx, codec, NULL);
    if (ret)
    {
        char buf[1024] = {0};
        av_strerror(ret, buf, sizeof(buf) - 1);
        std::cerr << "avcodec_open2 failed!" << buf << std::endl;
        return -1;
    }

    std::cout << "codec context 创建成功!" << std::endl;

    // 创建AVFrame
    AVFrame *frame = av_frame_alloc();
    frame->width = ctx->width;
    frame->height = ctx->height;
    frame->format = ctx->pix_fmt;
    // frame->linesize[0] = ctx->width;
    // frame->linesize[1] = ctx->width / 2;
    // frame->linesize[2] = ctx->width / 2;

    ret = av_frame_get_buffer(frame, 0);
    if (ret)
    {
        char buf[1024] = {0};
        av_strerror(ret, buf, sizeof(buf) - 1);
        std::cerr << "frame create failed!" << buf << std::endl;
        return -1;
    }

    // 创建AVPacket
    AVPacket *packet = av_packet_alloc();

    // 开始生成视频文件  10s 25fps

    for (int i = 0; i < 250; ++i)
    {
        // Y
        for (int y = 0; y < ctx->height; ++y)
        {
            for (int x = 0; x < ctx->width; ++x)
            {
                frame->data[0][y * frame->linesize[0] + x] = x + y + i * 3;
            }
        }
        // UV
        for (int y = 0; y < ctx->height / 2; ++y)
        {
            for (int x = 0; x < ctx->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; //帧序列id

        //开始压缩
        ret = avcodec_send_frame(ctx, frame);
        if (ret)
        {
            std::cerr << "avcodec_send_frame failed!" << std::endl;
            break;
        }

        // 等待接收压缩完的数据
        // 一般情况下,前几次会返回null,编码未完成
        // 编码实在独立的线程中执行的,每次调用会重新分配packet中的空间
        while (1)
        {
            ret = avcodec_receive_packet(ctx, packet);
            // 如果读完当前帧, 则退出循环
            if (ret == AVERROR_EOF || ret == AVERROR(EAGAIN))
            {
                std::cerr << "avcodec_receive_packet failed!" << std::endl;
                break;
            }
            if (ret)
            {
                char buf[1024] = {0};
                av_strerror(ret, buf, sizeof(buf) - 1);
                // std::cerr << "avcodec_receive_packet failed!" << buf << std::endl;
                // break;
                continue;
            }
            std::cout << "压缩之后数据大小为:" << packet->size << std::endl;
            ofs.write((char *)packet->data, packet->size);

            // 每次释放packet资源并重新分配
            av_packet_unref(packet);
        }
    }

    av_packet_free(&packet);
    av_frame_free(&frame);

    //释放编码器上下文
    avcodec_free_context(&ctx);

    // ifs.close();
    ofs.close();

    return 0;
}
cmake_minimum_required(VERSION 3.4.1)
SET(CMAKE_CXX_STANDARD 11)

project(main)

add_executable(main main.cpp)
target_link_libraries(main avcodec avutil )
  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-03-21 20:30:30  更:2022-03-21 20:34:36 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 2:45:45-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码