Skip to content

Commit

Permalink
make H265 encoder optional, and autodetection for H265 encoder
Browse files Browse the repository at this point in the history
  • Loading branch information
zoff99 committed Mar 22, 2024
1 parent 51dc34b commit 38d3c72
Show file tree
Hide file tree
Showing 6 changed files with 144 additions and 86 deletions.
2 changes: 1 addition & 1 deletion toxav/codecs/h264/codec.c
Original file line number Diff line number Diff line change
Expand Up @@ -2468,7 +2468,7 @@ uint32_t send_frames_h265(ToxAV *av, uint32_t friend_number, uint16_t width, uin
0,
*video_frame_record_timestamp,
(int32_t)0,
TOXAV_ENCODER_CODEC_USED_H264,
TOXAV_ENCODER_CODEC_USED_H265,
call->video_bit_rate,
call->video->client_video_capture_delay_ms,
call->video->video_encoder_frame_orientation_angle,
Expand Down
5 changes: 5 additions & 0 deletions toxav/rtp.c
Original file line number Diff line number Diff line change
Expand Up @@ -1150,6 +1150,11 @@ int rtp_send_data(RTPSession *session, const uint8_t *data, uint32_t length, boo
header.flags = header.flags | RTP_ENCODER_IS_H264;
}

if ((codec_used == TOXAV_ENCODER_CODEC_USED_H265) &&
(is_video_payload == 1)) {
header.flags = header.flags | RTP_ENCODER_IS_H265;
}

if (video_frame_orientation_angle == TOXAV_CLIENT_INPUT_VIDEO_ORIENTATION_90) {
header.flags = header.flags | RTP_ENCODER_VIDEO_ROTATION_ANGLE_BIT0;
} else if (video_frame_orientation_angle == TOXAV_CLIENT_INPUT_VIDEO_ORIENTATION_180) {
Expand Down
5 changes: 5 additions & 0 deletions toxav/rtp.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,11 @@ typedef enum RTPFlags {
RTP_ENCODER_VIDEO_ROTATION_ANGLE_BIT0 = 1 << 4,
RTP_ENCODER_VIDEO_ROTATION_ANGLE_BIT1 = 1 << 5,

/**
* Whether H265 codec was used to encode this video frame
*/
RTP_ENCODER_IS_H265 = 1 << 6,

} RTPFlags;


Expand Down
128 changes: 73 additions & 55 deletions toxav/toxav.c
Original file line number Diff line number Diff line change
Expand Up @@ -819,7 +819,7 @@ bool toxav_option_set(ToxAV *av, uint32_t friend_number, TOXAV_OPTIONS_OPTION op
VCSession *vc = (VCSession *)call->video;

if (((int32_t)value >= TOXAV_ENCODER_CODEC_USED_VP8)
&& ((int32_t)value <= TOXAV_ENCODER_CODEC_USED_H264)) {
&& ((int32_t)value <= TOXAV_ENCODER_CODEC_USED_H265)) {

if (vc->video_encoder_coded_used == (int32_t)value) {
LOGGER_API_WARNING(av->tox, "video video_encoder_coded_used already set to: %d", (int)value);
Expand Down Expand Up @@ -1517,7 +1517,8 @@ bool toxav_video_send_frame_age(ToxAV *av, uint32_t friend_number, uint16_t widt

pthread_mutex_lock(call->toxav_call_mutex);
// HINT: auto switch encoder, if we got capabilities packet from friend ------
if (call->video->video_encoder_coded_used != TOXAV_ENCODER_CODEC_USED_H264) {
if ((call->video->video_encoder_coded_used != TOXAV_ENCODER_CODEC_USED_H264) &&
(call->video->video_encoder_coded_used != TOXAV_ENCODER_CODEC_USED_H265)) {
const uint64_t friend_caps = tox_friend_get_capabilities(av->tox, friend_number);
LOGGER_API_DEBUG(av->tox, "-------> CCCCCC:%ld", (long)friend_caps);
if ((friend_caps & TOX_CAPABILITY_TOXAV_H264) != 0) {
Expand All @@ -1528,7 +1529,10 @@ bool toxav_video_send_frame_age(ToxAV *av, uint32_t friend_number, uint16_t widt

if ((call->video->h264_video_capabilities_received == 1)
&&
(call->video->video_encoder_coded_used != TOXAV_ENCODER_CODEC_USED_H264)) {
(call->video->video_encoder_coded_used != TOXAV_ENCODER_CODEC_USED_H264)
&&
(call->video->video_encoder_coded_used != TOXAV_ENCODER_CODEC_USED_H265)
) {
// when switching to H264 set default video bitrate

if (call->video_bit_rate > 0) {
Expand Down Expand Up @@ -1686,24 +1690,10 @@ bool toxav_video_send_frame_age(ToxAV *av, uint32_t friend_number, uint16_t widt
// for the H265 encoder -------
#endif

uint32_t result2_h265 = 1;
int h265_num_nals = 0;

{ /* Encode */

#ifdef HAVE_H265_ENCODER
LOGGER_API_DEBUG(av->tox, "**__** encoding H265 frame **__**");
result2_h265 = encode_frame_h265(av, friend_number, width, height,
y, u, v, call,
&video_frame_record_timestamp,
vpx_encode_flags,
&h265_num_nals,
&nal,
&i_frame_size, &h265_nals);
#endif


/*
if ((call->video->video_encoder_coded_used == TOXAV_ENCODER_CODEC_USED_VP8)
|| (call->video->video_encoder_coded_used == TOXAV_ENCODER_CODEC_USED_VP9)) {

Expand All @@ -1721,21 +1711,42 @@ bool toxav_video_send_frame_age(ToxAV *av, uint32_t friend_number, uint16_t widt
goto END;
}
} else {
LOGGER_API_DEBUG(av->tox, "**##** encoding H264 frame **##**");
uint32_t result = encode_frame_h264(av, friend_number, width, height,
y, u, v, call,
&video_frame_record_timestamp,
vpx_encode_flags,
&nal,
&i_frame_size);

if (result != 0) {
pthread_mutex_unlock(call->mutex_video);
rc = TOXAV_ERR_SEND_FRAME_INVALID;
goto END;
#ifdef HAVE_H265_ENCODER
if (call->video->video_encoder_coded_used == TOXAV_ENCODER_CODEC_USED_H265)
{
LOGGER_API_DEBUG(av->tox, "**__** encoding H265 frame **__**");
uint32_t result = encode_frame_h265(av, friend_number, width, height,
y, u, v, call,
&video_frame_record_timestamp,
vpx_encode_flags,
&h265_num_nals,
&nal,
&i_frame_size, &h265_nals);
if (result != 0) {
pthread_mutex_unlock(call->mutex_video);
rc = TOXAV_ERR_SEND_FRAME_INVALID;
goto END;
}
}
#endif

if (call->video->video_encoder_coded_used == TOXAV_ENCODER_CODEC_USED_H265)
{
LOGGER_API_DEBUG(av->tox, "**##** encoding H264 frame **##**");
uint32_t result = encode_frame_h264(av, friend_number, width, height,
y, u, v, call,
&video_frame_record_timestamp,
vpx_encode_flags,
&nal,
&i_frame_size);
if (result != 0) {
pthread_mutex_unlock(call->mutex_video);
rc = TOXAV_ERR_SEND_FRAME_INVALID;
goto END;
}
}
}
*/
}


Expand All @@ -1746,21 +1757,7 @@ bool toxav_video_send_frame_age(ToxAV *av, uint32_t friend_number, uint16_t widt

{ /* Send frames */

#ifdef HAVE_H265_ENCODER
if (result2_h265 == 0) {
uint32_t result3 = send_frames_h265(av, friend_number, width, height,
y, u, v, call,
&video_frame_record_timestamp,
vpx_encode_flags,
&nal,
&i_frame_size,
h265_num_nals,
&h265_nals,
&rc);
}
#endif

/*
if ((call->video->video_encoder_coded_used == TOXAV_ENCODER_CODEC_USED_VP8)
|| (call->video->video_encoder_coded_used == TOXAV_ENCODER_CODEC_USED_VP9)) {

Expand All @@ -1778,20 +1775,40 @@ bool toxav_video_send_frame_age(ToxAV *av, uint32_t friend_number, uint16_t widt
}

} else {
uint32_t result = send_frames_h264(av, friend_number, width, height,
y, u, v, call,
&video_frame_record_timestamp,
vpx_encode_flags,
&nal,
&i_frame_size,
&rc);

if (result != 0) {
pthread_mutex_unlock(call->mutex_video);
goto END;
#ifdef HAVE_H265_ENCODER
if (call->video->video_encoder_coded_used == TOXAV_ENCODER_CODEC_USED_H265) {
uint32_t result = send_frames_h265(av, friend_number, width, height,
y, u, v, call,
&video_frame_record_timestamp,
vpx_encode_flags,
&nal,
&i_frame_size,
h265_num_nals,
&h265_nals,
&rc);
if (result != 0) {
pthread_mutex_unlock(call->mutex_video);
goto END;
}
}
#endif

if (call->video->video_encoder_coded_used == TOXAV_ENCODER_CODEC_USED_H264) {
uint32_t result = send_frames_h264(av, friend_number, width, height,
y, u, v, call,
&video_frame_record_timestamp,
vpx_encode_flags,
&nal,
&i_frame_size,
&rc);

if (result != 0) {
pthread_mutex_unlock(call->mutex_video);
goto END;
}
}
}
*/
}

pthread_mutex_unlock(call->mutex_video);
Expand Down Expand Up @@ -2174,7 +2191,8 @@ void callback_bwc(BWController *bwc, uint32_t friend_number, float loss, void *u
}

// HINT: sanity check --------------
if (call->video->video_encoder_coded_used == TOXAV_ENCODER_CODEC_USED_H264) {
if ((call->video->video_encoder_coded_used == TOXAV_ENCODER_CODEC_USED_H264) ||
(call->video->video_encoder_coded_used == TOXAV_ENCODER_CODEC_USED_H265)) {
if (call->video_bit_rate < VIDEO_BITRATE_MIN_AUTO_VALUE_H264) {
call->video_bit_rate = VIDEO_BITRATE_MIN_AUTO_VALUE_H264;
} else if (call->video_bit_rate > VIDEO_BITRATE_MAX_AUTO_VALUE_H264) {
Expand Down
3 changes: 3 additions & 0 deletions toxav/toxav.h
Original file line number Diff line number Diff line change
Expand Up @@ -297,9 +297,11 @@ bool toxav_answer(ToxAV *av, uint32_t friend_number, uint32_t audio_bit_rate, ui
typedef enum TOXAV_CALL_COMM_INFO {
TOXAV_CALL_COMM_DECODER_IN_USE_VP8 = 0,
TOXAV_CALL_COMM_DECODER_IN_USE_H264 = 1,
TOXAV_CALL_COMM_DECODER_IN_USE_H265 = 16,
TOXAV_CALL_COMM_ENCODER_IN_USE_VP8 = 2,
TOXAV_CALL_COMM_ENCODER_IN_USE_H264 = 3,
TOXAV_CALL_COMM_ENCODER_IN_USE_H264_OMX_PI = 6,
TOXAV_CALL_COMM_ENCODER_IN_USE_H265 = 15,
TOXAV_CALL_COMM_DECODER_CURRENT_BITRATE = 4,
TOXAV_CALL_COMM_ENCODER_CURRENT_BITRATE = 5,
TOXAV_CALL_COMM_NETWORK_ROUND_TRIP_MS = 7,
Expand Down Expand Up @@ -984,6 +986,7 @@ typedef enum TOXAV_ENCODER_CODEC_USED_VALUE {
TOXAV_ENCODER_CODEC_USED_VP8 = 0,
TOXAV_ENCODER_CODEC_USED_VP9 = 1,
TOXAV_ENCODER_CODEC_USED_H264 = 2,
TOXAV_ENCODER_CODEC_USED_H265 = 3,
} TOXAV_ENCODER_CODEC_USED_VALUE;

typedef enum TOXAV_ENCODER_KF_METHOD_VALUE {
Expand Down
Loading

0 comments on commit 38d3c72

Please sign in to comment.