ffmpeg内存管理及API

       

1 解码流程

av_read_frame 将解封装后的数据存入 AVPacket,avcodec_send_packet()函数将原始AVPacket送入解码器, avcodec_receive_frame()  函数将解码后的数据存入AVFrame。

     这个解码过程必定会涉及到内存分配回收问题。在 FFMpeg 中,内存 IO 叫做 buffered IO ,是指将一块内存缓冲区用作 FFmpeg 的输入或者输出,与内存 IO 操作对应的是指定 URL 作为 FFmpeg 的输入或输出。

 AVPacket 音视频压缩数据

AVFrame解码后的原始图像数据

2 内存模型

两个avpacket指向同一AVBuffer空间,FFmpeg使用的引用计数的机制来管理。

 AVBufferFFmpeg中的缓冲区,一开始时AVBuffer的引用计数(refcount)初始化为 0

当有新的Packet引用共享的缓存空间时,就将引用计数再 +1

Packet释放掉对AVBuffer这块共享缓存空间的引用时,将引用计数 -1

只有当refcount为 0 的时候,才会释放掉缓存空间AVBuffer

 AVBuffer 表示数据缓冲区本身,只能通过AVBufferRef访问。

AVBufferRef表示单个对AVBuffer的引用,它是一个可以由调用者直接调用的对象。

附录:

 AVPacket API

  • AVPacket *av_packet_alloc(void);: 分配一个AVPacket,并将其字段设置为默认值。通过这个API分类的Packet必须由av_packet_free释放
  • void av_packet_free(AVPacket **pkt);: 释放掉Packet,如果这个Packet有引用的AVBuffer,将会先释放引用。
  • void av_init_packet(AVPacket *pkt);: 初始化Packet,注意,这并不涉及datasize成员,它们必须分别初始化。
  • int av_new_packet(AVPacket *pkt, int size);: 给AVPacket分配内存,这里引用计数将会+1
  • int av_packet_ref(AVPacket *dst, const AVPacket *src);:增加引用计数
  • void av_packet_unref(AVPacket *pkt);: 减少引用计数
  • void av_packet_move_ref(AVPacket *dst, AVPacket *src);: 将src中的每个字段移动到dst,并重置src
  • AVPacket *av_packet_clone(const AVPacket *src);: 克隆一个与src相同数据的Packet,等于av_packet_alloc()+av_packet_ref(

 AVFrame API

  • AVFrame *av_frame_alloc(void);: 分配一个AVFrame,并将其字段设置为默认值。通过这个API分类的Packet必须由av_frame_free()释放
  • void av_frame_free(AVFrame **frame);: 释放掉AVFrame,如果这个Frame有引用的AVBuffer,将会先释放引用。
  • int av_frame_ref(AVFrame *dst, const AVFrame *src): 增加引用计数
  • void av_frame_unref(AVFrame *frame);: 减少引用计数
  • void av_frame_move_ref(AVFrame *dst, AVFrame *src);: 将src中的每个字段移动到dst,并重置src
  • int av_frame_get_buffer(AVFrame *frame, int align);: 为音频或视频数据分配新的缓冲区。在调用这个字段之前必须在音视频帧上设置下面的字段format (pixel[像素] for video;sample format[采样格式]for audio);      width and height for video;         nb_samples and channel_layout for audi

FFMPEG API

/*  Initialize libavformat and register all the muxers, demuxers and protocols  */
void av_register_all(void);

//Do global initialization of network components

int avformat_network_init(void);
 

/*Allocate and initialize an AVIOContext for buffered I/O. 读写buffer

3 param:write_flag Set to 1 if the buffer should be writable, 0 otherwise

5 param:read_packet  A function for refilling the buffer, may be NULL

6 param:write_packet A function for writing the buffer contents, may be NULL

7param:seek A function for seeking to specified byte position, may be NULL

return:Allocated AVIOContext or NULL on failure*/

AVIOContext* pIOCtx = avio_alloc_context(m_pAvioBuffer, buffer_size, 0, this, &FFmpegPlayCore::EtvxReadFunc, 0, &FFmpegPlayCore::EtvxSeekFunc); 
 

 //Allocate an AVFormatContext.
AVFormatContext *avformat_alloc_context(void);

/*  Open an input stream and read the header. The codecs are not opened  */

int avformat_open_input(AVFormatContext **ps, const char *url, AVInputFormat *fmt, AVDictionary **options);
 

/* Read packets of a media file to get stream information */

int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options);

/* Seek to timestamp ts */

int avformat_seek_file(AVFormatContext *s, int stream_index, int64_t min_ts, int64_t ts, int64_t max_ts, int flags);
 

/* 获取音视频对应的stream_index   */

int av_find_best_stream(AVFormatContext *ic, enum AVMediaType type,
                        int wanted_stream_nb, int related_stream, AVCodec **decoder_ret,  int flags);

//解封装后的数据存入每个AVPacket

int av_read_frame(AVFormatContext *s, AVPacket *pkt);

//Find a registered decoder with a matching codec ID

AVCodec *avcodec_find_decoder(enum AVCodecID id);
 

//Find a registered decoder with the specified name

AVCodec *avcodec_find_decoder_by_name(const char *name);
 

//打开解码器

int avcodec_open2(AVCodecContext *avctx, const AVCodec *codec, AVDictionary **options);
 

//Supply raw packet data as input to a decoder

int avcodec_send_packet(AVCodecContext *avctx, const AVPacket *avpkt);

//Read encoded data from the encoder

int avcodec_receive_packet(AVCodecContext *avctx, AVPacket *avpkt);
 

//解码

int avcodec_decode_video2(AVCodecContext *avctx, AVFrame *picture,
                         int *got_picture_ptr,
                         const AVPacket *avpkt);

//Return decoded output data from a decoder

int avcodec_receive_frame(AVCodecContext *avctx, AVFrame *frame);
 

//Supply a raw video or audio frame to the encoder

int avcodec_send_frame(AVCodecContext *avctx, const AVFrame *frame);
 

/* Start playing a network-based stream (e.g. RTSP stream) at the  current position. */
int av_read_play(AVFormatContext *s);

/* Pause a network-based stream (e.g. RTSP stream) ,Use av_read_play() to resume it  */
int av_read_pause(AVFormatContext *s);


//Close an opened input AVFormatContext.
void avformat_close_input(AVFormatContext **s);

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
FFmpeg是一个开源的跨平台的音视频处理框架,而FFmpeg Java API则是基于Java语言封装了FFmpeg功能的一个库。 使用FFmpeg Java API,我们可以在Java程序中方便地进行音视频的解码、编码、转码、剪切、合并等操作。通过调用FFmpeg的各种命令和参数,可以实现对音视频文件的各种处理需求。 FFmpeg Java API的主要特点包括: 1. 跨平台:由于基于Java语言开发,FFmpeg Java API可以在各种操作系统上使用,包括Windows、Linux、Mac等。 2. 功能强大:FFmpeg提供了丰富的音视频处理功能,FFmpeg Java API则封装了这些功能,使得在Java程序中可以方便地调用。 3. 简单易用:FFmpeg Java API提供了简洁的接口和方法,使得开发者可以快速上手,并快速实现各种音视频处理需求。 4. 高效性能:FFmpeg本身就是一个高性能的音视频处理框架,而FFmpeg Java API则是通过JNI技术与Java进行交互,保证了高效的执行速度和内存管理。 除了基本的音视频编解码功能外,FFmpeg Java API还支持基于滤镜的视频处理、音频处理、字幕添加等功能,使得开发者可以实现更加丰富的音视频处理效果。 总而言之,FFmpeg Java API是一个功能强大、跨平台、简单易用的音视频处理库,可以帮助开发者在Java程序中实现各种音视频处理需求。无论是简单的音视频格式转换,还是复杂的剪辑合成,FFmpeg Java API都能提供便捷的解决方案。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

步基

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值