From 71f39ba1b67bd99a59e2dc5878da6356357e4f98 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 2 Jul 2018 21:28:31 -0700 Subject: [PATCH 01/10] GBA BIOS: Use exp2f instead of powf --- src/gba/bios.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gba/bios.c b/src/gba/bios.c index dcbe8dac9..ead5332c2 100644 --- a/src/gba/bios.c +++ b/src/gba/bios.c @@ -251,7 +251,7 @@ static void _MidiKey2Freq(struct GBA* gba) { uint32_t key = cpu->memory.load32(cpu, cpu->gprs[0] + 4, 0); gba->memory.activeRegion = oldRegion; - cpu->gprs[0] = key / powf(2, (180.f - cpu->gprs[1] - cpu->gprs[2] / 256.f) / 12.f); + cpu->gprs[0] = key / exp2f((180.f - cpu->gprs[1] - cpu->gprs[2] / 256.f) / 12.f); } static void _Div(struct GBA* gba, int32_t num, int32_t denom) { From d620faba0a106abd916e1a909492d3a28853b70b Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 2 Jul 2018 21:30:45 -0700 Subject: [PATCH 02/10] GBA: Fix setting mask in ROM size coercion --- src/gba/gba.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/gba/gba.c b/src/gba/gba.c index 13dceff92..73a8378a3 100644 --- a/src/gba/gba.c +++ b/src/gba/gba.c @@ -398,6 +398,7 @@ bool GBALoadROM(struct GBA* gba, struct VFile* vf) { gba->memory.rom = newRom; #endif gba->memory.romSize = SIZE_CART0; + gba->memory.romMask = SIZE_CART0 - 1; gba->isPristine = false; } if (gba->cpu && gba->memory.activeRegion >= REGION_CART0) { From 4767ae42d292514186b85694beac061037822394 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Wed, 4 Jul 2018 12:28:55 -0700 Subject: [PATCH 03/10] GB Video: Darken colors in GBA mode --- CHANGES | 1 + src/gb/renderers/software.c | 21 ++++++++++++++++++++- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index c29b5a6a5..89a7ab176 100644 --- a/CHANGES +++ b/CHANGES @@ -66,6 +66,7 @@ Misc: - GB Audio: Improved audio quality - GB, GBA Audio: Increase max audio volume - GB: Fix VRAM/palette locking (fixes mgba.io/i/1109) + - GB Video: Darken colors in GBA mode 0.6.3: (2017-04-14) Bugfixes: diff --git a/src/gb/renderers/software.c b/src/gb/renderers/software.c index 8ca44026b..dd78eb94d 100644 --- a/src/gb/renderers/software.c +++ b/src/gb/renderers/software.c @@ -437,10 +437,29 @@ static void GBVideoSoftwareRendererWritePalette(struct GBVideoRenderer* renderer color = softwareRenderer->palette[0]; } } - softwareRenderer->palette[index] = color; if (renderer->cache) { mCacheSetWritePalette(renderer->cache, index, color); } + if (softwareRenderer->model == GB_MODEL_AGB) { + unsigned r = M_R5(value); + unsigned g = M_G5(value); + unsigned b = M_B5(value); + r = r * r; + g = g * g; + b = b * b; +#ifdef COLOR_16_BIT + r /= 31; + g /= 31; + b /= 31; + color = mColorFrom555(r | (g << 5) | (b << 10)); +#else + r >>= 2; + g >>= 2; + b >>= 2; + color = r | (g << 8) | (b << 16); +#endif + } + softwareRenderer->palette[index] = color; if (softwareRenderer->model == GB_MODEL_SGB && !index && GBRegisterLCDCIsEnable(softwareRenderer->lcdc)) { renderer->writePalette(renderer, 0x04, value); From 2e330b92a73e67aa6b238bb4a07840e235557082 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Wed, 4 Jul 2018 12:46:49 -0700 Subject: [PATCH 04/10] Feature: Fix memory leak in mVideoLogContext --- src/feature/video-logger.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/feature/video-logger.c b/src/feature/video-logger.c index 6d9710872..6f49e482d 100644 --- a/src/feature/video-logger.c +++ b/src/feature/video-logger.c @@ -682,6 +682,18 @@ void mVideoLogContextDestroy(struct mCore* core, struct mVideoLogContext* contex if (context->initialState) { mappedMemoryFree(context->initialState, context->initialStateSize); } + + size_t i; + for (i = 0; i < context->nChannels; ++i) { + CircleBufferDeinit(&context->channels[i].buffer); +#ifdef USE_ZLIB + if (context->channels[i].inflating) { + inflateEnd(&context->channels[i].inflateStream); + context->channels[i].inflating = false; + } +#endif + } + free(context); } From 3be77c162247f5380bd1ec226ab4bf7ab800efcb Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Wed, 4 Jul 2018 12:47:09 -0700 Subject: [PATCH 05/10] Qt: Fix memory leak in LogController --- src/platform/qt/LogController.cpp | 4 ++++ src/platform/qt/LogController.h | 1 + 2 files changed, 5 insertions(+) diff --git a/src/platform/qt/LogController.cpp b/src/platform/qt/LogController.cpp index 32cf7a917..85de8720b 100644 --- a/src/platform/qt/LogController.cpp +++ b/src/platform/qt/LogController.cpp @@ -25,6 +25,10 @@ LogController::LogController(int levels, QObject* parent) } } +LogController::~LogController() { + mLogFilterDeinit(&m_filter); +} + LogController::Stream LogController::operator()(int category, int level) { return Stream(this, category, level); } diff --git a/src/platform/qt/LogController.h b/src/platform/qt/LogController.h index e9f536e97..b3c9470cf 100644 --- a/src/platform/qt/LogController.h +++ b/src/platform/qt/LogController.h @@ -35,6 +35,7 @@ private: public: LogController(int levels, QObject* parent = nullptr); + ~LogController(); int levels() const { return m_filter.defaultLevels; } mLogFilter* filter() { return &m_filter; } From 08ec1e89c41606c5ae99005aaf665d1d4e254f56 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Wed, 4 Jul 2018 12:47:37 -0700 Subject: [PATCH 06/10] Qt: Work around invalid new/delete semantics --- src/platform/qt/DisplayGL.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/platform/qt/DisplayGL.cpp b/src/platform/qt/DisplayGL.cpp index 781753009..1c335b49b 100644 --- a/src/platform/qt/DisplayGL.cpp +++ b/src/platform/qt/DisplayGL.cpp @@ -180,7 +180,7 @@ PainterGL::PainterGL(int majorVersion, QGLWidget* parent) #if !defined(_WIN32) || defined(USE_EPOXY) if (majorVersion >= 2) { - gl2Backend = new mGLES2Context; + gl2Backend = static_cast(malloc(sizeof(mGLES2Context))); mGLES2ContextCreate(gl2Backend); m_backend = &gl2Backend->d; m_supportsShaders = true; @@ -189,7 +189,7 @@ PainterGL::PainterGL(int majorVersion, QGLWidget* parent) #ifdef BUILD_GL if (!m_backend) { - glBackend = new mGLContext; + glBackend = static_cast(malloc(sizeof(mGLContext))); mGLContextCreate(glBackend); m_backend = &glBackend->d; m_supportsShaders = false; @@ -239,7 +239,7 @@ PainterGL::~PainterGL() { #endif m_backend->deinit(m_backend); m_gl->doneCurrent(); - delete m_backend; + free(m_backend); m_backend = nullptr; } From 8fdfa130bd717f141a35dc77d6e724ba0c00c65e Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Thu, 5 Jul 2018 20:26:03 -0700 Subject: [PATCH 07/10] Qt: Fix DisplayGL crash --- src/platform/qt/DisplayGL.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/platform/qt/DisplayGL.cpp b/src/platform/qt/DisplayGL.cpp index 1c335b49b..7f89f39d4 100644 --- a/src/platform/qt/DisplayGL.cpp +++ b/src/platform/qt/DisplayGL.cpp @@ -29,8 +29,11 @@ using namespace QGBA; DisplayGL::DisplayGL(const QGLFormat& format, QWidget* parent) : Display(parent) - , m_gl(new EmptyGLWidget(format, this)) + , m_gl(nullptr) { + // This can spontaneously re-enter into this->resizeEvent before creation is done, so we + // need to make sure it's initialized to nullptr before we assign the new object to it + m_gl = new EmptyGLWidget(format, this); m_painter = new PainterGL(format.majorVersion() < 2 ? 1 : m_gl->format().majorVersion(), m_gl); m_gl->setMouseTracking(true); m_gl->setAttribute(Qt::WA_TransparentForMouseEvents); // This doesn't seem to work? @@ -162,7 +165,9 @@ void DisplayGL::resizeEvent(QResizeEvent* event) { } void DisplayGL::resizePainter() { - m_gl->resize(size()); + if (m_gl) { + m_gl->resize(size()); + } if (m_drawThread) { QMetaObject::invokeMethod(m_painter, "resize", Qt::BlockingQueuedConnection, Q_ARG(QSize, size())); } From cc0d582b38119d195b3e23a348562c812f76fd9a Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Thu, 5 Jul 2018 20:30:47 -0700 Subject: [PATCH 08/10] Qt: More memory leak fixes --- src/platform/qt/library/LibraryController.cpp | 8 ++++---- src/platform/qt/library/LibraryController.h | 4 ++-- src/platform/qt/library/LibraryTree.cpp | 6 ++++++ 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/platform/qt/library/LibraryController.cpp b/src/platform/qt/library/LibraryController.cpp index 9bfad5d95..3f2a5fc96 100644 --- a/src/platform/qt/library/LibraryController.cpp +++ b/src/platform/qt/library/LibraryController.cpp @@ -45,10 +45,10 @@ LibraryController::LibraryController(QWidget* parent, const QString& path, Confi mLibraryAttachGameDB(m_library.get(), GBAApp::app()->gameDB()); - m_libraryTree = new LibraryTree(this); + m_libraryTree = std::make_unique(this); addWidget(m_libraryTree->widget()); - m_libraryGrid = new LibraryGrid(this); + m_libraryGrid = std::make_unique(this); addWidget(m_libraryGrid->widget()); setViewStyle(LibraryStyle::STYLE_LIST); @@ -67,9 +67,9 @@ void LibraryController::setViewStyle(LibraryStyle newStyle) { AbstractGameList* newCurrentList = nullptr; if (newStyle == LibraryStyle::STYLE_LIST || newStyle == LibraryStyle::STYLE_TREE) { - newCurrentList = m_libraryTree; + newCurrentList = m_libraryTree.get(); } else { - newCurrentList = m_libraryGrid; + newCurrentList = m_libraryGrid.get(); } newCurrentList->selectEntry(selectedEntry()); newCurrentList->setViewStyle(newStyle); diff --git a/src/platform/qt/library/LibraryController.h b/src/platform/qt/library/LibraryController.h index 789550919..029b96aaa 100644 --- a/src/platform/qt/library/LibraryController.h +++ b/src/platform/qt/library/LibraryController.h @@ -107,8 +107,8 @@ private: LibraryStyle m_currentStyle; AbstractGameList* m_currentList = nullptr; - LibraryGrid* m_libraryGrid = nullptr; - LibraryTree* m_libraryTree = nullptr; + std::unique_ptr m_libraryGrid; + std::unique_ptr m_libraryTree; }; } diff --git a/src/platform/qt/library/LibraryTree.cpp b/src/platform/qt/library/LibraryTree.cpp index 6dc763e4a..cfaa69187 100644 --- a/src/platform/qt/library/LibraryTree.cpp +++ b/src/platform/qt/library/LibraryTree.cpp @@ -62,6 +62,12 @@ LibraryTree::LibraryTree(LibraryController* parent) }); } +LibraryTree::~LibraryTree() { + for (QTreeWidgetItem* i : m_items.values()) { + delete i; + } +} + void LibraryTree::resizeAllCols() { for (int i = 0; i < m_widget->columnCount(); i++) { m_widget->resizeColumnToContents(i); From 5874235c2d7a2cfb11320a8fee575cc1be7506f3 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Thu, 5 Jul 2018 20:50:56 -0700 Subject: [PATCH 09/10] Travis: Use docker containers for applicable builds --- .travis-deps.sh | 15 --------------- .travis.yml | 30 +++++++++++++++++++++++------- 2 files changed, 23 insertions(+), 22 deletions(-) diff --git a/.travis-deps.sh b/.travis-deps.sh index 64e45cc98..02e336f75 100755 --- a/.travis-deps.sh +++ b/.travis-deps.sh @@ -2,19 +2,4 @@ if [ $TRAVIS_OS_NAME = "osx" ]; then brew update brew install qt5 ffmpeg imagemagick sdl2 libedit libelf libpng libzip -else - sudo apt-get clean - sudo add-apt-repository -y ppa:beineri/opt-qt542-trusty - sudo add-apt-repository -y ppa:george-edison55/cmake-3.x - sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test - sudo apt-get update - sudo apt-get install -y -q cmake libedit-dev libelf-dev libmagickwand-dev \ - libpng-dev libsdl2-dev libzip-dev qt54base qt54multimedia \ - libavcodec-dev libavutil-dev libavformat-dev libavresample-dev \ - libswscale-dev - if [ "$CC" == "gcc" ]; then - sudo apt-get install -y -q gcc-5 g++-5 - export CC=gcc-5 - export CXX=g++-5 - fi fi diff --git a/.travis.yml b/.travis.yml index 17bcaca87..e3b77c343 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,14 +1,30 @@ +if: type = pull_request OR NOT branch =~ /^(master$|optimization)/ OR fork language: c sudo: required +services: +- docker +os: linux +env: +- DOCKER_TAG=ubuntu:xenial +- DOCKER_TAG=ubuntu:artful +- DOCKER_TAG=ubuntu:bionic +- DOCKER_TAG=3ds +- DOCKER_TAG=wii +- DOCKER_TAG=vita +- DOCKER_TAG=windows:w32 +- DOCKER_TAG=windows:w64 + matrix: include: - - os: linux - dist: trusty - compiler: gcc - - os: osx - compiler: clang + - os: osx + compiler: clang + env: DOCKER_TAG= before_install: - - source ./.travis-deps.sh +- '[ -z "$DOCKER_TAG" ] || docker pull mgba/$DOCKER_TAG' +- '[ "$TRAVIS_OS_NAME" != "osx" ] || . ./.travis-deps.sh' +- 'mkdir build && chmod 777 build' -script: mkdir build && cd build && cmake -DCMAKE_PREFIX_PATH='/usr/local/opt/qt5;/opt/qt54' .. && make -j2 +script: +- '[ -z "$DOCKER_TAG" ] || docker run -e BUILD_DIR=build -e MAKEFLAGS=-j2 -v $PWD:/home/mgba/src mgba/$DOCKER_TAG' +- '[ "$TRAVIS_OS_NAME" != "osx" ] || (cd build && cmake -DCMAKE_PREFIX_PATH="/usr/local/opt/qt5" .. && make -j2)' From 31e0642e6498e1b06f44468980322a842099d43e Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 8 Jul 2018 22:43:01 -0700 Subject: [PATCH 10/10] FFmpeg: Support libswresample (fixes #1120) --- CHANGES | 1 + CMakeLists.txt | 29 ++++++++++++++++++++++------- src/feature/ffmpeg/ffmpeg-encoder.c | 28 +++++++++++++++++++++++++++- src/feature/ffmpeg/ffmpeg-encoder.h | 4 ++++ 4 files changed, 54 insertions(+), 8 deletions(-) diff --git a/CHANGES b/CHANGES index 89a7ab176..4f2e65fe1 100644 --- a/CHANGES +++ b/CHANGES @@ -67,6 +67,7 @@ Misc: - GB, GBA Audio: Increase max audio volume - GB: Fix VRAM/palette locking (fixes mgba.io/i/1109) - GB Video: Darken colors in GBA mode + - FFmpeg: Support libswresample (fixes mgba.io/i/1120, mgba.io/b/123) 0.6.3: (2017-04-14) Bugfixes: diff --git a/CMakeLists.txt b/CMakeLists.txt index d3f0c353e..7c2efeb98 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -438,7 +438,7 @@ set(WANT_LIBZIP ${USE_LIBZIP}) set(WANT_SQLITE3 ${USE_SQLITE3}) set(USE_CMOCKA ${BUILD_SUITE}) -find_feature(USE_FFMPEG "libavcodec;libavformat;libavresample;libavutil;libswscale") +find_feature(USE_FFMPEG "libavcodec;libavformat;libavutil;libswscale") find_feature(USE_ZLIB "ZLIB") find_feature(USE_MINIZIP "minizip") find_feature(USE_PNG "PNG") @@ -450,6 +450,13 @@ find_feature(USE_SQLITE3 "sqlite3") find_feature(USE_ELF "libelf") find_feature(ENABLE_PYTHON "PythonLibs") +if(USE_FFMPEG) + set(USE_LIBAVRESAMPLE ON) + set(USE_LIBSWRESAMPLE ON) + find_feature(USE_LIBAVRESAMPLE "libavresample") + find_feature(USE_LIBSWRESAMPLE "libswresample") +endif() + # Features set(DEBUGGER_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/debugger/debugger.c @@ -485,22 +492,30 @@ source_group("Debugger" FILES ${DEBUGGER_SRC}) if(USE_FFMPEG) list(APPEND FEATURES FFMPEG) - pkg_search_module(LIBSWRESAMPLE QUIET libswresample) - if(NOT LIBSWRESAMPLE_FOUND) + if(USE_LIBSWRESAMPLE) + list(APPEND FEATURES LIBSWRESAMPLE) + else() + list(APPEND FEATURES LIBAVRESAMPLE) list(APPEND FEATURES LIBAV) endif() - include_directories(AFTER ${LIBAVCODEC_INCLUDE_DIRS} ${LIBAVFORMAT_INCLUDE_DIRS} ${LIBAVRESAMPLE_INCLUDE_DIRS} ${LIBAVUTIL_INCLUDE_DIRS} ${LIBSWSCALE_INCLUDE_DIRS}) - link_directories(${LIBAVCODEC_LIBRARY_DIRS} ${LIBAVFORMAT_LIBRARY_DIRS} ${LIBAVRESAMPLE_LIBRARY_DIRS} ${LIBAVUTIL_LIBRARY_DIRS} ${LIBSWSCALE_LIBRARY_DIRS}) + include_directories(AFTER ${LIBAVCODEC_INCLUDE_DIRS} ${LIBAVFORMAT_INCLUDE_DIRS} ${LIBAVRESAMPLE_INCLUDE_DIRS} ${LIBAVUTIL_INCLUDE_DIRS} ${LIBSWRESAMPLE_INCLUDE_DIRS} ${LIBSWSCALE_INCLUDE_DIRS}) + link_directories(${LIBAVCODEC_LIBRARY_DIRS} ${LIBAVFORMAT_LIBRARY_DIRS} ${LIBAVRESAMPLE_LIBRARY_DIRS} ${LIBAVUTIL_LIBRARY_DIRS} ${LIBSWRESAMPLE_LIBRARY_DIRS} ${LIBSWSCALE_LIBRARY_DIRS}) list(APPEND FEATURE_SRC "${CMAKE_CURRENT_SOURCE_DIR}/src/feature/ffmpeg/ffmpeg-encoder.c") string(REGEX MATCH "^[0-9]+" LIBAVCODEC_VERSION_MAJOR ${libavcodec_VERSION}) string(REGEX MATCH "^[0-9]+" LIBAVFORMAT_VERSION_MAJOR ${libavformat_VERSION}) string(REGEX MATCH "^[0-9]+" LIBAVRESAMPLE_VERSION_MAJOR ${libavresample_VERSION}) string(REGEX MATCH "^[0-9]+" LIBAVUTIL_VERSION_MAJOR ${libavutil_VERSION}) + string(REGEX MATCH "^[0-9]+" LIBSWRESAMPLE_VERSION_MAJOR ${libswresample_VERSION}) string(REGEX MATCH "^[0-9]+" LIBSWSCALE_VERSION_MAJOR ${libswscale_VERSION}) - list(APPEND DEPENDENCY_LIB ${LIBAVCODEC_LIBRARIES} ${LIBAVFORMAT_LIBRARIES} ${LIBAVRESAMPLE_LIBRARIES} ${LIBAVUTIL_LIBRARIES} ${LIBSWSCALE_LIBRARIES}) + math(EXPR LIBSWRESAMPLE_VERSION_DEBIAN "${LIBSWRESAMPLE_VERSION_MAJOR} - 1") + list(APPEND DEPENDENCY_LIB ${LIBAVCODEC_LIBRARIES} ${LIBAVFORMAT_LIBRARIES} ${LIBAVRESAMPLE_LIBRARIES} ${LIBAVUTIL_LIBRARIES} ${LIBSWSCALE_LIBRARIES} ${LIBSWRESAMPLE_LIBRARIES}) set(CPACK_DEBIAN_PACKAGE_DEPENDS "${CPACK_DEBIAN_PACKAGE_DEPENDS},libavcodec${LIBAVCODEC_VERSION_MAJOR}|libavcodec-extra-${LIBAVCODEC_VERSION_MAJOR}|libavcodec-ffmpeg${LIBAVCODEC_VERSION_MAJOR}|libavcodec-ffmpeg-extra${LIBAVCODEC_VERSION_MAJOR}") set(CPACK_DEBIAN_PACKAGE_DEPENDS "${CPACK_DEBIAN_PACKAGE_DEPENDS},libavformat${LIBAVFORMAT_VERSION_MAJOR}|libavformat-ffmpeg${LIBAVFORMAT_VERSION_MAJOR}") - set(CPACK_DEBIAN_PACKAGE_DEPENDS "${CPACK_DEBIAN_PACKAGE_DEPENDS},libavresample${LIBAVRESAMPLE_VERSION_MAJOR}|libavresample-ffmpeg${LIBAVRESAMPLE_VERSION_MAJOR}") + if(USE_LIBSWRESAMPLE) + set(CPACK_DEBIAN_PACKAGE_DEPENDS "${CPACK_DEBIAN_PACKAGE_DEPENDS},libswresample${LIBSWRESAMPLE_VERSION_DEBIAN}|libswresample-ffmpeg${LIBSWRESAMPLE_VERSION_DEBIAN}") + else() + set(CPACK_DEBIAN_PACKAGE_DEPENDS "${CPACK_DEBIAN_PACKAGE_DEPENDS},libavresample${LIBAVRESAMPLE_VERSION_MAJOR}|libavresample-ffmpeg${LIBAVRESAMPLE_VERSION_MAJOR}") + endif() set(CPACK_DEBIAN_PACKAGE_DEPENDS "${CPACK_DEBIAN_PACKAGE_DEPENDS},libavutil${LIBAVUTIL_VERSION_MAJOR}|libavutil-ffmpeg${LIBAVUTIL_VERSION_MAJOR}") set(CPACK_DEBIAN_PACKAGE_DEPENDS "${CPACK_DEBIAN_PACKAGE_DEPENDS},libswscale${LIBSWSCALE_VERSION_MAJOR}|libswscale-ffmpeg${LIBSWSCALE_VERSION_MAJOR}") set(CPACK_DEBIAN_PACKAGE_RECOMMENDS "libavcodec-extra|libavcodec-ffmpeg-extra${LIBAVCODEC_VERSION_MAJOR}") diff --git a/src/feature/ffmpeg/ffmpeg-encoder.c b/src/feature/ffmpeg/ffmpeg-encoder.c index 2da3754f8..7fbc9a51c 100644 --- a/src/feature/ffmpeg/ffmpeg-encoder.c +++ b/src/feature/ffmpeg/ffmpeg-encoder.c @@ -19,7 +19,11 @@ #include #include +#ifdef USE_LIBAVRESAMPLE #include +#else +#include +#endif #include static void _ffmpegPostVideoFrame(struct mAVStream*, const color_t* pixels, size_t stride); @@ -248,6 +252,7 @@ bool FFmpegEncoderOpen(struct FFmpegEncoder* encoder, const char* outfile) { encoder->audioFrame->nb_samples = encoder->audio->frame_size; encoder->audioFrame->format = encoder->audio->sample_fmt; encoder->audioFrame->pts = 0; +#ifdef USE_LIBAVRESAMPLE encoder->resampleContext = avresample_alloc_context(); av_opt_set_int(encoder->resampleContext, "in_channel_layout", AV_CH_LAYOUT_STEREO, 0); av_opt_set_int(encoder->resampleContext, "out_channel_layout", AV_CH_LAYOUT_STEREO, 0); @@ -256,6 +261,11 @@ bool FFmpegEncoderOpen(struct FFmpegEncoder* encoder, const char* outfile) { av_opt_set_int(encoder->resampleContext, "in_sample_fmt", AV_SAMPLE_FMT_S16, 0); av_opt_set_int(encoder->resampleContext, "out_sample_fmt", encoder->sampleFormat, 0); avresample_open(encoder->resampleContext); +#else + encoder->resampleContext = swr_alloc_set_opts(NULL, AV_CH_LAYOUT_STEREO, encoder->sampleFormat, encoder->sampleRate, + AV_CH_LAYOUT_STEREO, AV_SAMPLE_FMT_S16, PREFERRED_SAMPLE_RATE, 0, NULL); + swr_init(encoder->resampleContext); +#endif encoder->audioBufferSize = (encoder->audioFrame->nb_samples * PREFERRED_SAMPLE_RATE / encoder->sampleRate) * 4; encoder->audioBuffer = av_malloc(encoder->audioBufferSize); encoder->postaudioBufferSize = av_samples_get_buffer_size(0, encoder->audio->channels, encoder->audio->frame_size, encoder->audio->sample_fmt, 0); @@ -362,7 +372,11 @@ void FFmpegEncoderClose(struct FFmpegEncoder* encoder) { avcodec_close(encoder->audio); if (encoder->resampleContext) { +#ifdef USE_LIBAVRESAMPLE avresample_close(encoder->resampleContext); +#else + swr_free(&encoder->resampleContext); +#endif } if (encoder->absf) { @@ -414,10 +428,11 @@ void _ffmpegPostAudioFrame(struct mAVStream* stream, int16_t left, int16_t right } int channelSize = 2 * av_get_bytes_per_sample(encoder->audio->sample_fmt); + encoder->currentAudioSample = 0; +#ifdef USE_LIBAVRESAMPLE avresample_convert(encoder->resampleContext, 0, 0, 0, (uint8_t**) &encoder->audioBuffer, 0, encoder->audioBufferSize / 4); - encoder->currentAudioSample = 0; if (avresample_available(encoder->resampleContext) < encoder->audioFrame->nb_samples) { return; } @@ -425,6 +440,17 @@ void _ffmpegPostAudioFrame(struct mAVStream* stream, int16_t left, int16_t right av_frame_make_writable(encoder->audioFrame); #endif int samples = avresample_read(encoder->resampleContext, encoder->audioFrame->data, encoder->postaudioBufferSize / channelSize); +#else +#if LIBAVCODEC_VERSION_MAJOR >= 55 + av_frame_make_writable(encoder->audioFrame); +#endif + if (swr_get_out_samples(encoder->resampleContext, encoder->audioBufferSize / 4) < encoder->audioFrame->nb_samples) { + swr_convert(encoder->resampleContext, NULL, 0, (const uint8_t**) &encoder->audioBuffer, encoder->audioBufferSize / 4); + return; + } + int samples = swr_convert(encoder->resampleContext, encoder->audioFrame->data, encoder->postaudioBufferSize / channelSize, + (const uint8_t**) &encoder->audioBuffer, encoder->audioBufferSize / 4); +#endif encoder->audioFrame->pts = av_rescale_q(encoder->currentAudioFrame, encoder->audio->time_base, encoder->audioStream->time_base); encoder->currentAudioFrame += samples; diff --git a/src/feature/ffmpeg/ffmpeg-encoder.h b/src/feature/ffmpeg/ffmpeg-encoder.h index feeeddc77..f8c5add36 100644 --- a/src/feature/ffmpeg/ffmpeg-encoder.h +++ b/src/feature/ffmpeg/ffmpeg-encoder.h @@ -57,7 +57,11 @@ struct FFmpegEncoder { size_t currentAudioSample; int64_t currentAudioFrame; int64_t nextAudioPts; // TODO (0.6): Remove +#ifdef USE_LIBAVRESAMPLE struct AVAudioResampleContext* resampleContext; +#else + struct SwrContext* resampleContext; +#endif #ifdef FFMPEG_USE_NEW_BSF struct AVBSFContext* absf; // Needed for AAC in MP4 #else