Improve:MediaBase module.
This commit is contained in:
parent
e7ce303ec3
commit
ff4eb8bf07
|
@ -33,8 +33,9 @@ extern "C" {
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
#include <stdint.h>
|
||||||
FfmpegDecoder::FfmpegDecoder(const enum AVCodecID &codecId)
|
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)
|
bool FfmpegDecoder::Init(void)
|
||||||
|
@ -84,6 +85,16 @@ bool FfmpegDecoder::Init(void)
|
||||||
LogError("Could not allocate video frame\n");
|
LogError("Could not allocate video frame\n");
|
||||||
return false;
|
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) {
|
if (AVMEDIA_TYPE_AUDIO == mCodec->type) {
|
||||||
mFrame->nb_samples = mCodecCtx->frame_size;
|
mFrame->nb_samples = mCodecCtx->frame_size;
|
||||||
mFrame->format = mCodecCtx->sample_fmt;
|
mFrame->format = mCodecCtx->sample_fmt;
|
||||||
|
@ -105,19 +116,63 @@ bool FfmpegDecoder::UnInit(void)
|
||||||
avcodec_free_context(&mCodecCtx);
|
avcodec_free_context(&mCodecCtx);
|
||||||
mCodecCtx = nullptr;
|
mCodecCtx = nullptr;
|
||||||
}
|
}
|
||||||
|
av_packet_free(&mPacket);
|
||||||
|
mPacket = nullptr;
|
||||||
|
if (mParser) {
|
||||||
|
av_parser_close(mParser);
|
||||||
|
mParser = nullptr;
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
void FfmpegDecoder::DecodeData(const void *data, const size_t &size, std::function<void(AVFrame *frame)> callback)
|
void FfmpegDecoder::DecodeData(const void *data, const size_t &size, std::function<void(AVFrame *frame)> callback)
|
||||||
{
|
{
|
||||||
AVPacket *packet = nullptr;
|
if (nullptr == mParser) {
|
||||||
packet = av_packet_alloc();
|
mPacket->data = (uint8_t *)data;
|
||||||
packet->data = (unsigned char *)data;
|
mPacket->size = size;
|
||||||
packet->size = size;
|
// mPacket->stream_index = 0;
|
||||||
int ret = avcodec_send_packet(mCodecCtx, packet);
|
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) {
|
if (ret < 0) {
|
||||||
LogError("Error sending a packet for decoding\n");
|
LogError("Error sending a packet for decoding\n");
|
||||||
av_packet_unref(packet);
|
av_packet_unref(pkt);
|
||||||
av_packet_free(&packet);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
while (ret >= 0) {
|
while (ret >= 0) {
|
||||||
|
@ -134,8 +189,7 @@ void FfmpegDecoder::DecodeData(const void *data, const size_t &size, std::functi
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
av_packet_unref(packet);
|
av_packet_unref(pkt);
|
||||||
av_packet_free(&packet);
|
|
||||||
}
|
}
|
||||||
/* just pick the highest supported samplerate */
|
/* just pick the highest supported samplerate */
|
||||||
int FfmpegDecoder::select_sample_rate(const AVCodec *codec)
|
int FfmpegDecoder::select_sample_rate(const AVCodec *codec)
|
||||||
|
|
|
@ -42,6 +42,10 @@ public:
|
||||||
bool UnInit(void);
|
bool UnInit(void);
|
||||||
void DecodeData(const void *data, const size_t &size, std::function<void(AVFrame *frame)> callback);
|
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:
|
private:
|
||||||
static int select_sample_rate(const AVCodec *codec);
|
static int select_sample_rate(const AVCodec *codec);
|
||||||
static int select_channel_layout(const AVCodec *codec, AVChannelLayout *dst);
|
static int select_channel_layout(const AVCodec *codec, AVChannelLayout *dst);
|
||||||
|
@ -52,5 +56,7 @@ private:
|
||||||
AVCodec *mCodec;
|
AVCodec *mCodec;
|
||||||
AVCodecContext *mCodecCtx;
|
AVCodecContext *mCodecCtx;
|
||||||
AVFrame *mFrame;
|
AVFrame *mFrame;
|
||||||
|
AVPacket *mPacket;
|
||||||
|
AVCodecParserContext *mParser;
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
Loading…
Reference in New Issue
Block a user