基于网络流音视频包的音视频解码思路

本篇文章对自己项目中的网络媒体流解码流程进行了梳理和总结。本文中的方法不同于一般打开文件或流进行读写的流程,不需要通过avformat_open_input,avformat_find_stream_info等操作获取AVFormatContext,然后遍历不同流信息。此处直接通过解析音视频sequence header包,获取相应的参数来初始化对应的AVCodec和AVCodecContext,然后使用AVCodecContext进行后续的解码操作。由于项目中直接获取到了音视频包,所以也省去了av_read_frame操作。

一般流程:

前提:av_register_all()

1. 构造AVCodec

2. 构造AVCodecContext

3. 解码(注意输入的数据格式)

音频解码(关键函数 avcodec_decode_audio4):

1. 构造AVCodec(AAC为例)

codec = avcodec_find_decoder(AV_CODEC_ID_AAC);

2. 构造AVCodecContext

codec_ctx = avcodec_alloc_context3(codec);
// these params are neccesary when decoding
codec_ctx->sample_fmt = AV_SAMPLE_FMT_FLTP;
codec_ctx->sample_rate = 44100;
codec_ctx->channels = channels;
codec_ctx->channel_layout = AV_CH_LAYOUT_MONO;
if (channels == 2) {
    codec_ctx->channel_layout = AV_CH_LAYOUT_STEREO;
}
// 可选参数aac audio sequence header,当前不设置可以正常解析
//codec_ctx->extradata = (uint8_t*)extradata;
//codec_ctx->extradata_size = extradata_size;

// 别忘了open codec context
if ((ret=avcodec_open2(codec_ctx, codec, NULL)) < 0) {
    error("avcodec_open2 audio codec(AAC) failed.");
    return ret;
}

3. 解码(注意输入的数据格式)

AVPacket pkt;
av_init_packet(&pkt);
pkt.data = (uint8_t*)unit->bytes;
pkt.size = unit->size;frame = av_frame_alloc();

do {
    int got_frame = 0;
    // pkt should be raw aac audio data, that is, without aac header.    // 纯aac音频数据,不包含任何容器头或编码格式头
    ret = avcodec_decode_audio4(codec_ctx, frame, &got_frame, &pkt);
    trace("ret=%d, got_frame=%d, decoded frame size=%d", ret, got_frame, frame->linesize[0]);
    if (ret < 0) {
        char err[1000];
        av_make_error_string(err, 1000, ret);
        error("avcodec_decode_audio4 failed. err=%s", err);
        break;
    }    

    if (!got_frame) {
        ret = ERROR_AAC_NO_FRAME;
        error("avcodec_decode_audio4 no frame.");
        break;
    }

} while (false);
av_free_packet(&pkt);

视频解码(关键函数 avcodec_decode_video2):

1. 构造AVCodec(H.264为例)

codec = avcodec_find_decoder(AV_CODEC_ID_H264);

2. 构造AVCodecContext

codec_ctx = avcodec_alloc_context3(codec);
// extradata(video sequence header SPS, PPS) is neccesary when decoding
codec_ctx->extradata = (uint8_t*)extradata;
codec_ctx->extradata_size = extradata_size;
// 别忘了 open codec ctx
if (avcodec_open2(codec_ctx, codec, NULL) < 0) {
    error("avcodec_open2 video codec(H264) failed.");
    return -1;
}

3. 解码(注意输入的数据格式)

AVPacket pkt;
av_init_packet(&pkt);
pkt.data = (uint8_t*)unit->bytes;
pkt.size = unit->size;
frame = av_frame_alloc();

do {
    int got_picture = 0;
    // pkt should be NAL unit, that is, with 1 byte header.     // 如果是ibmf(iso basic media file format)格式,需要在nalu unit前面加上可变字长的Unit length字段
    // 如果是annexb格式,没有测试过,如果纯nalu数据解码不正常,可以尝试加入nalu的starting code(0x000001/0x00000001)测试。
    ret = avcodec_decode_video2(codec_ctx, frame, &got_picture, &pkt);
    trace("ret=%d, got_picture=%d, decoded frame size=%d", ret, got_picture, frame->linesize[0]*3/2);
    if (ret < 0) {
        error("avcodec_decode_video2 failed. ret=%d", ret);
        break;
    }

    if (!got_picture) {
        ret = ERROR_H264_NO_FRAME;
        error("avcodec_decode_video2 no frame.");
        break;
    }

} while (false);
av_free_packet(&pkt);
时间: 2024-10-14 16:57:26

基于网络流音视频包的音视频解码思路的相关文章

音视频技术 即时通讯SDK

视频流中的DTS/PTS到底是什么? DTS(解码时间戳)和PTS(显示时间戳)分别是解码器进行解码和显示帧时相对于SCR(系统参考)的时间戳.SCR可以理解为解码器应该开始从磁盘读取数据时的时间. mpeg(当前更多的是使用H.264视频技术,如AnyChat SDK)文件中的每一个包都有一个SCR时间戳并且这个时间戳就是读取这个数据包时的系统时间.通常情况下,解码器会在它开始读取mpeg流时启动系统时钟(系统时钟的初始值是第一个数据包的SCR值,通常为0但也可以不从0开始). DTS 时间戳

音视频的编码和解码

主流的媒体解码主要是三种:FFMPEG.live555.MobileVLCKit. FFMPEG:是一种可以用来记录.转移数字音频.视频.并能够将其转化成流的开源的计算机程序.采用LGPL或者GPL许可证.她提供了录制.转化以及流化音视频的完整解决方案.她包含了非常先进的音频.视频编码库:libavcodec.为了保证高可以执行和编解码质量,libavcodec里面有很多都是从头开始的. 需要能力:理解视频编码解码原理和流程.理解图像压缩技术.音视频压缩技术等.网站链接:http://ffmpe

即时通讯——详解音视频同步技术

转自:http://tieba.baidu.com/p/2138076570 摘要:针对网络传输中由于延迟.抖动.网络传输条件变化等因素引起的音视频不同步的问题,设计并实现了一种适应不同网络条件的音视频同步方案.利用音视频编码技术AMR-WB和H.264具有在复杂网络环境中速率可选择的特性,结合RTP时间戳和RTCP反馈检测QOS,通过控制音视频编码方式,实现了动态网络环境下的音视频同步方案.重点介绍了可靠网络环境和动态网络环境下同步算法的设计过程,并通过实际测试验证了此方案的可行性.结果表明,

音视频同步通讯SDK

视频流中的DTS/PTS到底是什么? DTS(解码时间戳)和PTS(显示时间戳)分别是解码器进行解码和显示帧时相对于SCR(系统参考)的时间戳.SCR可以理解为解码器应该开始从磁盘读取数据时的时间. mpeg文件中的每一个包都有一个SCR时间戳并且这个时间戳就是读取这个数据包时的系统时间.通常情况下,解码器会在它开始读取mpeg流时启动系统时钟(系统时钟的初始值是第一个数据包的SCR值,通常为0但也可以不从0开始). DTS 时间戳决定了解码器在SCR时间等于DTS时间时进行解码,PTS时间戳也

音视频同步问题

音视频同步问题 音视频流里都包含了播放速率的信息,音频使用采样率来表示,而视频则采用f/s来表示,但是我们却不能简单地用这两个数据来对音视频进行同步,我们需要使用DTS(解码时间戳)和PTS(播放时间戳)这两个数据:我们知道影视数据在存储时,会存在多种帧形式,例如MPEG中就采用了I,B和P,由于B帧的存在使得PTS和DTS存在不同(原因见附录),如图1所示为一个简单的例子:当然真正影响我们音视频同步的是PTS. 我们可以从影视文件中获得包的PTS,但是我们无法直接获得帧(我们真正关心的)的PT

音视频直播服务平台总结

p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; text-align: center; font: 18.0px "PingFang SC Semibold"; color: #000000 } p.p2 { margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Helvetica; color: #000000; min-height: 13.0px } p.p3 { margin: 0.0px 0.0px 0.0

Android音视频即时通讯软件怎样通过JNI快速实现

Android音视频即时通讯软件怎样通过JNI快速实现 音视频通信 作为独立开发者或想缩短音视频开发周期的公司来说,想要在Android平台下实现音视频通信,最快捷的方法是寻找开源项目或调用其他公司API.之所以这么说是因为音视频通信技术涉及到底层音视频采集.解码. FFmpeg(音视频处理解决方案).媒体流传输协议等太多太多相关技术知识点.试了几个开源项目,视频差强人意,语音与视频不同步等不稳定因素.因此我把目光放到其他公司的API上(点击下载demo程序).demo程序API提供了一系列纯J

即时通讯 音视频录制技术

音视频录制是音视频解决方案中最重要的功能特性之一,特别是一些行业应用中音视频录制是最基本的功能需求,AnyChat作为业界一流的跨平台音视频解决方案,在音视频录制方面也提供了非常完善的整体解决方案,概括起来有如下特点: 1.   可针对单个用户的音频.视频进行录制: 2.   可针对通话双方的音频.视频合成录制,支持画中画.并列模式等多种合成方式: 3.   可以自定义录制参数,包括录制码率.视频分辩率等: 4.   录制的视频格式可自定义,支持MP4(默认).WMV.FLV.MP3等: 5. 

Android平台下通过JNI快速实现音视频通信

音视频通信 作为独立开发者或想缩短音视频开发周期的公司来说,想要在Android平台下实现音视频通信,最快捷的方法是寻找开源项目或调用其他公司API.之所以这么说是因为音视频通信技术涉及到底层音视频采集.解码. FFmpeg(音视频处理解决方案).媒体流传输协议等太多太多相关技术知识点.试了几个开源项目,视频差强人意,语音与视频不同步等不稳定因素.因此我把目光放到其他公司的API上(AnyChat音视频即时通讯解决方案),demo程序API提供了一系列纯Java语言的调用接口,通过JNI即可调用