all repos — mgba @ 0ad14bef7e50cb77a770f1c77e07ba96dc8ed927

mGBA Game Boy Advance Emulator

FFmpeg: Full support for libavcodec 56+
Jeffrey Pfau jeffrey@endrift.com
Mon, 05 Sep 2016 11:55:06 -0700
commit

0ad14bef7e50cb77a770f1c77e07ba96dc8ed927

parent

b0157aa871991d34cb6471e5184740ea63067fc9

3 files changed, 63 insertions(+), 5 deletions(-)

jump to
M CHANGESCHANGES

@@ -90,6 +90,7 @@ - Qt: Rearchitect game closing codepath

- Wii: Add pixelated resample filter - GBA: Better debug logging if event processing breaks - 3DS: 3D banner + - FFmpeg: Full support for libavcodec 56+ 0.4.1: (2016-07-11) Bugfixes:
M src/feature/ffmpeg/ffmpeg-encoder.csrc/feature/ffmpeg/ffmpeg-encoder.c

@@ -214,8 +214,13 @@ encoder->context->oformat = oformat;

#endif if (acodec) { +#if LIBAVFORMAT_VERSION_MAJOR >= 56 + encoder->audioStream = avformat_new_stream(encoder->context, NULL); + encoder->audio = avcodec_alloc_context3(acodec); +#else encoder->audioStream = avformat_new_stream(encoder->context, acodec); encoder->audio = encoder->audioStream->codec; +#endif encoder->audio->bit_rate = encoder->audioBitrate; encoder->audio->channels = 2; encoder->audio->channel_layout = AV_CH_LAYOUT_STEREO;

@@ -258,12 +263,26 @@ (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 +#if LIBAVCODEC_VERSION_MAJOR >= 56 + av_bsf_alloc(av_bsf_get_by_name("aac_adtstoasc"), &encoder->absf); + avcodec_parameters_from_context(encoder->absf->par_in, encoder->audio); + av_bsf_init(encoder->absf); +#else encoder->absf = av_bitstream_filter_init("aac_adtstoasc"); +#endif } +#if LIBAVCODEC_VERSION_MAJOR >= 56 + avcodec_parameters_from_context(encoder->audioStream->codecpar, encoder->audio); +#endif } +#if LIBAVFORMAT_VERSION_MAJOR >= 56 + encoder->videoStream = avformat_new_stream(encoder->context, NULL); + encoder->video = avcodec_alloc_context3(vcodec); +#else encoder->videoStream = avformat_new_stream(encoder->context, vcodec); encoder->video = encoder->videoStream->codec; +#endif encoder->video->bit_rate = encoder->videoBitrate; encoder->video->width = encoder->width; encoder->video->height = encoder->height;

@@ -297,11 +316,12 @@ encoder->videoFrame->height = encoder->video->height;

encoder->videoFrame->pts = 0; _ffmpegSetVideoDimensions(&encoder->d, encoder->iwidth, encoder->iheight); av_image_alloc(encoder->videoFrame->data, encoder->videoFrame->linesize, encoder->video->width, encoder->video->height, encoder->video->pix_fmt, 32); +#if LIBAVCODEC_VERSION_MAJOR >= 56 + avcodec_parameters_from_context(encoder->videoStream->codecpar, encoder->video); +#endif avio_open(&encoder->context->pb, outfile, AVIO_FLAG_WRITE); - avformat_write_header(encoder->context, 0); - - return true; + return avformat_write_header(encoder->context, 0) >= 0; } void FFmpegEncoderClose(struct FFmpegEncoder* encoder) {

@@ -328,8 +348,12 @@ avresample_close(encoder->resampleContext);

} if (encoder->absf) { +#if LIBAVCODEC_VERSION_MAJOR >= 56 + av_bsf_free(&encoder->absf); +#else av_bitstream_filter_close(encoder->absf); encoder->absf = 0; +#endif } }

@@ -389,25 +413,43 @@ av_init_packet(&packet);

packet.data = 0; packet.size = 0; int gotData; +#if LIBAVCODEC_VERSION_MAJOR >= 56 + avcodec_send_frame(encoder->audio, encoder->audioFrame); + gotData = avcodec_receive_packet(encoder->audio, &packet) == 0; +#else avcodec_encode_audio2(encoder->audio, &packet, encoder->audioFrame, &gotData); +#endif if (gotData) { if (encoder->absf) { AVPacket tempPacket = packet; + +#if LIBAVCODEC_VERSION_MAJOR >= 56 + int success = av_bsf_send_packet(encoder->absf, &packet) && av_bsf_receive_packet(encoder->absf, &packet); +#else int success = av_bitstream_filter_filter(encoder->absf, encoder->audio, 0, &tempPacket.data, &tempPacket.size, packet.data, packet.size, 0); +#endif if (success > 0) { #if LIBAVUTIL_VERSION_MAJOR >= 53 tempPacket.buf = av_buffer_create(tempPacket.data, tempPacket.size, av_buffer_default_free, 0, 0); #endif +#if LIBAVCODEC_VERSION_MAJOR >= 57 + av_packet_unref(&packet); +#else av_free_packet(&packet); +#endif } packet = tempPacket; } packet.stream_index = encoder->audioStream->index; av_interleaved_write_frame(encoder->context, &packet); } - av_free_packet(&packet); +#if LIBAVCODEC_VERSION_MAJOR >= 57 + av_packet_unref(&packet); +#else + av_free_packet(&packet); +#endif } void _ffmpegPostVideoFrame(struct mAVStream* stream, const color_t* pixels, size_t stride) {

@@ -431,15 +473,26 @@

sws_scale(encoder->scaleContext, (const uint8_t* const*) &pixels, (const int*) &stride, 0, encoder->iheight, encoder->videoFrame->data, encoder->videoFrame->linesize); int gotData; +#if LIBAVCODEC_VERSION_MAJOR >= 56 + avcodec_send_frame(encoder->video, encoder->videoFrame); + gotData = avcodec_receive_packet(encoder->video, &packet) == 0; +#else avcodec_encode_video2(encoder->video, &packet, encoder->videoFrame, &gotData); +#endif if (gotData) { - if (encoder->videoStream->codec->coded_frame->key_frame) { +#if LIBAVCODEC_VERSION_MAJOR < 56 + if (encoder->video->coded_frame->key_frame) { packet.flags |= AV_PKT_FLAG_KEY; } +#endif packet.stream_index = encoder->videoStream->index; av_interleaved_write_frame(encoder->context, &packet); } +#if LIBAVCODEC_VERSION_MAJOR >= 57 + av_packet_unref(&packet); +#else av_free_packet(&packet); +#endif } static void _ffmpegSetVideoDimensions(struct mAVStream* stream, unsigned width, unsigned height) {
M src/feature/ffmpeg/ffmpeg-encoder.hsrc/feature/ffmpeg/ffmpeg-encoder.h

@@ -34,7 +34,11 @@ size_t currentAudioSample;

int64_t currentAudioFrame; int64_t nextAudioPts; struct AVAudioResampleContext* resampleContext; +#if LIBAVCODEC_VERSION_MAJOR >= 56 + struct AVBSFContext* absf; // Needed for AAC in MP4 +#else struct AVBitStreamFilterContext* absf; // Needed for AAC in MP4 +#endif struct AVStream* audioStream; struct AVCodecContext* video;