文档章节

把 ffmpeg AVAudioFifo/AVFrame 数据读到共享内存

UMU
 UMU
发布于 2017/07/20 16:45
字数 513
阅读 358
收藏 0

精选30+云产品,助力企业轻松上云!>>>

一般情况下操作 AVAudioFifo/AVFrame 都是用全套 ffmpeg API,内部自己管理内存,不需要了解它们内部怎么组织内存。比如:

inline int InitFrame(AVFrame *&frame, int frame_size = kTargetSamplesPerFrame)
{
    frame = av_frame_alloc();
    if (nullptr == frame) {
        return AVERROR(ENOMEM);
    }

    frame->nb_samples = frame_size;
    frame->channel_layout = av_get_default_channel_layout(kTargetChannels);
    frame->format = kTargetSampleFormat;
    frame->sample_rate = kTargetSampleRate;

    int error = av_frame_get_buffer(frame, 0);
    if (error < 0) {
        av_frame_free(&frame);
        ATLTRACE2(atlTraceException, 0, "!av_frame_get_buffer(), #%d, %s\n", error, GetAvErrorText(error));
    }
    return error;
}

{
    ...
    AVFrame *frame;
    error_code = InitFrame(frame);
    if (error_code < 0) {
        ATLTRACE2(atlTraceException, 0, __FUNCTION__ ": !InitFrame(), #%d\n", error_code);
        return error_code;
    }
    ON_SCOPE_EXIT([&] {
        av_frame_free(&frame);
    });
    
    int read_size = av_audio_fifo_read(fifo_, (void **)frame->data, kTargetSamplesPerFrame);
    ...
}

这里读了一个 AVFrame 出来,并不需要知道具体的内存布局,但如果要写入 FileMapping 对象里,就得知道了!参考以下函数:

int av_audio_fifo_read(AVAudioFifo *af, void **data, int nb_samples)
{
    int i, size;

    if (nb_samples < 0)
        return AVERROR(EINVAL);
    nb_samples = FFMIN(nb_samples, af->nb_samples);
    if (!nb_samples)
        return 0;

    size = nb_samples * af->sample_size;
    for (i = 0; i < af->nb_buffers; i++) {
        if (av_fifo_generic_read(af->buf[i], data[i], size, NULL) < 0)
            return AVERROR_BUG;
    }
    af->nb_samples -= nb_samples;

    return nb_samples;
}

和 AVFrame 定义:

typedef struct AVFrame {
#define AV_NUM_DATA_POINTERS 8
    /**
     * pointer to the picture/channel planes.
     * This might be different from the first allocated byte
     *
     * Some decoders access areas outside 0,0 - width,height, please
     * see avcodec_align_dimensions2(). Some filters and swscale can read
     * up to 16 bytes beyond the planes, if these filters are to be used,
     * then 16 extra bytes must be allocated.
     *
     * NOTE: Except for hwaccel formats, pointers not needed by the format
     * MUST be set to NULL.
     */
    uint8_t *data[AV_NUM_DATA_POINTERS];

    /**
     * For video, size in bytes of each picture line.
     * For audio, size in bytes of each plane.
     *
     * For audio, only linesize[0] may be set. For planar audio, each channel
     * plane must be the same size.
     *
     * For video the linesizes should be multiples of the CPUs alignment
     * preference, this is 16 or 32 for modern desktop CPUs.
     * Some code requires such alignment other code can be slower without
     * correct alignment, for yet other it makes no difference.
     *
     * @note The linesize may be larger than the size of usable data -- there
     * may be extra padding present for performance reasons.
     */
    int linesize[AV_NUM_DATA_POINTERS];
...
};

以 AV_SAMPLE_FMT_S16 为例,发现 InitFrame() 里的 av_frame_get_buffer() 之后只有 linesize[0] 是非 0,即 data[0] 的分配长度,其它 7 个都是 0,即 data[1] -> data[7] 都没有分配,于是猜测就是读 data[0],长度 linesize[0],尝试把它写到 FileMapping 里,果然是对的。如果 SampleFormat 是带 P 的,就不是只有 data[0] 了,有几个 channel 就有几个 data,要相应改变。

UMU

UMU

粉丝 120
博文 113
码字总数 44317
作品 0
厦门
程序员
私信 提问
加载中
请先登录后再评论。
FFmpeg: AVAudioFifo 总结

一. 说明 AVAudioFifo是FFmpeg提供的一个先入先出的音频缓冲队列。主要要以下几个特点: 操作在样本级别而不是字节级别。 支持多通道的格式,不管是planar还是packed类型。 当写入一个已满的...

夜行过客
03/13
0
0
ffmpeg关于音频的总结(一)

一:关于音频分片的问题 1:无论是不是分片的数据总量是相同的. 2:分片的存储在内存中linesize如果两声道则左右分开占用linesize[0]和linesize[1]. 3:不是分片的存储在内存中两声道不分开,...

朱韦刚
2016/05/25
0
0
FFMpeg.AutoGen(1)讲解官方example代码:Main函数、 解码

FFMpeg是一套C编译的开源工具集。主要用于视频处理,可以编解码视频,建立流媒体服务器等等。官方网站:http://ffmpeg.org/ FFMpeg.AutoGen封装方法以方便C#调用FFmpeg。项目地址:https://g...

伊一线天
05/05
0
0
FFMpeg.AutoGen(1)讲解官方example代码:Main函数、 解码

FFMpeg是一套C编译的开源工具集。主要用于视频处理,可以编解码视频,建立流媒体服务器等等。官方网站:http://ffmpeg.org/ FFMpeg.AutoGen封装方法以方便C#调用FFmpeg。项目地址:https://g...

osc_immhr7su
05/23
14
0
FFMpeg.AutoGen(1)讲解官方example代码:Main函数、 解码

FFMpeg是一套C编译的开源工具集。主要用于视频处理,可以编解码视频,建立流媒体服务器等等。官方网站:http://ffmpeg.org/ FFMpeg.AutoGen封装方法以方便C#调用FFmpeg。项目地址:https://g...

伊一线天
05/05
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Java中C ++ Pair 的等价物是什么? - What is the equivalent of the C++ Pair in Java?

问题: Is there a good reason why there is no Pair<L,R> in Java? 有没有一个很好的理由说明Java中没有Pair<L,R> ? What would be the equivalent of this C++ construct? 这个C ++构造的......

富含淀粉
27分钟前
18
0
在Swift中将字符串拆分成数组? - Split a String into an array in Swift?

问题: Say I have a string here: 说我在这里有一个字符串: var fullName: String = "First Last" I want to split the string base on white space and assign the values to their res......

javail
57分钟前
12
0
中国饭店协会数据表明

记者了解到,中国饭店协会数据表明,2018年全国餐饮收入42716亿元,同比增长9.5%.根据国家统计局数据显示,截至2017年底,限额以上餐饮行业的从业人数达到2232万人,巨大的餐饮市场背后,餐饮行业的...

asd369
今天
35
0
OSChina 周六乱弹 —— 日本的丧尸光天化日之下都开始……

Osc乱弹歌单(2020)请戳(这里) 【今日歌曲】 @薛定谔的兄弟 :分享洛神有语创建的歌单「我喜欢的音乐」: 《風の手枕》- 増田俊郎 手机党少年们想听歌,请使劲儿戳(这里) @码界农民工 :...

小小编辑
今天
77
0
Hacker News 简讯 2020-07-11

更新时间: 2020-07-11 04:01 Investors say agroforestry is climate friendly and also profitable - (mongabay.com) 投资者表示,农林复合林对气候友好,而且也有利可图 得分:86 | 评论:52...

FalconChen
今天
163
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部