XEncode.h
作用:继承于XCodec,用于编码
1 2 3 4 5 6 7 8 9 10 #pragma once #include "xcodec.h" class XEncode :public XCodec{ public : AVPacket *Encode (const AVFrame* frame) ; std::vector<AVPacket *> End () ; };
AVPacket
是 FFmpeg 库中的一个数据结构,主要用于存储编码后的音频或视频数据包。
在多媒体处理中,数据包通常包含一个完整的编码帧或部分编码帧的比特流数据。
这些数据包可以用于传输、存储或进一步处理,如解码。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 typedef struct AVPacket { uint8_t *data; int size; int64_t pts; int64_t dts; int stream_index; int flags; int64_t duration; void *opaque; AVBufferRef *buf; ... } AVPacket;
XEncode.cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 #include "xencode.h" #include <iostream> #include "xtools.h" using namespace std;extern "C" { #include <libavcodec/avcodec.h> #include <libavutil/opt.h> } AVPacket* XEncode::Encode (const AVFrame* frame) { if (!frame) return nullptr ; unique_lock<mutex> lock (mux_) ; if (!c_) return false ; auto re = avcodec_send_frame (c_, frame); if (re != 0 ) return nullptr ; auto pkt = av_packet_alloc (); re = avcodec_receive_packet (c_, pkt); if (re == 0 ) return pkt; av_packet_free (&pkt); if (re == AVERROR (EAGAIN) || re == AVERROR_EOF) { return nullptr ; } if (re < 0 ) { PrintErr (re); return nullptr ; } return pkt; } std::vector<AVPacket *> XEncode::End () { std::vector<AVPacket*> res; unique_lock<mutex> lock (mux_) ; if (!c_) return res; auto re = avcodec_send_frame (c_, NULL ); if (re != 0 ) return res; while (re >= 0 ) { auto pkt = av_packet_alloc (); re = avcodec_receive_packet (c_, pkt); if (re != 0 ) { av_packet_free (&pkt); break ; } res.push_back (pkt); } return res; }
Encode()
作用:
将原始的音视频帧(AVFrame
)编码成压缩的数据包(AVPacket
)。这是编码过程的核心步骤。
线程安全
@para frame 空间由用户维护
@return 失败范围nullptr 返回的AVPacket用户需要通过av_packet_free清理
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 AVPacket* XEncode::Encode (const AVFrame* frame) { if (!frame) return nullptr ; unique_lock<mutex> lock (mux_) ; if (!c_) return false ; auto re = avcodec_send_frame (c_, frame); if (re != 0 ) return nullptr ; auto pkt = av_packet_alloc (); re = avcodec_receive_packet (c_, pkt); if (re == 0 ) return pkt; av_packet_free (&pkt); if (re == AVERROR (EAGAIN) || re == AVERROR_EOF) { return nullptr ; } if (re < 0 ) { PrintErr (re); return nullptr ; } return pkt; }
End()
作用:用于编码结束时处理剩余的编码数据并将其存储在 std::vector<AVPacket *>
,在完成编码操作后获取所有剩余的编码数据包
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 std::vector<AVPacket *> XEncode::End () { std::vector<AVPacket*> res; unique_lock<mutex> lock (mux_) ; if (!c_) return res; auto re = avcodec_send_frame (c_, NULL ); if (re != 0 ) return res; while (re >= 0 ) { auto pkt = av_packet_alloc (); re = avcodec_receive_packet (c_, pkt); if (re != 0 ) { av_packet_free (&pkt); break ; } res.push_back (pkt); } return res; }