Video: Support AAC in MP4

This commit is contained in:
Jeffrey Pfau 2014-10-28 23:30:15 -07:00
parent eab30ebf05
commit 3ad2047855
2 changed files with 35 additions and 7 deletions

View File

@ -2,6 +2,8 @@
#include "gba-video.h"
#include <libavcodec/avcodec.h>
#include <libavutil/imgutils.h>
#include <libavutil/opt.h>
@ -27,6 +29,8 @@ void FFmpegEncoderInit(struct FFmpegEncoder* encoder) {
FFmpegEncoderSetAudio(encoder, "flac", 0);
FFmpegEncoderSetVideo(encoder, "png", 0);
FFmpegEncoderSetContainer(encoder, "matroska");
encoder->resampleContext = 0;
encoder->absf = 0;
encoder->context = 0;
}
@ -200,6 +204,14 @@ bool FFmpegEncoderOpen(struct FFmpegEncoder* encoder, const char* outfile) {
encoder->postaudioBuffer = av_malloc(encoder->postaudioBufferSize);
avcodec_fill_audio_frame(encoder->audioFrame, encoder->audio->channels, encoder->audio->sample_fmt, (const uint8_t*) encoder->postaudioBuffer, encoder->postaudioBufferSize, 0);
if (encoder->audio->codec->id == AV_CODEC_ID_AAC &&
(strcasecmp(encoder->containerFormat, "mp4") ||
strcasecmp(encoder->containerFormat, "m4v") ||
strcasecmp(encoder->containerFormat, "mov"))) {
// MP4 container doesn't support the raw ADTS AAC format that the encoder spits out
encoder->absf = av_bitstream_filter_init("aac_adtstoasc");
}
encoder->videoStream = avformat_new_stream(encoder->context, vcodec);
encoder->video = encoder->videoStream->codec;
encoder->video->bit_rate = encoder->videoBitrate;
@ -252,6 +264,11 @@ void FFmpegEncoderClose(struct FFmpegEncoder* encoder) {
avresample_close(encoder->resampleContext);
}
if (encoder->absf) {
av_bitstream_filter_close(encoder->absf);
encoder->absf = 0;
}
sws_freeContext(encoder->scaleContext);
avformat_free_context(encoder->context);
@ -296,6 +313,17 @@ void _ffmpegPostAudioFrame(struct GBAAVStream* stream, int32_t left, int32_t rig
int gotData;
avcodec_encode_audio2(encoder->audio, &packet, encoder->audioFrame, &gotData);
if (gotData) {
if (encoder->absf) {
AVPacket tempPacket = packet;
int success = av_bitstream_filter_filter(encoder->absf, encoder->audio, 0,
&tempPacket.data, &tempPacket.size,
packet.data, packet.size, 0);
if (success > 0) {
tempPacket.buf = av_buffer_create(tempPacket.data, tempPacket.size, av_buffer_default_free, 0, 0);
av_free_packet(&packet);
}
packet = tempPacket;
}
packet.stream_index = encoder->audioStream->index;
av_interleaved_write_frame(encoder->context, &packet);
}

View File

@ -3,12 +3,11 @@
#include "gba-thread.h"
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
struct FFmpegEncoder {
struct GBAAVStream d;
AVFormatContext* context;
struct AVFormatContext* context;
unsigned audioBitrate;
const char* audioCodec;
@ -18,7 +17,7 @@ struct FFmpegEncoder {
const char* containerFormat;
AVCodecContext* audio;
struct AVCodecContext* audio;
enum AVSampleFormat sampleFormat;
int sampleRate;
uint16_t* audioBuffer;
@ -30,14 +29,15 @@ struct FFmpegEncoder {
int64_t currentAudioFrame;
int64_t nextAudioPts;
struct AVAudioResampleContext* resampleContext;
AVStream* audioStream;
struct AVBitStreamFilterContext* absf; // Needed for AAC in MP4
struct AVStream* audioStream;
AVCodecContext* video;
struct AVCodecContext* video;
enum AVPixelFormat pixFormat;
AVFrame* videoFrame;
struct AVFrame* videoFrame;
int64_t currentVideoFrame;
struct SwsContext* scaleContext;
AVStream* videoStream;
struct AVStream* videoStream;
};
void FFmpegEncoderInit(struct FFmpegEncoder*);