Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(decode): Port HDR support, update deps to OBS 29.1.x #77

Merged
merged 1 commit into from
May 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake/Modules")

# Change obs-plugintemplate to your plugin's name in a machine-readable format (e.g.:
# obs-myawesomeplugin) and set
project(obs-ssp VERSION 0.9.5)
project(obs-ssp VERSION 1.0.0)
add_library(${CMAKE_PROJECT_NAME} MODULE)

# Replace `Your Name Here` with the name (yours or your organization's) you want to see as the
Expand Down Expand Up @@ -71,6 +71,7 @@ target_include_directories(
${CMAKE_PROJECT_NAME} PRIVATE ${CMAKE_SOURCE_DIR}/src ${CMAKE_SOURCE_DIR}/lib/ssp/include
${CMAKE_SOURCE_DIR}/ssp_connector)

target_compile_definitions(${CMAKE_PROJECT_NAME} PRIVATE ENABLE_HEVC)
target_link_libraries(${CMAKE_PROJECT_NAME} PRIVATE OBS::libobs FFmpeg::avcodec FFmpeg::avutil mdns)

# --- End of section ---
Expand Down
46 changes: 23 additions & 23 deletions buildspec.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,47 +7,47 @@
"hash": "b51773b97b551cb409603146a97b2827d2a66ec3"
},
"prebuilt": {
"version": "2023-01-22",
"version": "2023-05-07",
"baseUrl": "https://github.com/summershrimp/obs-deps/releases/download",
"label": "Pre-built obs-deps",
"hashes": {
"macos-x86_64": "d7597665261c45e81c2780d6127ae6578428b914b4c862deeebda489d2ee20f9",
"macos-arm64": "29cf7574bb9e6d04bc612b5d2a09a3e3c876eab2f1aa0f0c439ec553f6b8f074",
"macos-universal": "9b908297bc9fe3f764a8943d583bd44c589fd9ff38f32f94c5a60fd95710d1f7",
"windows-x64": "8aad11356ef0ea608c07d170bac4dfba1da4ae71e7291a8bcfd22aeb000ed5e6",
"windows-x86": "a53da059f697d07aa01c85263294b2a68bf092e44248a533986cff8909c0752c"
"macos-x86_64": "e6eb65cbf35ab839d029682b199c6ce11a359df18138b1f2ba372db6aabe9e17",
"macos-arm64": "4655c8c21301c185c18ffceceec0541ba6805b96660d575d9e4f3d962a07ccb1",
"macos-universal": "e041f6d4ce0e4632a13ec8d25a35953405d52d9a5b0875c60e130e2f3dc865ba",
"windows-x64": "81e21b6334f001b0489d062beb26fa656a2fea2cdd449e322e2884d042f4756f",
"windows-x86": "b9ff30b1e0c9a00c300b35503f1734bbded4f51dac86521fc876fd14025b6995"
}
},
"qt5": {
"version": "2023-01-22",
"version": "2023-05-07",
"baseUrl": "https://github.com/summershrimp/obs-deps/releases/download",
"label": "Pre-built Qt5",
"hashes": {
"macos-x86_64": "79a0baf7e0ea2ec1ec7000efc5082a095966c8e1a06806884b691b79be1b6949",
"macos-arm64": "23e0cb299b36414447fc903dceb3b893b0b1b1e5dedca3629ca03d50d25aa137",
"macos-universal": "b12ec3d7dffba2d3618e12546a6d9098173c5fb2cf0b50ded7cb936a7175e060",
"windows-x64": "b2077dadf49350968778c41bf6551d61721e1de1192656c32f3d514c1d874cab",
"windows-x86": "b981a9929ba209de82644b6b6e07f6773332ad0b0eb2763dd3a1cec17883a9e0"
"macos-x86_64": "86ff0d3a3ab7057bca7615ee57992d3c79f79a9ff80b27b91566520560a5f3b0",
"macos-arm64": "d39bc94c742b5d63f608319f934f1312f386da9a9b6db76bf10dce06aa3449a7",
"macos-universal": "6e2d0744f78c5ba55ae6b604509ce30f0c6c52357f7357f64fcece5c2744e58f",
"windows-x64": "ecb53abcdb66436cf7953fd41d2619461582c5d874ad744e522e96f06e505987",
"windows-x86": "3f2f7efd3fb5a6d704a88fdbc77a4bcb2495b229a071068be658d7a3971b62bd"
},
"pdb-hashes": {
"windows-x64": "27fba1f4b99f5156be092b6820b3a70f1d82c6842cae24cc1df1fa115cdec1e5",
"windows-x86": "2a48debe9e2d8d8c32772b46cc00fa21e1982772dc7295b52b1b55c2fb0afe1b"
"windows-x64": "1c66a9724e7548b0a0bc6365fe9b3f87924ad76754e4318a53d62513a5809c54",
"windows-x86": "f5803fa086d82bd2b948c9df3b6a9096a185e340117ab65d4b730fa4744740a2"
}
},
"qt6": {
"version": "2023-01-22",
"version": "2023-05-07",
"baseUrl": "https://github.com/summershrimp/obs-deps/releases/download",
"label": "Pre-built Qt6",
"hashes": {
"macos-x86_64": "f9393fda169ab637c7a9525b97ef29b72dd2c05e58d2fff530f02ccde9d31bd3",
"macos-arm64": "bf17060835f8fd654d67acc0a2a0460546d418890b579787c8a930b5f9f9d3c7",
"macos-universal": "3b652267b4d37075f14e60df07965d085d75969b2b74fb4b02610c6f8cf8e4b9",
"windows-x64": "2a1b74abe58c234002cd20879ebcbe792936577e5a3a8b979610c10302685b09",
"windows-x86": "d4a8325f64414c762a75f9cad65d4800f2149c2837b6a1516a3e74ef26fe3560"
"macos-x86_64": "4eb382e0b5ec5cb58e256af7c76610cf6088f52848bda174f50347c5f6d73c41",
"macos-arm64": "672d11d03430c6b3c7e1d4c5b6af33cc48abf8d9337e9eb31499c500fe12d1ec",
"macos-universal": "68b83c10a50dceaba040887e0ebbdb8eb16398035965a6cb0b6dea3785ad6732",
"windows-x64": "5a29da428e4c270a76730152f6d3428719b5ecfc0885907d7377b2436d0356ec",
"windows-x86": "da96c96d9595c5717a2d1e012e194b7dc248d14b3b075deae69ec88f78c63be7"
},
"pdb-hashes": {
"windows-x64": "9e621185ef54042a3b395dd5511bd99a5fc3d22374759910eb290e6f96fccd9a",
"windows-x86": "892bd078ae37ca31852e6232564afe84045811922b6c29dd4aaded0d4397a292"
"windows-x64": "030459201801935b8e9cfa5279b8a2299f4f178f83f2808385d2d2769270ae94",
"windows-x86": "88f6b7d7e6b5eea0d0c1530e6a352464780e411ffbf495c48ffdd1c8bcd2c887"
}
}
},
Expand Down Expand Up @@ -82,5 +82,5 @@
}
},
"name": "obs-ssp",
"version": "0.11.0"
"version": "0.12.0"
}
104 changes: 77 additions & 27 deletions src/ffmpeg-decode.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@
#include "ffmpeg-decode.h"
#include "obs-ffmpeg-compat.h"
#include <obs-avc.h>
#ifdef ENABLE_HEVC
#include <obs-hevc.h>
#endif

#if LIBAVCODEC_VERSION_INT > AV_VERSION_INT(58, 4, 100)
#define USE_NEW_HARDWARE_CODEC_METHOD
Expand Down Expand Up @@ -125,8 +128,10 @@ int ffmpeg_decode_init(struct ffmpeg_decode *decode, enum AVCodecID id,
return ret;
}

#if LIBAVCODEC_VERSION_MAJOR < 60
if (decode->codec->capabilities & CODEC_CAP_TRUNC)
decode->decoder->flags |= CODEC_FLAG_TRUNC;
#endif

return 0;
}
Expand Down Expand Up @@ -162,6 +167,8 @@ static inline enum video_format convert_pixel_format(int f)
return VIDEO_FORMAT_NV12;
case AV_PIX_FMT_YUYV422:
return VIDEO_FORMAT_YUY2;
case AV_PIX_FMT_YVYU422:
return VIDEO_FORMAT_YVYU;
case AV_PIX_FMT_UYVY422:
return VIDEO_FORMAT_UYVY;
case AV_PIX_FMT_YUV422P:
Expand All @@ -171,8 +178,12 @@ static inline enum video_format convert_pixel_format(int f)
return VIDEO_FORMAT_RGBA;
case AV_PIX_FMT_BGRA:
return VIDEO_FORMAT_BGRA;
case AV_PIX_FMT_YUV420P10LE:
return VIDEO_FORMAT_I010;
case AV_PIX_FMT_BGR0:
return VIDEO_FORMAT_BGRX;
case AV_PIX_FMT_P010LE:
return VIDEO_FORMAT_P010;
default:;
}

Expand Down Expand Up @@ -247,26 +258,28 @@ bool ffmpeg_decode_audio(struct ffmpeg_decode *decode, uint8_t *data,
size_t size, struct obs_source_audio *audio,
bool *got_output)
{
AVPacket packet = {0};
int got_frame = false;
int ret = 0;

*got_output = false;

copy_data(decode, data, size);

av_init_packet(&packet);
packet.data = decode->packet_buffer;
packet.size = (int)size;

if (!decode->frame) {
decode->frame = av_frame_alloc();
if (!decode->frame)
return false;
}

if (data && size)
ret = avcodec_send_packet(decode->decoder, &packet);
if (data && size) {
AVPacket *packet = av_packet_alloc();
packet->data = decode->packet_buffer;
packet->size = (int)size;

ret = avcodec_send_packet(decode->decoder, packet);

av_packet_free(&packet);
}
if (ret == 0)
ret = avcodec_receive_frame(decode->decoder, decode->frame);

Expand Down Expand Up @@ -298,7 +311,8 @@ bool ffmpeg_decode_audio(struct ffmpeg_decode *decode, uint8_t *data,
}

static enum video_colorspace
convert_color_space(enum AVColorSpace s, enum AVColorTransferCharacteristic trc)
convert_color_space(enum AVColorSpace s, enum AVColorTransferCharacteristic trc,
enum AVColorPrimaries color_primaries)
{
switch (s) {
case AVCOL_SPC_BT709:
Expand All @@ -309,17 +323,23 @@ convert_color_space(enum AVColorSpace s, enum AVColorTransferCharacteristic trc)
case AVCOL_SPC_SMPTE170M:
case AVCOL_SPC_SMPTE240M:
return VIDEO_CS_601;
case AVCOL_SPC_BT2020_NCL:
return (trc == AVCOL_TRC_ARIB_STD_B67) ? VIDEO_CS_2100_HLG
: VIDEO_CS_2100_PQ;
default:
return VIDEO_CS_DEFAULT;
return (color_primaries == AVCOL_PRI_BT2020)
? ((trc == AVCOL_TRC_ARIB_STD_B67)
? VIDEO_CS_2100_HLG
: VIDEO_CS_2100_PQ)
: VIDEO_CS_DEFAULT;
}
}

bool ffmpeg_decode_video(struct ffmpeg_decode *decode, uint8_t *data,
size_t size, long long *ts,
size_t size, long long *ts, enum video_colorspace cs,
enum video_range_type range,
struct obs_source_frame2 *frame, bool *got_output)
{
AVPacket packet = {0};
int got_frame = false;

AVFrame *avframe = NULL, *sw_frame = NULL;
Expand All @@ -331,15 +351,6 @@ bool ffmpeg_decode_video(struct ffmpeg_decode *decode, uint8_t *data,

copy_data(decode, data, size);

av_init_packet(&packet);
packet.data = decode->packet_buffer;
packet.size = (int)size;
packet.pts = *ts;

if (decode->codec->id == AV_CODEC_ID_H264 &&
obs_avc_keyframe(data, size))
packet.flags |= AV_PKT_FLAG_KEY;

if (!decode->frame) {
decode->frame = av_frame_alloc();
}
Expand All @@ -356,7 +367,24 @@ bool ffmpeg_decode_video(struct ffmpeg_decode *decode, uint8_t *data,
avframe = decode->hw_frame;
sw_frame = decode->frame;

ret = avcodec_send_packet(decode->decoder, &packet);
AVPacket *packet = av_packet_alloc();
packet->data = decode->packet_buffer;
packet->size = (int)size;
packet->pts = *ts;

switch (decode->codec->id) {
case AV_CODEC_ID_H264:
if (obs_avc_keyframe(data, size))
packet->flags |= AV_PKT_FLAG_KEY;
#ifdef ENABLE_HEVC
break;
case AV_CODEC_ID_HEVC:
if (obs_hevc_keyframe(data, size))
packet->flags |= AV_PKT_FLAG_KEY;
#endif
}

ret = avcodec_send_packet(decode->decoder, packet);
if (ret < 0) {
blog(LOG_INFO, "Error during decoding\n");
return false;
Expand Down Expand Up @@ -397,12 +425,15 @@ bool ffmpeg_decode_video(struct ffmpeg_decode *decode, uint8_t *data,
: VIDEO_RANGE_PARTIAL;
}

const enum video_colorspace cs = convert_color_space(
tmp_frame->colorspace, tmp_frame->color_trc);
if (cs == VIDEO_CS_DEFAULT) {
cs = convert_color_space(decode->frame->colorspace,
decode->frame->color_trc,
decode->frame->color_primaries);
}

const bool success = video_format_get_parameters(
cs, range, frame->color_matrix, frame->color_range_min,
frame->color_range_max);
const bool success = video_format_get_parameters_for_format(
cs, range, frame->format, frame->color_matrix,
frame->color_range_min, frame->color_range_max);
if (!success) {
blog(LOG_ERROR,
"Failed to get video format "
Expand All @@ -419,9 +450,28 @@ bool ffmpeg_decode_video(struct ffmpeg_decode *decode, uint8_t *data,
frame->height = tmp_frame->height;
frame->flip = false;

switch (decode->frame->color_trc) {
case AVCOL_TRC_BT709:
case AVCOL_TRC_GAMMA22:
case AVCOL_TRC_GAMMA28:
case AVCOL_TRC_SMPTE170M:
case AVCOL_TRC_SMPTE240M:
case AVCOL_TRC_IEC61966_2_1:
frame->trc = VIDEO_TRC_SRGB;
break;
case AVCOL_TRC_SMPTE2084:
frame->trc = VIDEO_TRC_PQ;
break;
case AVCOL_TRC_ARIB_STD_B67:
frame->trc = VIDEO_TRC_HLG;
break;
default:
frame->trc = VIDEO_TRC_DEFAULT;
}

if (frame->format == VIDEO_FORMAT_NONE)
return false;

*got_output = true;
return true;
}
}
1 change: 1 addition & 0 deletions src/ffmpeg-decode.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ extern bool ffmpeg_decode_audio(struct ffmpeg_decode *decode, uint8_t *data,

extern bool ffmpeg_decode_video(struct ffmpeg_decode *decode, uint8_t *data,
size_t size, long long *ts,
enum video_colorspace cs,
enum video_range_type range,
struct obs_source_frame2 *frame,
bool *got_output);
Expand Down
5 changes: 3 additions & 2 deletions src/obs-ssp-source.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -179,8 +179,9 @@ static void ssp_on_video_data(struct imf::SspH264Data *video, ssp_connection *s)
int64_t ts = video->pts;
bool got_output;
bool success = ffmpeg_decode_video(&s->vdecoder, video->data,
video->len, &ts, VIDEO_RANGE_PARTIAL,
&s->frame, &got_output);
video->len, &ts, VIDEO_CS_DEFAULT,
VIDEO_RANGE_PARTIAL, &s->frame,
&got_output);
if (!success) {
ssp_blog(LOG_WARNING, "Error decoding video");
return;
Expand Down