mirror of
https://git.sr.ht/~thestr4ng3r/chiaki
synced 2025-08-20 13:33:13 -07:00
Pass StreamInfo to Video Receiver
This commit is contained in:
parent
b2541d5430
commit
ef106073d9
6 changed files with 148 additions and 2 deletions
|
@ -18,6 +18,7 @@ set(HEADER_FILES
|
||||||
include/chiaki/gkcrypt.h
|
include/chiaki/gkcrypt.h
|
||||||
include/chiaki/audio.h
|
include/chiaki/audio.h
|
||||||
include/chiaki/audioreceiver.h
|
include/chiaki/audioreceiver.h
|
||||||
|
include/chiaki/video.h
|
||||||
include/chiaki/videoreceiver.h)
|
include/chiaki/videoreceiver.h)
|
||||||
|
|
||||||
set(SOURCE_FILES
|
set(SOURCE_FILES
|
||||||
|
|
40
lib/include/chiaki/video.h
Normal file
40
lib/include/chiaki/video.h
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
/*
|
||||||
|
* This file is part of Chiaki.
|
||||||
|
*
|
||||||
|
* Chiaki 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.
|
||||||
|
*
|
||||||
|
* Chiaki 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 Chiaki. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef CHIAKI_VIDEO_H
|
||||||
|
#define CHIAKI_VIDEO_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef struct chiaki_video_profile_t
|
||||||
|
{
|
||||||
|
unsigned int width;
|
||||||
|
unsigned int height;
|
||||||
|
size_t header_sz;
|
||||||
|
uint8_t *header;
|
||||||
|
} ChiakiVideoProfile;
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // CHIAKI_VIDEO_H
|
|
@ -20,21 +20,34 @@
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
#include "video.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define CHIAKI_VIDEO_PROFILES_MAX 8
|
||||||
|
|
||||||
typedef struct chiaki_video_receiver_t
|
typedef struct chiaki_video_receiver_t
|
||||||
{
|
{
|
||||||
struct chiaki_session_t *session;
|
struct chiaki_session_t *session;
|
||||||
ChiakiLog *log;
|
ChiakiLog *log;
|
||||||
|
ChiakiVideoProfile profiles[CHIAKI_VIDEO_PROFILES_MAX];
|
||||||
|
size_t profiles_count;
|
||||||
} ChiakiVideoReceiver;
|
} ChiakiVideoReceiver;
|
||||||
|
|
||||||
CHIAKI_EXPORT void chiaki_video_receiver_init(ChiakiVideoReceiver *video_receiver, struct chiaki_session_t *session);
|
CHIAKI_EXPORT void chiaki_video_receiver_init(ChiakiVideoReceiver *video_receiver, struct chiaki_session_t *session);
|
||||||
CHIAKI_EXPORT void chiaki_video_receiver_fini(ChiakiVideoReceiver *video_receiver);
|
CHIAKI_EXPORT void chiaki_video_receiver_fini(ChiakiVideoReceiver *video_receiver);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called after receiving the Stream Info Packet.
|
||||||
|
*
|
||||||
|
* @param video_receiver
|
||||||
|
* @param profiles Array of profiles. Ownership of the contained header buffers will be transferred to the ChiakiVideoReceiver!
|
||||||
|
* @param profiles_count must be <= CHIAKI_VIDEO_PROFILES_MAX
|
||||||
|
*/
|
||||||
|
CHIAKI_EXPORT void chiaki_video_receiver_stream_info(ChiakiVideoReceiver *video_receiver, ChiakiVideoProfile *profiles, size_t profiles_count);
|
||||||
|
|
||||||
static inline ChiakiVideoReceiver *chiaki_video_receiver_new(struct chiaki_session_t *session)
|
static inline ChiakiVideoReceiver *chiaki_video_receiver_new(struct chiaki_session_t *session)
|
||||||
{
|
{
|
||||||
ChiakiVideoReceiver *video_receiver = CHIAKI_NEW(ChiakiVideoReceiver);
|
ChiakiVideoReceiver *video_receiver = CHIAKI_NEW(ChiakiVideoReceiver);
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#include <chiaki/launchspec.h>
|
#include <chiaki/launchspec.h>
|
||||||
#include <chiaki/base64.h>
|
#include <chiaki/base64.h>
|
||||||
#include <chiaki/audio.h>
|
#include <chiaki/audio.h>
|
||||||
|
#include <chiaki/video.h>
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
@ -305,6 +306,44 @@ error:
|
||||||
chiaki_mirai_signal(&nagare->mirai, NAGARE_MIRAI_RESPONSE_FAIL);
|
chiaki_mirai_signal(&nagare->mirai, NAGARE_MIRAI_RESPONSE_FAIL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef struct decode_resolutions_context_t
|
||||||
|
{
|
||||||
|
ChiakiNagare *nagare;
|
||||||
|
ChiakiVideoProfile video_profiles[CHIAKI_VIDEO_PROFILES_MAX];
|
||||||
|
size_t video_profiles_count;
|
||||||
|
} DecodeResolutionsContext;
|
||||||
|
|
||||||
|
static bool pb_decode_resolution(pb_istream_t *stream, const pb_field_t *field, void **arg)
|
||||||
|
{
|
||||||
|
DecodeResolutionsContext *ctx = *arg;
|
||||||
|
|
||||||
|
tkproto_ResolutionPayload resolution = { 0 };
|
||||||
|
ChiakiPBDecodeBufAlloc header_buf = { 0 };
|
||||||
|
resolution.video_header.arg = &header_buf;
|
||||||
|
resolution.video_header.funcs.decode = chiaki_pb_decode_buf_alloc;
|
||||||
|
if(!pb_decode(stream, tkproto_ResolutionPayload_fields, &resolution))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if(!header_buf.buf)
|
||||||
|
{
|
||||||
|
CHIAKI_LOGE(&ctx->nagare->session->log, "Failed to decode video header\n");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(ctx->video_profiles_count >= CHIAKI_VIDEO_PROFILES_MAX)
|
||||||
|
{
|
||||||
|
CHIAKI_LOGE(&ctx->nagare->session->log, "Received more resolutions than the maximum\n");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
ChiakiVideoProfile *profile = &ctx->video_profiles[ctx->video_profiles_count++];
|
||||||
|
profile->width = resolution.width;
|
||||||
|
profile->height = resolution.height;
|
||||||
|
profile->header_sz = header_buf.size;
|
||||||
|
profile->header = header_buf.buf;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void nagare_takion_data_expect_streaminfo(ChiakiNagare *nagare, uint8_t *buf, size_t buf_size)
|
static void nagare_takion_data_expect_streaminfo(ChiakiNagare *nagare, uint8_t *buf, size_t buf_size)
|
||||||
{
|
{
|
||||||
|
@ -316,7 +355,12 @@ static void nagare_takion_data_expect_streaminfo(ChiakiNagare *nagare, uint8_t *
|
||||||
msg.stream_info_payload.audio_header.arg = &audio_header_buf;
|
msg.stream_info_payload.audio_header.arg = &audio_header_buf;
|
||||||
msg.stream_info_payload.audio_header.funcs.decode = chiaki_pb_decode_buf;
|
msg.stream_info_payload.audio_header.funcs.decode = chiaki_pb_decode_buf;
|
||||||
|
|
||||||
// TODO: msg.stream_info_payload.resolution
|
DecodeResolutionsContext decode_resolutions_context;
|
||||||
|
decode_resolutions_context.nagare = nagare;
|
||||||
|
memset(decode_resolutions_context.video_profiles, 0, sizeof(decode_resolutions_context.video_profiles));
|
||||||
|
decode_resolutions_context.video_profiles_count = 0;
|
||||||
|
msg.stream_info_payload.resolution.arg = &decode_resolutions_context;
|
||||||
|
msg.stream_info_payload.resolution.funcs.decode = pb_decode_resolution;
|
||||||
|
|
||||||
pb_istream_t stream = pb_istream_from_buffer(buf, buf_size);
|
pb_istream_t stream = pb_istream_from_buffer(buf, buf_size);
|
||||||
bool r = pb_decode(&stream, tkproto_TakionMessage_fields, &msg);
|
bool r = pb_decode(&stream, tkproto_TakionMessage_fields, &msg);
|
||||||
|
@ -342,6 +386,10 @@ static void nagare_takion_data_expect_streaminfo(ChiakiNagare *nagare, uint8_t *
|
||||||
chiaki_audio_header_load(&audio_header_s, audio_header);
|
chiaki_audio_header_load(&audio_header_s, audio_header);
|
||||||
chiaki_audio_receiver_stream_info(nagare->session->audio_receiver, &audio_header_s);
|
chiaki_audio_receiver_stream_info(nagare->session->audio_receiver, &audio_header_s);
|
||||||
|
|
||||||
|
chiaki_video_receiver_stream_info(nagare->session->video_receiver,
|
||||||
|
decode_resolutions_context.video_profiles,
|
||||||
|
decode_resolutions_context.video_profiles_count);
|
||||||
|
|
||||||
// TODO: do some checks?
|
// TODO: do some checks?
|
||||||
|
|
||||||
nagare_send_streaminfo_ack(nagare);
|
nagare_send_streaminfo_ack(nagare);
|
||||||
|
|
|
@ -72,4 +72,23 @@ static bool chiaki_pb_decode_buf(pb_istream_t *stream, const pb_field_t *field,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct chiaki_pb_decode_buf_alloc_t
|
||||||
|
{
|
||||||
|
size_t size;
|
||||||
|
uint8_t *buf;
|
||||||
|
} ChiakiPBDecodeBufAlloc;
|
||||||
|
|
||||||
|
static bool chiaki_pb_decode_buf_alloc(pb_istream_t *stream, const pb_field_t *field, void **arg)
|
||||||
|
{
|
||||||
|
ChiakiPBDecodeBufAlloc *buf = *arg;
|
||||||
|
buf->size = stream->bytes_left;
|
||||||
|
buf->buf = malloc(buf->size);
|
||||||
|
if(!buf->buf)
|
||||||
|
return false;
|
||||||
|
bool r = pb_read(stream, buf->buf, buf->size);
|
||||||
|
if(!r)
|
||||||
|
buf->size = 0;
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
#endif // CHIAKI_PB_UTILS_H
|
#endif // CHIAKI_PB_UTILS_H
|
||||||
|
|
|
@ -18,13 +18,38 @@
|
||||||
#include <chiaki/videoreceiver.h>
|
#include <chiaki/videoreceiver.h>
|
||||||
#include <chiaki/session.h>
|
#include <chiaki/session.h>
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
CHIAKI_EXPORT void chiaki_video_receiver_init(ChiakiVideoReceiver *video_receiver, struct chiaki_session_t *session)
|
CHIAKI_EXPORT void chiaki_video_receiver_init(ChiakiVideoReceiver *video_receiver, struct chiaki_session_t *session)
|
||||||
{
|
{
|
||||||
video_receiver->session = session;
|
video_receiver->session = session;
|
||||||
video_receiver->log = &session->log;
|
video_receiver->log = &session->log;
|
||||||
|
memset(video_receiver->profiles, 0, sizeof(video_receiver->profiles));
|
||||||
|
video_receiver->profiles_count = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
CHIAKI_EXPORT void chiaki_video_receiver_fini(ChiakiVideoReceiver *video_receiver)
|
CHIAKI_EXPORT void chiaki_video_receiver_fini(ChiakiVideoReceiver *video_receiver)
|
||||||
{
|
{
|
||||||
|
for(size_t i=0; i<video_receiver->profiles_count; i++)
|
||||||
|
free(video_receiver->profiles[i].header);
|
||||||
|
}
|
||||||
|
|
||||||
|
CHIAKI_EXPORT void chiaki_video_receiver_stream_info(ChiakiVideoReceiver *video_receiver, ChiakiVideoProfile *profiles, size_t profiles_count)
|
||||||
|
{
|
||||||
|
if(video_receiver->profiles_count > 0)
|
||||||
|
{
|
||||||
|
CHIAKI_LOGE(video_receiver->log, "Video Receiver profiles already set\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(video_receiver->profiles, profiles, profiles_count * sizeof(ChiakiVideoProfile));
|
||||||
|
video_receiver->profiles_count = profiles_count;
|
||||||
|
|
||||||
|
CHIAKI_LOGI(video_receiver->log, "Video Profiles:\n");
|
||||||
|
for(size_t i=0; i<video_receiver->profiles_count; i++)
|
||||||
|
{
|
||||||
|
ChiakiVideoProfile *profile = &video_receiver->profiles[i];
|
||||||
|
CHIAKI_LOGI(video_receiver->log, " %zu: %ux%u\n", i, profile->width, profile->height);
|
||||||
|
chiaki_log_hexdump(video_receiver->log, CHIAKI_LOG_DEBUG, profile->header, profile->header_sz);
|
||||||
|
}
|
||||||
}
|
}
|
Loading…
Add table
Add a link
Reference in a new issue