FFmpeg源码:av_init_packet、get_packet_defaults、av_packet_alloc函数分析

一、av_init_packet函数

av_init_packet函数定义在FFmpeg源码(本文演示用的FFmpeg源码版本为7.0.1)的源文件libavcodec/avpacket.c中:

cpp 复制代码
/**
 * Initialize optional fields of a packet with default values.
 *
 * Note, this does not touch the data and size members, which have to be
 * initialized separately.
 *
 * @param pkt packet
 *
 * @see av_packet_alloc
 * @see av_packet_unref
 *
 * @deprecated This function is deprecated. Once it's removed,
               sizeof(AVPacket) will not be a part of the ABI anymore.
 */
void av_init_packet(AVPacket *pkt)
{
    pkt->pts                  = AV_NOPTS_VALUE;
    pkt->dts                  = AV_NOPTS_VALUE;
    pkt->pos                  = -1;
    pkt->duration             = 0;
    pkt->flags                = 0;
    pkt->stream_index         = 0;
    pkt->buf                  = NULL;
    pkt->side_data            = NULL;
    pkt->side_data_elems      = 0;
    pkt->opaque               = NULL;
    pkt->opaque_ref           = NULL;
    pkt->time_base            = av_make_q(0, 1);
}

该函数作用是:初始化一个AVPacket类型变量,给其成员变量赋默认值。注意:在最新版本的FFmpeg源码(比如7.0.1版本中)该函数已被弃用,不推荐继续使用。

形参pkt:输出型参数。指针,指向需要被初始化的AVPacket类型变量。该函数不会对pkt->data和pkt->size进行赋值。

返回值:无。

二、get_packet_defaults函数

新版本的FFmpeg源码使用get_packet_defaults函数来代替av_init_packet函数。get_packet_defaults函数定义在源文件libavcodec/avpacket.c中:

cpp 复制代码
/**
 * @brief Undefined timestamp value
 *
 * Usually reported by demuxer that work on containers that do not provide
 * either pts or dts.
 */
static void get_packet_defaults(AVPacket *pkt)
{
    memset(pkt, 0, sizeof(*pkt));

    pkt->pts             = AV_NOPTS_VALUE;
    pkt->dts             = AV_NOPTS_VALUE;
    pkt->pos             = -1;
    pkt->time_base       = av_make_q(0, 1);
}

该函数作用是:初始化一个已经分配了内存的AVPacket类型变量,给其成员变量pts、dts、pos、time_base赋默认值,让其它成员变量字节清零。注意:执行该函数前必须先给形参pkt指向的AVPacket类型变量分配内存,否则可能会导致程序崩溃。

形参pkt:输出型参数。指针,指向需要被初始化的AVPacket类型变量。执行该函数后:

pkt->pts和pkt->dts的值会变为AV_NOPTS_VALUE,也就是十进制的:-9223372036854775808。

宏AV_NOPTS_VALUE定义在libavutil/avutil.h中,表示时间戳的值未定义:

cpp 复制代码
/**
 * @brief Undefined timestamp value
 *
 * Usually reported by demuxer that work on containers that do not provide
 * either pts or dts.
 */

#define AV_NOPTS_VALUE          ((int64_t)UINT64_C(0x8000000000000000))

pkt->pos的值会变为-1,pkt->time_base->num的值会变为0,pkt->time_base->den的值会变为1。av_make_q函数的用法可以参考:《FFmpeg有理数相关的源码:AVRational结构体和其相关的函数分析》。

返回值:无

三、av_packet_alloc函数

av_packet_alloc函数定义在源文件libavcodec/avpacket.c中:

cpp 复制代码
/**
 * Allocate an AVPacket and set its fields to default values.  The resulting
 * struct must be freed using av_packet_free().
 *
 * @return An AVPacket filled with default values or NULL on failure.
 *
 * @note this only allocates the AVPacket itself, not the data buffers. Those
 * must be allocated through other means such as av_new_packet.
 *
 * @see av_new_packet
 */
AVPacket *av_packet_alloc(void)
{
    AVPacket *pkt = av_malloc(sizeof(AVPacket));
    if (!pkt)
        return pkt;

    get_packet_defaults(pkt);

    return pkt;
}

该函数作用是:给一个AVPacket类型变量分配内存,并对其成员变量进行初始化。注意:该函数只会给AVPacket本身分配内存,而不会给里面的数据缓冲区(成员变量data和buf指向的缓冲区)分配内存。要想给里面的数据缓冲区分配内存可以使用av_new_packet函数。可以看到该函数内部调用了av_malloc函数来分配内存,关于av_malloc函数用法可以参考:《FFmpeg中内存分配和释放相关的源码:av_malloc函数、av_mallocz函数、av_free函数和av_freep函数分析》。

形参:无

返回值:指针,指向被分配了内存和初始化了的AVPacket类型变量。通过该函数得到的AVPacket类型变量之后必须通过av_packet_free()来释放其空间。

相关推荐
Java陈序员5 小时前
直播录制神器!一款多平台直播流自动录制客户端!
python·docker·ffmpeg
简鹿办公4 天前
FFmpeg vs 去水印软件:哪种方式更适合你?
ffmpeg·怎样去除视频水印·如何去视频logo视频水印
小狮子安度因4 天前
ffplay数据结构分析
数据结构·ffmpeg
小狮子安度因5 天前
ffplay音频重采样
ffmpeg·音视频
小狮子安度因5 天前
AAC ADTS格式分析
网络·ffmpeg·aac
勘察加熊人5 天前
ffmpeg切割音频
ffmpeg·音视频
xiaohouzi1122336 天前
Python读取视频-硬解和软解
python·opencv·ffmpeg·视频编解码·gstreamer
kimble_xia@oracle7 天前
性能优化笔记
ffmpeg
wang_chao1187 天前
RK3399平台ffmpeg-VPU硬编码录制USB摄像头视频、H264或MJPEG编码
ffmpeg·音视频
鹅毛在路上了9 天前
C++, ffmpeg, libavcodec-RTSP拉流,opencv实时预览
c++·opencv·ffmpeg