Improve:MediaBase module.

This commit is contained in:
Fancy code 2024-07-02 17:59:02 +08:00
parent e7ce303ec3
commit ff4eb8bf07
2 changed files with 70 additions and 10 deletions

View File

@ -33,8 +33,9 @@ extern "C" {
#include <cstdlib>
#include <errno.h>
#include <functional>
#include <stdint.h>
FfmpegDecoder::FfmpegDecoder(const enum AVCodecID &codecId)
: mCodecId(codecId), mCodec(nullptr), mCodecCtx(nullptr), mFrame(nullptr)
: mCodecId(codecId), mCodec(nullptr), mCodecCtx(nullptr), mFrame(nullptr), mPacket(nullptr), mParser(nullptr)
{
}
bool FfmpegDecoder::Init(void)
@ -84,6 +85,16 @@ bool FfmpegDecoder::Init(void)
LogError("Could not allocate video frame\n");
return false;
}
mPacket = av_packet_alloc();
if (!mPacket) {
LogError("Could not allocate video frame\n");
return false;
}
mParser = av_parser_init(mCodec->id);
if (!mParser) {
LogError("mParser not found : %s\n", avcodec_get_name(mCodec->id));
return false;
}
if (AVMEDIA_TYPE_AUDIO == mCodec->type) {
mFrame->nb_samples = mCodecCtx->frame_size;
mFrame->format = mCodecCtx->sample_fmt;
@ -105,19 +116,63 @@ bool FfmpegDecoder::UnInit(void)
avcodec_free_context(&mCodecCtx);
mCodecCtx = nullptr;
}
av_packet_free(&mPacket);
mPacket = nullptr;
if (mParser) {
av_parser_close(mParser);
mParser = nullptr;
}
return true;
}
void FfmpegDecoder::DecodeData(const void *data, const size_t &size, std::function<void(AVFrame *frame)> callback)
{
AVPacket *packet = nullptr;
packet = av_packet_alloc();
packet->data = (unsigned char *)data;
packet->size = size;
int ret = avcodec_send_packet(mCodecCtx, packet);
if (nullptr == mParser) {
mPacket->data = (uint8_t *)data;
mPacket->size = size;
// mPacket->stream_index = 0;
mPacket->pts = AV_NOPTS_VALUE;
mPacket->dts = AV_NOPTS_VALUE;
AVDecodeData(mPacket, callback);
return;
}
AVParseData(data, size, callback);
}
void inline FfmpegDecoder::AVParseData(const void *data, const size_t &size,
std::function<void(AVFrame *frame)> callback)
{
if (nullptr == data) {
LogError("data is null\n");
return;
}
uint8_t *frameData = (uint8_t *)data;
size_t data_size = size;
while (data_size > 0) {
int ret = av_parser_parse2(mParser,
mCodecCtx,
&mPacket->data,
&mPacket->size,
frameData,
data_size,
AV_NOPTS_VALUE,
AV_NOPTS_VALUE,
0);
if (ret < 0) {
LogError("av_parse_frame failed\n");
break;
}
frameData += ret;
data_size -= ret;
if (mPacket->size) {
AVDecodeData(mPacket, callback);
}
}
}
void inline FfmpegDecoder::AVDecodeData(AVPacket *pkt, std::function<void(AVFrame *frame)> callback)
{
int ret = avcodec_send_packet(mCodecCtx, pkt);
if (ret < 0) {
LogError("Error sending a packet for decoding\n");
av_packet_unref(packet);
av_packet_free(&packet);
av_packet_unref(pkt);
return;
}
while (ret >= 0) {
@ -134,8 +189,7 @@ void FfmpegDecoder::DecodeData(const void *data, const size_t &size, std::functi
}
break;
}
av_packet_unref(packet);
av_packet_free(&packet);
av_packet_unref(pkt);
}
/* just pick the highest supported samplerate */
int FfmpegDecoder::select_sample_rate(const AVCodec *codec)

View File

@ -42,6 +42,10 @@ public:
bool UnInit(void);
void DecodeData(const void *data, const size_t &size, std::function<void(AVFrame *frame)> callback);
private:
void AVParseData(const void *data, const size_t &size, std::function<void(AVFrame *frame)> callback);
void AVDecodeData(AVPacket *pkt, std::function<void(AVFrame *frame)> callback);
private:
static int select_sample_rate(const AVCodec *codec);
static int select_channel_layout(const AVCodec *codec, AVChannelLayout *dst);
@ -52,5 +56,7 @@ private:
AVCodec *mCodec;
AVCodecContext *mCodecCtx;
AVFrame *mFrame;
AVPacket *mPacket;
AVCodecParserContext *mParser;
};
#endif