mirror of https://github.com/mgba-emu/mgba.git
FFmpeg: Support audio-only recording
This commit is contained in:
parent
fd7989e748
commit
3e86eeda70
1
CHANGES
1
CHANGES
|
@ -57,6 +57,7 @@ Misc:
|
||||||
- Debugger: Print breakpoint/watchpoint number when inserting
|
- Debugger: Print breakpoint/watchpoint number when inserting
|
||||||
- Qt: Open a message box for Qt frontend errors
|
- Qt: Open a message box for Qt frontend errors
|
||||||
- GBA Video: Clean up dead code in sprite rendering loop
|
- GBA Video: Clean up dead code in sprite rendering loop
|
||||||
|
- FFmpeg: Support audio-only recording
|
||||||
|
|
||||||
0.7.1: (2019-02-24)
|
0.7.1: (2019-02-24)
|
||||||
Bugfixes:
|
Bugfixes:
|
||||||
|
|
|
@ -55,10 +55,12 @@ void FFmpegEncoderInit(struct FFmpegEncoder* encoder) {
|
||||||
encoder->absf = NULL;
|
encoder->absf = NULL;
|
||||||
encoder->context = NULL;
|
encoder->context = NULL;
|
||||||
encoder->scaleContext = NULL;
|
encoder->scaleContext = NULL;
|
||||||
|
encoder->audio = NULL;
|
||||||
encoder->audioStream = NULL;
|
encoder->audioStream = NULL;
|
||||||
encoder->audioFrame = NULL;
|
encoder->audioFrame = NULL;
|
||||||
encoder->audioBuffer = NULL;
|
encoder->audioBuffer = NULL;
|
||||||
encoder->postaudioBuffer = NULL;
|
encoder->postaudioBuffer = NULL;
|
||||||
|
encoder->video = NULL;
|
||||||
encoder->videoStream = NULL;
|
encoder->videoStream = NULL;
|
||||||
encoder->videoFrame = NULL;
|
encoder->videoFrame = NULL;
|
||||||
}
|
}
|
||||||
|
@ -146,6 +148,12 @@ bool FFmpegEncoderSetVideo(struct FFmpegEncoder* encoder, const char* vcodec, un
|
||||||
{ AV_PIX_FMT_YUV444P, 5 },
|
{ AV_PIX_FMT_YUV444P, 5 },
|
||||||
{ AV_PIX_FMT_YUV420P, 6 }
|
{ AV_PIX_FMT_YUV420P, 6 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (!vcodec) {
|
||||||
|
encoder->videoCodec = 0;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
AVCodec* codec = avcodec_find_encoder_by_name(vcodec);
|
AVCodec* codec = avcodec_find_encoder_by_name(vcodec);
|
||||||
if (!codec) {
|
if (!codec) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -189,13 +197,13 @@ bool FFmpegEncoderVerifyContainer(struct FFmpegEncoder* encoder) {
|
||||||
AVOutputFormat* oformat = av_guess_format(encoder->containerFormat, 0, 0);
|
AVOutputFormat* oformat = av_guess_format(encoder->containerFormat, 0, 0);
|
||||||
AVCodec* acodec = avcodec_find_encoder_by_name(encoder->audioCodec);
|
AVCodec* acodec = avcodec_find_encoder_by_name(encoder->audioCodec);
|
||||||
AVCodec* vcodec = avcodec_find_encoder_by_name(encoder->videoCodec);
|
AVCodec* vcodec = avcodec_find_encoder_by_name(encoder->videoCodec);
|
||||||
if ((encoder->audioCodec && !acodec) || !vcodec || !oformat) {
|
if ((encoder->audioCodec && !acodec) || (encoder->videoCodec && !vcodec) || !oformat) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (encoder->audioCodec && !avformat_query_codec(oformat, acodec->id, FF_COMPLIANCE_EXPERIMENTAL)) {
|
if (encoder->audioCodec && !avformat_query_codec(oformat, acodec->id, FF_COMPLIANCE_EXPERIMENTAL)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!avformat_query_codec(oformat, vcodec->id, FF_COMPLIANCE_EXPERIMENTAL)) {
|
if (encoder->videoCodec && !avformat_query_codec(oformat, vcodec->id, FF_COMPLIANCE_EXPERIMENTAL)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -562,7 +570,7 @@ void _ffmpegPostAudioFrame(struct mAVStream* stream, int16_t left, int16_t right
|
||||||
|
|
||||||
void _ffmpegPostVideoFrame(struct mAVStream* stream, const color_t* pixels, size_t stride) {
|
void _ffmpegPostVideoFrame(struct mAVStream* stream, const color_t* pixels, size_t stride) {
|
||||||
struct FFmpegEncoder* encoder = (struct FFmpegEncoder*) stream;
|
struct FFmpegEncoder* encoder = (struct FFmpegEncoder*) stream;
|
||||||
if (!encoder->context) {
|
if (!encoder->context || !encoder->videoCodec) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
stride *= BYTES_PER_PIXEL;
|
stride *= BYTES_PER_PIXEL;
|
||||||
|
@ -606,6 +614,9 @@ void _ffmpegPostVideoFrame(struct mAVStream* stream, const color_t* pixels, size
|
||||||
|
|
||||||
static void _ffmpegSetVideoDimensions(struct mAVStream* stream, unsigned width, unsigned height) {
|
static void _ffmpegSetVideoDimensions(struct mAVStream* stream, unsigned width, unsigned height) {
|
||||||
struct FFmpegEncoder* encoder = (struct FFmpegEncoder*) stream;
|
struct FFmpegEncoder* encoder = (struct FFmpegEncoder*) stream;
|
||||||
|
if (!encoder->context || !encoder->videoCodec) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
encoder->iwidth = width;
|
encoder->iwidth = width;
|
||||||
encoder->iheight = height;
|
encoder->iheight = height;
|
||||||
if (encoder->scaleContext) {
|
if (encoder->scaleContext) {
|
||||||
|
|
|
@ -275,7 +275,11 @@ void VideoView::setAudioCodec(const QString& codec, bool manual) {
|
||||||
void VideoView::setVideoCodec(const QString& codec, bool manual) {
|
void VideoView::setVideoCodec(const QString& codec, bool manual) {
|
||||||
free(m_videoCodecCstr);
|
free(m_videoCodecCstr);
|
||||||
m_videoCodec = sanitizeCodec(codec, s_vcodecMap);
|
m_videoCodec = sanitizeCodec(codec, s_vcodecMap);
|
||||||
|
if (m_videoCodec == "none") {
|
||||||
|
m_videoCodecCstr = nullptr;
|
||||||
|
} else {
|
||||||
m_videoCodecCstr = strdup(m_videoCodec.toUtf8().constData());
|
m_videoCodecCstr = strdup(m_videoCodec.toUtf8().constData());
|
||||||
|
}
|
||||||
if (!FFmpegEncoderSetVideo(&m_encoder, m_videoCodecCstr, m_vbr)) {
|
if (!FFmpegEncoderSetVideo(&m_encoder, m_videoCodecCstr, m_vbr)) {
|
||||||
free(m_videoCodecCstr);
|
free(m_videoCodecCstr);
|
||||||
m_videoCodecCstr = nullptr;
|
m_videoCodecCstr = nullptr;
|
||||||
|
|
Loading…
Reference in New Issue