音视频开发(五)——转码


我的大部分学习都来自雷神,没有基础去雷神博客转转,每次都有很多收获。
https://blog.csdn.net/leixiaohua1020/article/details/42658139

转码,就是将一个不需要的格式转换成为自己需要的格式。

首先,研究不带编解码的转码(更换后缀名??)。
本次实验把avi转码为mp4。

一、输入初始化

const char *url = "my.avi";
AVFormatContext *ic = avformat_alloc_context();

然后获取信息(就不加错误判定了,具体前面解码有讲)

int ret = avformat_open_input(&ic, url, NULL, NULL);
ret = avformat_find_stream_info(ic, NULL);
av_dump_format(ic, 0, url, 0);

二、输出初始化

这步比较简单

AVFormatContext *oc;
const char *outputPath = "out.mp4";
avformat_alloc_output_context2(&oc, NULL, NULL, outputPath);

三、创建输出流

根据输入 in 创建输出 out
使用的都是最新的API

1.使用codecpar替代codec

AVCodec *codec = avcodec_find_decoder(ic->streams[i]->codecpar->codec_id);
AVCodecContext *codecCtx = avcodec_alloc_context3(codec);
AVStream *in = ic->streams[i];
AVStream *out = avformat_new_stream(oc, codec);

2.使用avcodec_parameters_to_context(),avcodec_parameters_from_context()代替了avcodec_copy_context()

ret = avcodec_parameters_to_context(codecCtx, in->codecpar);
codecCtx->codec_tag = 0;
if(oc->oformat->flags & AVFMT_GLOBALHEADER)
    codecCtx->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
ret = avcodec_parameters_from_context(out->codecpar, codecCtx);

四、打开输出文件获取信息,写文件头

if (avio_open(&oc->pb, outputPath, AVIO_FLAG_READ_WRITE) < 0)
av_dump_format(oc, 0, outputPath, 1);

ret = avformat_write_header(oc, NULL);

五、转换pts、dts并写入

pkt.pts = av_rescale_q_rnd(pkt.pts, in->time_base, out->time_base, (AVRounding)(AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX));
pkt.dts = av_rescale_q_rnd(pkt.dts, in->time_base, out->time_base, (AVRounding)(AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX));
pkt.duration = av_rescale_q(pkt.duration, in->time_base, out->time_base);
av_interleaved_write_frame(oc, &pkt);

六、写文件尾,释放空间

av_write_trailer(oc);

avformat_close_input(&ic);
if (oc && !(oc->oformat->flags & AVFMT_NOFILE))
    avio_close(oc->pb);
avformat_free_context(oc);

下一步研究带编解码的转码。最后,附上源码。

附源码

int main()
{
    const char *url = "my.avi";
    AVFormatContext *ic = avformat_alloc_context();

    int ret = avformat_open_input(&ic, url, NULL, NULL);
    

	ret = avformat_find_stream_info(ic, NULL);
    av_dump_format(ic, 0, url, 0);

	AVFormatContext *oc;
	const char *outputPath = "out.mp4";
	avformat_alloc_output_context2(&oc, NULL, NULL, outputPath);

	unsigned int i;
	for(i = 0; i < ic->nb_streams; i++)
	{
	    AVStream *in = ic->streams[i];
	    AVCodec *codec = avcodec_find_decoder(ic->streams[i]->codecpar->codec_id);
	    AVCodecContext *codecCtx = avcodec_alloc_context3(codec);
	    AVStream *out = avformat_new_stream(oc, codec);
	    ret = avcodec_parameters_to_context(codecCtx, in->codecpar);
	    if(ret < 0)
	    {
	        //failed
	        return -1;
	    }
	    codecCtx->codec_tag = 0;
	    if(oc->oformat->flags & AVFMT_GLOBALHEADER)
	        codecCtx->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
	    ret = avcodec_parameters_from_context(out->codecpar, codecCtx);
	    if(ret < 0)
	    {
	        //failed
	        return -1;
	    }
	}

    if (avio_open(&oc->pb, outputPath, AVIO_FLAG_READ_WRITE) < 0)
     {
        cout << "Failed to open output file!" << endl;
        return -1;
	}

 	av_dump_format(oc, 0, outputPath, 1);

    ret = avformat_write_header(oc, NULL);

    AVPacket pkt;
    av_new_packet(&pkt, 192000);

    while(av_read_frame(ic, &pkt) >= 0)
    {
    	AVStream *in = ic->streams[pkt.stream_index];
    	AVStream *out = oc->streams[pkt.stream_index];
    	pkt.pts = av_rescale_q_rnd(pkt.pts, in->time_base, out->time_base, (AVRounding)(AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX));
    	pkt.dts = av_rescale_q_rnd(pkt.dts, in->time_base, out->time_base, (AVRounding)(AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX));
    	pkt.duration = av_rescale_q(pkt.duration, in->time_base, out->time_base);
    	pkt.pos = -1;

    	av_interleaved_write_frame(oc, &pkt);
    	av_packet_unref(&pkt);
	}
	av_write_trailer(oc);

	avformat_close_input(&ic);
	if (oc && !(oc->oformat->flags & AVFMT_NOFILE))
	    avio_close(oc->pb);
	avformat_free_context(oc);

    return 0;
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Linux音视频开发是指在Linux操作系统上进行音视频相关应用程序的开发。这种开发需要掌握Linux操作系统的基本知识,以及音视频编解码、音视频处理、音视频传输等方面的专业知识。常见的Linux音视频开发包括音视频播放器、音视频采集、音视频编解码、音视频流媒体等应用程序的开发。在Linux音视频开发中,常用的开发工具包括FFmpeg、GStreamer、OpenCV等。 ### 回答2: Linux音视频开发是指在Linux操作系统下进行音视频处理和开发的一系列工作。Linux作为开源操作系统,具有稳定、高效和安全等特点,因此在音视频领域得到了广泛应用。 Linux音视频开发涉及到的技术包括音视频编解码、音视频采集和播放、音频处理和视频处理等。在Linux下,开发人员可以利用开源的音视频开发工具和库,如FFmpeg、GStreamer等,进行音视频编解码、截取和叠加等操作。同时,开发人员也可以通过Linux的音频和视频设备驱动接口,实现音视频的采集和播放。 在Linux音视频开发中,开发人员需要具备音视频编程基础知识和Linux系统编程的技能。他们需要了解音视频信号的原理、编解码算法以及相关的数据格式和协议。此外,他们还需要熟悉Linux操作系统的底层接口和相关工具,掌握Linux系统编程和多线程编程的技术。 Linux音视频开发在众多领域中发挥着重要的作用。例如,在网络通信领域,开发人员可以利用Linux音视频开发技术,实现音频和视频的传输和会议系统的搭建。在娱乐领域,开发人员可以利用Linux音视频开发技术,开发音视频播放器和编辑器等应用程序。 总之,通过Linux音视频开发,人们可以在Linux操作系统下实现丰富的音视频应用。该领域的发展离不开开源社区和开源工具的支持,同时也需要开发人员持续不断地学习和探索,以适应技术的不断更新和新需求的不断出现。 ### 回答3: Linux音视频开发是指在Linux操作系统下进行音视频相关的应用程序开发。Linux操作系统具有很高的稳定性和灵活性,因此在音视频开发领域有着广泛的应用。 在Linux音视频开发中,开发者可以使用各种开源工具和库,如FFmpeg、GStreamer等。FFmpeg是一个强大的多媒体开源框架,可以用来处理音频和视频文件,包括编解码、转码、剪辑、合并等。GStreamer是一个流媒体处理框架,提供了丰富的插件和工具,用于构建各种音视频应用。 在开发过程中,开发者可以使用C/C++等编程语言进行开发,通过这些语言可以调用各种库函数和接口来进行音视频处理。例如,可以使用ALSA库来进行音频输入输出,使用X11或Wayland来进行视频的显示,使用PulseAudio来进行音频混音等。 在Linux音视频开发中,需要熟悉音视频编码、解码、压缩等相关技术。同时,还需要了解网络传输和流媒体传输协议,如RTSP、RTMP、HLS等。这些知识对于开发实时音视频通信、流媒体服务等应用非常重要。 总之,Linux音视频开发是一个广阔而有挑战性的领域。通过使用强大的开源工具和库,结合深入的理解音视频相关技术,开发者可以创建出高质量的音视频应用,满足用户的需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值