Backup test code.
This commit is contained in:
parent
beecc6659f
commit
90f0ebd438
6
external/ffmpeg/README.md
vendored
6
external/ffmpeg/README.md
vendored
|
@ -21,6 +21,12 @@ $ ffplay video.h264
|
||||||
$ fmpeg -f mulaw -ar 8000 -i audio.g711a audio.wav
|
$ fmpeg -f mulaw -ar 8000 -i audio.g711a audio.wav
|
||||||
```
|
```
|
||||||
|
|
||||||
|
* 播放pcm文件
|
||||||
|
|
||||||
|
```code
|
||||||
|
$ ffplay -f s16le -ar 8000 -ac 1 test.pcm
|
||||||
|
```
|
||||||
|
|
||||||
* 将h264和wav文件合成mp4文件
|
* 将h264和wav文件合成mp4文件
|
||||||
|
|
||||||
**注意:未发现可以将h264和g711a文件合成mp4文件**
|
**注意:未发现可以将h264和g711a文件合成mp4文件**
|
||||||
|
|
|
@ -167,6 +167,24 @@ void inline FfmpegDecoder::AVParseData(const void *data, const size_t &size,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void save_code_stream_file(const void *data, const size_t &size)
|
||||||
|
{
|
||||||
|
char OutPath[16];
|
||||||
|
const void *pData = data;
|
||||||
|
FILE *file = NULL;
|
||||||
|
|
||||||
|
sprintf(OutPath, "./test.pcm");
|
||||||
|
file = fopen(OutPath, "a+");
|
||||||
|
|
||||||
|
if (file) { // TODO: Don't open very time.
|
||||||
|
fwrite(pData, 1, size, file);
|
||||||
|
fflush(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (file)
|
||||||
|
fclose(file);
|
||||||
|
}
|
||||||
void inline FfmpegDecoder::AVDecodeData(AVPacket *pkt, std::function<void(AVFrame *frame)> callback)
|
void inline FfmpegDecoder::AVDecodeData(AVPacket *pkt, std::function<void(AVFrame *frame)> callback)
|
||||||
{
|
{
|
||||||
int ret = avcodec_send_packet(mCodecCtx, pkt);
|
int ret = avcodec_send_packet(mCodecCtx, pkt);
|
||||||
|
@ -185,6 +203,13 @@ void inline FfmpegDecoder::AVDecodeData(AVPacket *pkt, std::function<void(AVFram
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (callback) {
|
if (callback) {
|
||||||
|
// int i, ch, data_size;
|
||||||
|
// data_size = av_get_bytes_per_sample(mCodecCtx->sample_fmt);
|
||||||
|
// for (i = 0; i < mFrame->nb_samples; i++)
|
||||||
|
// for (ch = 0; ch < mCodecCtx->ch_layout.nb_channels; ch++)
|
||||||
|
// // fwrite(frame->data[ch] + data_size * i, 1, data_size, outfile);
|
||||||
|
// save_code_stream_file(mFrame->data[ch] + data_size * i, data_size);
|
||||||
|
save_code_stream_file(mFrame->data[0], mFrame->linesize[0]);
|
||||||
callback(mFrame);
|
callback(mFrame);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -39,8 +39,9 @@ extern "C" {
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
constexpr long SOURCE_AUDIO_SAMPEL_RATE = 8000;
|
||||||
#define STREAM_DURATION 10.0
|
#define STREAM_DURATION 10.0
|
||||||
#define STREAM_FRAME_RATE 25 /* 25 images/s */
|
#define STREAM_FRAME_RATE 1200000 /* 25 images/s */
|
||||||
#define STREAM_PIX_FMT AV_PIX_FMT_YUV420P /* default pix_fmt */
|
#define STREAM_PIX_FMT AV_PIX_FMT_YUV420P /* default pix_fmt */
|
||||||
FfmpegEncoder::FfmpegEncoder(const enum AVCodecID &codecId)
|
FfmpegEncoder::FfmpegEncoder(const enum AVCodecID &codecId)
|
||||||
: mCodecId(codecId), mCodecCtx(nullptr), mCodec(nullptr), mFrame(nullptr), mTmpFrame(nullptr), mTmpPkt(nullptr),
|
: mCodecId(codecId), mCodecCtx(nullptr), mCodec(nullptr), mFrame(nullptr), mTmpFrame(nullptr), mTmpPkt(nullptr),
|
||||||
|
@ -71,8 +72,8 @@ bool FfmpegEncoder::Init(int &outputFlags)
|
||||||
switch (mCodec->type) {
|
switch (mCodec->type) {
|
||||||
case AVMEDIA_TYPE_AUDIO:
|
case AVMEDIA_TYPE_AUDIO:
|
||||||
mCodecCtx->sample_fmt = mCodec->sample_fmts ? mCodec->sample_fmts[0] : AV_SAMPLE_FMT_FLTP;
|
mCodecCtx->sample_fmt = mCodec->sample_fmts ? mCodec->sample_fmts[0] : AV_SAMPLE_FMT_FLTP;
|
||||||
// mCodecCtx->bit_rate = 64000;
|
mCodecCtx->bit_rate = 64000;
|
||||||
mCodecCtx->bit_rate = 24000;
|
// mCodecCtx->bit_rate = 24000;
|
||||||
mCodecCtx->sample_rate = 44100;
|
mCodecCtx->sample_rate = 44100;
|
||||||
if (mCodec->supported_samplerates) {
|
if (mCodec->supported_samplerates) {
|
||||||
mCodecCtx->sample_rate = mCodec->supported_samplerates[0];
|
mCodecCtx->sample_rate = mCodec->supported_samplerates[0];
|
||||||
|
@ -81,7 +82,8 @@ bool FfmpegEncoder::Init(int &outputFlags)
|
||||||
mCodecCtx->sample_rate = 44100;
|
mCodecCtx->sample_rate = 44100;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mCodecCtx->sample_rate = 8000;
|
mCodecCtx->sample_rate = SOURCE_AUDIO_SAMPEL_RATE;
|
||||||
|
// mCodecCtx->time_base = (AVRational){1, mCodecCtx->sample_rate};
|
||||||
mCodecCtx->ch_layout.nb_channels = 1;
|
mCodecCtx->ch_layout.nb_channels = 1;
|
||||||
av_channel_layout_default(&mCodecCtx->ch_layout, 1);
|
av_channel_layout_default(&mCodecCtx->ch_layout, 1);
|
||||||
// av_channel_layout_copy(&mCodecCtx->ch_layout, &src);
|
// av_channel_layout_copy(&mCodecCtx->ch_layout, &src);
|
||||||
|
@ -168,6 +170,23 @@ bool FfmpegEncoder::OpenEncoder(AVDictionary *optArg, AVStream *stream)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
static void save_code_stream_file(const void *data, const size_t &size)
|
||||||
|
{
|
||||||
|
char OutPath[16];
|
||||||
|
const void *pData = data;
|
||||||
|
FILE *file = NULL;
|
||||||
|
LogInfo("save_code_stream_file: %d\n", size);
|
||||||
|
sprintf(OutPath, "./test.aac");
|
||||||
|
file = fopen(OutPath, "a+");
|
||||||
|
|
||||||
|
if (file) { // TODO: Don't open very time.
|
||||||
|
fwrite(pData, 1, size, file);
|
||||||
|
fflush(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (file)
|
||||||
|
fclose(file);
|
||||||
|
}
|
||||||
int FfmpegEncoder::EncodeData(AVFrame *frame, AVStream *stream, std::function<void(AVPacket *pkt)> callback)
|
int FfmpegEncoder::EncodeData(AVFrame *frame, AVStream *stream, std::function<void(AVPacket *pkt)> callback)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
@ -204,6 +223,7 @@ int FfmpegEncoder::EncodeData(AVFrame *frame, AVStream *stream, std::function<vo
|
||||||
mTmpPkt->stream_index = stream->index;
|
mTmpPkt->stream_index = stream->index;
|
||||||
|
|
||||||
if (callback) {
|
if (callback) {
|
||||||
|
// save_code_stream_file(mTmpPkt->data, mTmpPkt->size);
|
||||||
callback(mTmpPkt);
|
callback(mTmpPkt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -263,7 +283,7 @@ bool FfmpegEncoder::OpenAudio(AVDictionary *optArg, AVStream *stream)
|
||||||
else
|
else
|
||||||
nb_samples = mCodecCtx->frame_size;
|
nb_samples = mCodecCtx->frame_size;
|
||||||
mFrame = alloc_audio_frame(mCodecCtx->sample_fmt, &mCodecCtx->ch_layout, mCodecCtx->sample_rate, nb_samples);
|
mFrame = alloc_audio_frame(mCodecCtx->sample_fmt, &mCodecCtx->ch_layout, mCodecCtx->sample_rate, nb_samples);
|
||||||
mTmpFrame = alloc_audio_frame(AV_SAMPLE_FMT_S16, &mCodecCtx->ch_layout, mCodecCtx->sample_rate, nb_samples);
|
// mTmpFrame = alloc_audio_frame(AV_SAMPLE_FMT_S16, &mCodecCtx->ch_layout, mCodecCtx->sample_rate, nb_samples);
|
||||||
/* copy the stream parameters to the muxer */
|
/* copy the stream parameters to the muxer */
|
||||||
ret = avcodec_parameters_from_context(stream->codecpar, mCodecCtx);
|
ret = avcodec_parameters_from_context(stream->codecpar, mCodecCtx);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
|
@ -276,9 +296,13 @@ bool FfmpegEncoder::OpenAudio(AVDictionary *optArg, AVStream *stream)
|
||||||
LogError("Could not allocate resampler context\n");
|
LogError("Could not allocate resampler context\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
const AVChannelLayout src = (AVChannelLayout)AV_CHANNEL_LAYOUT_MONO;
|
||||||
|
AVChannelLayout ch_layout;
|
||||||
|
av_channel_layout_copy(&ch_layout, &src);
|
||||||
/* set options */
|
/* set options */
|
||||||
|
// av_opt_set_chlayout(mSwrCtx, "in_chlayout", &ch_layout, 0);
|
||||||
av_opt_set_chlayout(mSwrCtx, "in_chlayout", &mCodecCtx->ch_layout, 0);
|
av_opt_set_chlayout(mSwrCtx, "in_chlayout", &mCodecCtx->ch_layout, 0);
|
||||||
av_opt_set_int(mSwrCtx, "in_sample_rate", mCodecCtx->sample_rate, 0);
|
av_opt_set_int(mSwrCtx, "in_sample_rate", SOURCE_AUDIO_SAMPEL_RATE, 0);
|
||||||
av_opt_set_sample_fmt(mSwrCtx, "in_sample_fmt", AV_SAMPLE_FMT_S16, 0);
|
av_opt_set_sample_fmt(mSwrCtx, "in_sample_fmt", AV_SAMPLE_FMT_S16, 0);
|
||||||
av_opt_set_chlayout(mSwrCtx, "out_chlayout", &mCodecCtx->ch_layout, 0);
|
av_opt_set_chlayout(mSwrCtx, "out_chlayout", &mCodecCtx->ch_layout, 0);
|
||||||
av_opt_set_int(mSwrCtx, "out_sample_rate", mCodecCtx->sample_rate, 0);
|
av_opt_set_int(mSwrCtx, "out_sample_rate", mCodecCtx->sample_rate, 0);
|
||||||
|
@ -304,9 +328,9 @@ AVFrame *FfmpegEncoder::ConvertAudioFrame(AVFrame *decodeFrame, struct SwrContex
|
||||||
/* compute destination number of samples */
|
/* compute destination number of samples */
|
||||||
dst_nb_samples = av_rescale_rnd(swr_get_delay(swr_ctx, mCodecCtx->sample_rate) + decodeFrame->nb_samples,
|
dst_nb_samples = av_rescale_rnd(swr_get_delay(swr_ctx, mCodecCtx->sample_rate) + decodeFrame->nb_samples,
|
||||||
mCodecCtx->sample_rate,
|
mCodecCtx->sample_rate,
|
||||||
mCodecCtx->sample_rate,
|
SOURCE_AUDIO_SAMPEL_RATE,
|
||||||
AV_ROUND_UP);
|
AV_ROUND_UP);
|
||||||
av_assert0(dst_nb_samples == decodeFrame->nb_samples);
|
// av_assert0(dst_nb_samples == decodeFrame->nb_samples);
|
||||||
|
|
||||||
/* when we pass a frame to the encoder, it may keep a reference to it
|
/* when we pass a frame to the encoder, it may keep a reference to it
|
||||||
* internally;
|
* internally;
|
||||||
|
@ -357,7 +381,7 @@ AVFrame *FfmpegEncoder::alloc_audio_frame(enum AVSampleFormat sample_fmt, const
|
||||||
{
|
{
|
||||||
AVFrame *frame = av_frame_alloc();
|
AVFrame *frame = av_frame_alloc();
|
||||||
if (!frame) {
|
if (!frame) {
|
||||||
LogInfo("Error allocating an audio frame\n");
|
LogError("Error allocating an audio frame\n");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -368,7 +392,7 @@ AVFrame *FfmpegEncoder::alloc_audio_frame(enum AVSampleFormat sample_fmt, const
|
||||||
|
|
||||||
if (nb_samples) {
|
if (nb_samples) {
|
||||||
if (av_frame_get_buffer(frame, 0) < 0) {
|
if (av_frame_get_buffer(frame, 0) < 0) {
|
||||||
LogInfo("Error allocating an audio buffer\n");
|
LogError("Error allocating an audio buffer\n");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,6 +69,8 @@ void FfmpegMuxStreamV2::GetStreamData(const void *data, const size_t &size, cons
|
||||||
bool fileMuxing = false;
|
bool fileMuxing = false;
|
||||||
fileMuxing = mVideoStream->CheckStreamHeader(data, size);
|
fileMuxing = mVideoStream->CheckStreamHeader(data, size);
|
||||||
if (fileMuxing) {
|
if (fileMuxing) {
|
||||||
|
AVDictionary *opt = nullptr;
|
||||||
|
av_dict_set_int(&opt, "use_editlist", 0, 0);
|
||||||
/* Write the stream header, if any. */
|
/* Write the stream header, if any. */
|
||||||
ret = avformat_write_header(mOutputFormat, nullptr);
|
ret = avformat_write_header(mOutputFormat, nullptr);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
|
@ -78,6 +80,7 @@ void FfmpegMuxStreamV2::GetStreamData(const void *data, const size_t &size, cons
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
mFilesMuxing = true;
|
mFilesMuxing = true;
|
||||||
|
av_dict_free(&opt);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
LogWarning("Stream header not found, skip this frame.\n");
|
LogWarning("Stream header not found, skip this frame.\n");
|
||||||
|
@ -125,7 +128,10 @@ StatusCode inline FfmpegMuxStreamV2::OpenMuxOutputFile(const std::string &fileNa
|
||||||
av_make_error_string(error_str, AV_ERROR_MAX_STRING_SIZE, ret));
|
av_make_error_string(error_str, AV_ERROR_MAX_STRING_SIZE, ret));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return CreateStatusCode(STATUS_CODE_OK);
|
if (mVideoStream) {
|
||||||
|
return CreateStatusCode(STATUS_CODE_OK);
|
||||||
|
}
|
||||||
|
av_dict_set_int(&opt, "use_editlist", 0, 0);
|
||||||
/* Write the stream header, if any. */
|
/* Write the stream header, if any. */
|
||||||
ret = avformat_write_header(mOutputFormat, &opt);
|
ret = avformat_write_header(mOutputFormat, &opt);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
|
@ -134,6 +140,7 @@ StatusCode inline FfmpegMuxStreamV2::OpenMuxOutputFile(const std::string &fileNa
|
||||||
av_make_error_string(error_str, AV_ERROR_MAX_STRING_SIZE, ret));
|
av_make_error_string(error_str, AV_ERROR_MAX_STRING_SIZE, ret));
|
||||||
return CreateStatusCode(STATUS_CODE_NOT_OK);
|
return CreateStatusCode(STATUS_CODE_NOT_OK);
|
||||||
}
|
}
|
||||||
|
av_dict_free(&opt);
|
||||||
mFilesMuxing = true;
|
mFilesMuxing = true;
|
||||||
return CreateStatusCode(STATUS_CODE_OK);
|
return CreateStatusCode(STATUS_CODE_OK);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user