mirror of
https://github.com/moonlight-stream/moonlight-embedded.git
synced 2026-04-04 15:06:03 +00:00
117 lines
3.4 KiB
C
Executable File
117 lines
3.4 KiB
C
Executable File
/*
|
|
* This file is part of Moonlight Embedded.
|
|
*
|
|
* Copyright (C) 2015-2017 Iwan Timmer
|
|
* Copyright (C) 2016 OtherCrashOverride, Daniel Mehrwald
|
|
*
|
|
* Moonlight is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* Moonlight is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with Moonlight; if not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include <Limelight.h>
|
|
|
|
#include <sys/utsname.h>
|
|
#include <stdio.h>
|
|
#include <stdbool.h>
|
|
#include <stdlib.h>
|
|
#include <sys/stat.h>
|
|
#include <fcntl.h>
|
|
#include <unistd.h>
|
|
#include <sys/ioctl.h>
|
|
#include <codec.h>
|
|
|
|
#define SYNC_OUTSIDE 0x02
|
|
#define UCODE_IP_ONLY_PARAM 0x08
|
|
|
|
static codec_para_t codecParam = { 0 };
|
|
|
|
int aml_setup(int videoFormat, int width, int height, int redrawRate, void* context, int drFlags) {
|
|
codecParam.stream_type = STREAM_TYPE_ES_VIDEO;
|
|
codecParam.has_video = 1;
|
|
codecParam.noblock = 0;
|
|
codecParam.am_sysinfo.param = 0;
|
|
|
|
switch (videoFormat) {
|
|
case VIDEO_FORMAT_H264:
|
|
if (width > 1920 || height > 1080) {
|
|
codecParam.video_type = VFORMAT_H264_4K2K;
|
|
codecParam.am_sysinfo.format = VIDEO_DEC_FORMAT_H264_4K2K;
|
|
} else {
|
|
codecParam.video_type = VFORMAT_H264;
|
|
codecParam.am_sysinfo.format = VIDEO_DEC_FORMAT_H264;
|
|
|
|
// Workaround for decoding special case of C1, 1080p, H264
|
|
int major, minor;
|
|
struct utsname name;
|
|
uname(&name);
|
|
int ret = sscanf(name.release, "%d.%d", &major, &minor);
|
|
if (!(major > 3 || (major == 3 && minor >= 14)) && width == 1920 && height == 1080)
|
|
codecParam.am_sysinfo.param = (void*) UCODE_IP_ONLY_PARAM;
|
|
}
|
|
break;
|
|
case VIDEO_FORMAT_H265:
|
|
codecParam.video_type = VFORMAT_HEVC;
|
|
codecParam.am_sysinfo.format = VIDEO_DEC_FORMAT_HEVC;
|
|
break;
|
|
default:
|
|
printf("Video format not supported\n");
|
|
return -1;
|
|
}
|
|
|
|
codecParam.am_sysinfo.width = width;
|
|
codecParam.am_sysinfo.height = height;
|
|
codecParam.am_sysinfo.rate = 96000 / redrawRate;
|
|
codecParam.am_sysinfo.param = (void*) ((size_t) codecParam.am_sysinfo.param | SYNC_OUTSIDE);
|
|
|
|
int ret;
|
|
if ((ret = codec_init(&codecParam)) != 0) {
|
|
fprintf(stderr, "codec_init error: %x\n", ret);
|
|
return -2;
|
|
}
|
|
|
|
if ((ret = codec_set_freerun_mode(&codecParam, 1)) != 0) {
|
|
fprintf(stderr, "Can't set Freerun mode: %x\n", ret);
|
|
return -2;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void aml_cleanup() {
|
|
codec_close(&codecParam);
|
|
}
|
|
|
|
int aml_submit_decode_unit(PDECODE_UNIT decodeUnit) {
|
|
int result = DR_OK;
|
|
PLENTRY entry = decodeUnit->bufferList;
|
|
while (entry != NULL) {
|
|
int api = codec_write(&codecParam, entry->data, entry->length);
|
|
if (api != entry->length) {
|
|
fprintf(stderr, "codec_write error: %x\n", api);
|
|
codec_reset(&codecParam);
|
|
result = DR_NEED_IDR;
|
|
break;
|
|
}
|
|
|
|
entry = entry->next;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
DECODER_RENDERER_CALLBACKS decoder_callbacks_aml = {
|
|
.setup = aml_setup,
|
|
.cleanup = aml_cleanup,
|
|
.submitDecodeUnit = aml_submit_decode_unit,
|
|
.capabilities = CAPABILITY_DIRECT_SUBMIT | CAPABILITY_SLICES_PER_FRAME(8),
|
|
};
|