Merge branch 'master' (early part) into medusa

This commit is contained in:
Vicki Pfau 2019-06-28 16:17:21 -07:00
commit a6dcfcc338
16 changed files with 139 additions and 43 deletions

View File

@ -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

View File

@ -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)'

View File

@ -86,6 +86,8 @@ 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
- FFmpeg: Support libswresample (fixes mgba.io/i/1120, mgba.io/b/123)
0.6.3: (2017-04-14)
Bugfixes:

View File

@ -443,7 +443,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")
@ -455,6 +455,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
@ -503,22 +510,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}")

View File

@ -19,7 +19,11 @@
#include <libavutil/mathematics.h>
#include <libavutil/opt.h>
#ifdef USE_LIBAVRESAMPLE
#include <libavresample/avresample.h>
#else
#include <libswresample/swresample.h>
#endif
#include <libswscale/swscale.h>
static void _ffmpegPostVideoFrame(struct mAVStream*, const color_t* pixels, size_t stride);
@ -254,6 +258,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);
@ -262,6 +267,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);
@ -370,7 +380,11 @@ void FFmpegEncoderClose(struct FFmpegEncoder* encoder) {
encoder->audio = NULL;
if (encoder->resampleContext) {
#ifdef USE_LIBAVRESAMPLE
avresample_close(encoder->resampleContext);
#else
swr_free(&encoder->resampleContext);
#endif
}
if (encoder->absf) {
@ -423,10 +437,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;
}
@ -434,6 +449,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;

View File

@ -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

View File

@ -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);
}

View File

@ -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);

View File

@ -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) {

View File

@ -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) {

View File

@ -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?
@ -166,7 +169,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()));
}
@ -184,7 +189,7 @@ PainterGL::PainterGL(int majorVersion, QGLWidget* parent)
#if !defined(_WIN32) || defined(USE_EPOXY)
if (majorVersion >= 2) {
gl2Backend = new mGLES2Context;
gl2Backend = static_cast<mGLES2Context*>(malloc(sizeof(mGLES2Context)));
mGLES2ContextCreate(gl2Backend);
m_backend = &gl2Backend->d;
m_supportsShaders = true;
@ -193,7 +198,7 @@ PainterGL::PainterGL(int majorVersion, QGLWidget* parent)
#ifdef BUILD_GL
if (!m_backend) {
glBackend = new mGLContext;
glBackend = static_cast<mGLContext*>(malloc(sizeof(mGLContext)));
mGLContextCreate(glBackend);
m_backend = &glBackend->d;
m_supportsShaders = false;
@ -243,7 +248,7 @@ PainterGL::~PainterGL() {
#endif
m_backend->deinit(m_backend);
m_gl->doneCurrent();
delete m_backend;
free(m_backend);
m_backend = nullptr;
}

View File

@ -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);
}

View File

@ -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; }

View File

@ -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<LibraryTree>(this);
addWidget(m_libraryTree->widget());
m_libraryGrid = new LibraryGrid(this);
m_libraryGrid = std::make_unique<LibraryGrid>(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);

View File

@ -107,8 +107,8 @@ private:
LibraryStyle m_currentStyle;
AbstractGameList* m_currentList = nullptr;
LibraryGrid* m_libraryGrid = nullptr;
LibraryTree* m_libraryTree = nullptr;
std::unique_ptr<LibraryGrid> m_libraryGrid;
std::unique_ptr<LibraryTree> m_libraryTree;
};
}

View File

@ -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);