Improve:MediaBase module.
This commit is contained in:
parent
e7ce303ec3
commit
ff4eb8bf07
|
@ -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)
|
||||
|
|
|
@ -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
|
Loading…
Reference in New Issue
Block a user