Skip to content

Commit 3de37c8

Browse files
committed
update to 13.1.1 (7237)
1 parent 3ba4e60 commit 3de37c8

25 files changed

Lines changed: 904 additions & 323 deletions

‎Dockerfile‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,9 @@ CMD mkdir -p /home/source/TMessagesProj/build/outputs/apk && \
3939
mkdir -p /home/source/TMessagesProj/build/outputs/mapping/TMessagesProj_App \
4040
/home/source/TMessagesProj/build/outputs/mapping/TMessagesProj_AppHuawei \
4141
/home/source/TMessagesProj/build/outputs/mapping/TMessagesProj_AppStandalone && \
42-
cp -R /home/source/. /home/gradle && \
42+
tar -C /home/source \
43+
--exclude=./.git --exclude=.cxx --exclude=build --exclude=.gradle --exclude=./local.properties \
44+
-cf - . | tar -C /home/gradle -xf - && \
4345
cd /home/gradle && \
4446
gradle --parallel \
4547
:TMessagesProj_App:bundleBundleAfatRelease \

‎TMessagesProj/jni/audio.c‎

Lines changed: 114 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,8 @@ static int writeOggPage(ogg_page *page, FILE *os) {
222222
return written;
223223
}
224224

225-
const opus_int32 bitrate = OPUS_BITRATE_MAX;
225+
const opus_int32 bitrate = 30 * 1024;
226+
static const int opus_application = OPUS_APPLICATION_AUDIO;
226227
const opus_int32 frame_size = 960;
227228
const int with_cvbr = 1;
228229
const int max_ogg_delay = 0;
@@ -343,7 +344,7 @@ int initRecorder(const char *path, opus_int32 sampleRate) {
343344
header.nb_streams = 1;
344345

345346
int result = OPUS_OK;
346-
_encoder = opus_encoder_create(coding_rate, 1, OPUS_APPLICATION_VOIP, &result);
347+
_encoder = opus_encoder_create(coding_rate, 1, opus_application, &result);
347348
if (result != OPUS_OK) {
348349
LOGE("Error cannot create encoder: %s", opus_strerror(result));
349350
return 0;
@@ -1315,7 +1316,7 @@ static AudioRecorderContext *createAudioRecorderContext(const char *path, opus_i
13151316
recorder->encoder = opus_encoder_create(
13161317
recorder->coding_rate,
13171318
1,
1318-
OPUS_APPLICATION_VOIP,
1319+
opus_application,
13191320
&result
13201321
);
13211322
if (result != OPUS_OK) {
@@ -1437,10 +1438,13 @@ static AudioRecorderContext *createAudioRecorderContext(const char *path, opus_i
14371438
return recorder;
14381439
}
14391440

1440-
static int writeAudioRecorderContextFrame(
1441+
// countedSamples is how many of the encoded samples belong to the stream duration; padding
1442+
// frames that only flush the encoder lookahead count zero.
1443+
static int writeAudioRecorderContextPacket(
14411444
AudioRecorderContext *recorder,
14421445
uint8_t *framePcmBytes,
14431446
uint32_t frameByteCount,
1447+
opus_int32 countedSamples,
14441448
int end
14451449
) {
14461450
if (!recorder || !recorder->encoder || !recorder->file) {
@@ -1450,7 +1454,7 @@ static int writeAudioRecorderContextFrame(
14501454
recorder->packet_id++;
14511455

14521456
opus_int32 nb_samples = frameByteCount / 2;
1453-
recorder->total_samples += nb_samples;
1457+
recorder->total_samples += countedSamples;
14541458
recorder->ogg_packet.e_o_s = end;
14551459

14561460
int nbBytes = 0;
@@ -1549,6 +1553,63 @@ static int writeAudioRecorderContextFrame(
15491553
return 1;
15501554
}
15511555

1556+
static int writeAudioRecorderContextFrame(
1557+
AudioRecorderContext *recorder,
1558+
uint8_t *framePcmBytes,
1559+
uint32_t frameByteCount,
1560+
int end
1561+
) {
1562+
return writeAudioRecorderContextPacket(
1563+
recorder,
1564+
framePcmBytes,
1565+
frameByteCount,
1566+
(opus_int32) (frameByteCount / 2),
1567+
end
1568+
);
1569+
}
1570+
1571+
// Writes the buffered tail and enough silent frames to push the encoder lookahead out, then
1572+
// marks the last packet as end of stream. Its granule position trims the padding, so the
1573+
// stream ends exactly after the last captured sample.
1574+
static int finishAudioRecorderStream(AudioRecorderContext *recorder) {
1575+
if (!recorder) {
1576+
return 0;
1577+
}
1578+
if (recorder->pending_samples > 0) {
1579+
int pendingSamples = recorder->pending_samples;
1580+
recorder->pending_samples = 0;
1581+
if (!writeAudioRecorderContextFrame(
1582+
recorder,
1583+
(uint8_t *) recorder->pending_frame,
1584+
pendingSamples * sizeof(int16_t),
1585+
0
1586+
)) {
1587+
return 0;
1588+
}
1589+
}
1590+
ogg_int64_t endGranulePosition =
1591+
(recorder->total_samples * 48000 + recorder->rate - 1) / recorder->rate
1592+
+ recorder->header.preskip;
1593+
int16_t silence[960];
1594+
memset(silence, 0, sizeof(silence));
1595+
while (1) {
1596+
int end = recorder->encoded_granule_position
1597+
+ frame_size * 48000 / recorder->coding_rate >= endGranulePosition;
1598+
if (!writeAudioRecorderContextPacket(
1599+
recorder,
1600+
(uint8_t *) silence,
1601+
sizeof(silence),
1602+
0,
1603+
end
1604+
)) {
1605+
return 0;
1606+
}
1607+
if (end) {
1608+
return 1;
1609+
}
1610+
}
1611+
}
1612+
15521613
static jlong flushAudioRecorderContext(AudioRecorderContext *recorder) {
15531614
if (!recorder || !recorder->file || fflush(recorder->file) != 0) {
15541615
return -1;
@@ -1631,15 +1692,17 @@ static int cropAudioRecorderOpusAudio(const char *inputPath, const char *outputP
16311692
}
16321693
remaining_samples -= samples_read;
16331694

1634-
int end = remaining_samples <= 0;
1635-
16361695
size_t byte_count = samples_read * sizeof(int16_t);
1637-
if (!writeAudioRecorderContextFrame(recorder, (uint8_t *)buffer, byte_count, end)) {
1696+
if (!writeAudioRecorderContextFrame(recorder, (uint8_t *)buffer, byte_count, 0)) {
16381697
LOGE("Failed to write frame");
16391698
success = 0;
16401699
break;
16411700
}
16421701
}
1702+
if (success && !finishAudioRecorderStream(recorder)) {
1703+
LOGE("Failed to finish cropped stream");
1704+
success = 0;
1705+
}
16431706

16441707
free(buffer);
16451708
destroyAudioRecorderContext(recorder);
@@ -1648,9 +1711,13 @@ static int cropAudioRecorderOpusAudio(const char *inputPath, const char *outputP
16481711
return success;
16491712
}
16501713

1714+
// Re-encodes [startMs, endMs) of the prefix file into the recorder; a negative endMs keeps the
1715+
// rest of the file.
16511716
static int appendRecorderPrefix(
16521717
AudioRecorderContext *recorder,
1653-
const char *prefixPath
1718+
const char *prefixPath,
1719+
opus_int64 startMs,
1720+
opus_int64 endMs
16541721
) {
16551722
if (!recorder || !prefixPath) {
16561723
return 0;
@@ -1673,6 +1740,26 @@ static int appendRecorderPrefix(
16731740
return 0;
16741741
}
16751742

1743+
opus_int64 remainingSamples = INT64_MAX;
1744+
if (startMs > 0 || endMs >= 0) {
1745+
opus_int64 totalSamples = op_pcm_total(prefixFile, -1);
1746+
if (totalSamples < 0) {
1747+
LOGE("Failed to get Opus prefix length: %lld", (long long) totalSamples);
1748+
op_free(prefixFile);
1749+
return 0;
1750+
}
1751+
opus_int64 startSample = MAX(0, MIN(totalSamples, startMs * 48000 / 1000));
1752+
opus_int64 endSample = endMs < 0
1753+
? totalSamples
1754+
: MAX(startSample, MIN(totalSamples, endMs * 48000 / 1000));
1755+
if (startSample > 0 && op_pcm_seek(prefixFile, startSample) != 0) {
1756+
LOGE("Failed to seek Opus prefix to %lld", (long long) startSample);
1757+
op_free(prefixFile);
1758+
return 0;
1759+
}
1760+
remainingSamples = endSample - startSample;
1761+
}
1762+
16761763
int16_t *buffer = malloc(sizeof(int16_t) * frame_size);
16771764
if (!buffer) {
16781765
LOGE("Out of memory while rebuilding Opus prefix");
@@ -1682,11 +1769,11 @@ static int appendRecorderPrefix(
16821769

16831770
int success = 1;
16841771
int bufferedSamples = 0;
1685-
while (1) {
1772+
while (remainingSamples > 0) {
16861773
int samplesRead = op_read(
16871774
prefixFile,
16881775
buffer + bufferedSamples,
1689-
frame_size - bufferedSamples,
1776+
(int) MIN(frame_size - bufferedSamples, remainingSamples),
16901777
NULL
16911778
);
16921779
if (samplesRead < 0) {
@@ -1697,6 +1784,7 @@ static int appendRecorderPrefix(
16971784
if (samplesRead == 0) {
16981785
break;
16991786
}
1787+
remainingSamples -= samplesRead;
17001788
bufferedSamples += samplesRead;
17011789
if (bufferedSamples == frame_size) {
17021790
if (!writeAudioRecorderContextFrame(
@@ -1728,8 +1816,7 @@ static int appendRecorderPrefix(
17281816
static int writeAudioRecorderFrame(
17291817
AudioRecorderContext *recorder,
17301818
uint8_t *pcmBytes,
1731-
uint32_t byteCount,
1732-
int end
1819+
uint32_t byteCount
17331820
) {
17341821
if (!recorder || (byteCount > 0 && !pcmBytes)) {
17351822
return 0;
@@ -1742,12 +1829,11 @@ static int writeAudioRecorderFrame(
17421829
while (sampleOffset < sampleCount) {
17431830
if (recorder->pending_samples == 0
17441831
&& sampleCount - sampleOffset >= frame_size) {
1745-
int frameEnd = end && sampleOffset + frame_size == sampleCount;
17461832
if (!writeAudioRecorderContextFrame(
17471833
recorder,
17481834
(uint8_t *) (samples + sampleOffset),
17491835
frame_size * sizeof(int16_t),
1750-
frameEnd
1836+
0
17511837
)) {
17521838
return 0;
17531839
}
@@ -1768,29 +1854,17 @@ static int writeAudioRecorderFrame(
17681854
sampleOffset += copySamples;
17691855

17701856
if (recorder->pending_samples == frame_size) {
1771-
int frameEnd = end && sampleOffset == sampleCount;
17721857
if (!writeAudioRecorderContextFrame(
17731858
recorder,
17741859
(uint8_t *) recorder->pending_frame,
17751860
frame_size * sizeof(int16_t),
1776-
frameEnd
1861+
0
17771862
)) {
17781863
return 0;
17791864
}
17801865
recorder->pending_samples = 0;
17811866
}
17821867
}
1783-
1784-
if (end && recorder->pending_samples > 0) {
1785-
int result = writeAudioRecorderContextFrame(
1786-
recorder,
1787-
(uint8_t *) recorder->pending_frame,
1788-
recorder->pending_samples * sizeof(int16_t),
1789-
1
1790-
);
1791-
recorder->pending_samples = 0;
1792-
return result;
1793-
}
17941868
return 1;
17951869
}
17961870

@@ -1799,7 +1873,9 @@ JNIEXPORT jlong Java_org_telegram_utils_recorder_audio_AudioRecorderNative_nCrea
17991873
jclass clazz,
18001874
jstring path,
18011875
jint sampleRate,
1802-
jstring prefixPath
1876+
jstring prefixPath,
1877+
jlong prefixStartMs,
1878+
jlong prefixEndMs
18031879
) {
18041880
const char *pathString = (*env)->GetStringUTFChars(env, path, 0);
18051881
if (!pathString) {
@@ -1818,7 +1894,12 @@ JNIEXPORT jlong Java_org_telegram_utils_recorder_audio_AudioRecorderNative_nCrea
18181894
destroyAudioRecorderContext(recorder);
18191895
return 0;
18201896
}
1821-
int prefixResult = appendRecorderPrefix(recorder, prefixPathString);
1897+
int prefixResult = appendRecorderPrefix(
1898+
recorder,
1899+
prefixPathString,
1900+
prefixStartMs,
1901+
prefixEndMs
1902+
);
18221903
(*env)->ReleaseStringUTFChars(env, prefixPath, prefixPathString);
18231904
if (!prefixResult) {
18241905
destroyAudioRecorderContext(recorder);
@@ -1842,12 +1923,8 @@ JNIEXPORT jint Java_org_telegram_utils_recorder_audio_AudioRecorderNative_nWrite
18421923
if (!recorder || !frameBytes || length < 0 || capacity < length) {
18431924
return 0;
18441925
}
1845-
return writeAudioRecorderFrame(
1846-
recorder,
1847-
(uint8_t *) frameBytes,
1848-
(uint32_t) length,
1849-
length / 2 < frame_size
1850-
);
1926+
// A short frame is just the tail of the capture; the stream ends only in nFinish.
1927+
return writeAudioRecorderFrame(recorder, (uint8_t *) frameBytes, (uint32_t) length);
18511928
}
18521929

18531930
JNIEXPORT jlong Java_org_telegram_utils_recorder_audio_AudioRecorderNative_nFlush(
@@ -1869,10 +1946,7 @@ JNIEXPORT jboolean Java_org_telegram_utils_recorder_audio_AudioRecorderNative_nF
18691946
return JNI_FALSE;
18701947
}
18711948

1872-
int result = 1;
1873-
if (recorder->pending_samples > 0) {
1874-
result = writeAudioRecorderFrame(recorder, NULL, 0, 1);
1875-
}
1949+
int result = finishAudioRecorderStream(recorder);
18761950
if (result && flushAudioRecorderContext(recorder) < 0) {
18771951
result = 0;
18781952
}

‎TMessagesProj/jni/voip/CMakeLists.txt‎

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -181,8 +181,7 @@ add_library(tgcalls STATIC
181181
tgcalls/tgcalls/v2/InstanceV2CompatImpl.cpp
182182
tgcalls/tgcalls/v2/InstanceV2Impl.cpp
183183
tgcalls/tgcalls/v2/InstanceV2ReferenceImpl.cpp
184-
tgcalls/tgcalls/v2/MtProtoIceTransport.cpp
185-
tgcalls/tgcalls/v2/MtProtoIceTransportTest.cpp
184+
tgcalls/tgcalls/v2/MtProtoDtlsTransport.cpp
186185
tgcalls/tgcalls/v2/NativeNetworkingImpl.cpp
187186
tgcalls/tgcalls/v2/RawTcpSocket.cpp
188187
tgcalls/tgcalls/v2/ReflectorPort.cpp

‎TMessagesProj/jni/voip/org_telegram_messenger_voip_Instance.cpp‎

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -824,6 +824,20 @@ JNIEXPORT void JNICALL Java_org_telegram_messenger_voip_NativeInstance_setVideoE
824824
broadcastRequestedSinks(instance);
825825
}
826826

827+
// IPv4 first, then the same server over IPv6 when the connection has one, as iOS
828+
// does. Both entries keep the same id: it travels on the wire as
829+
// reflector-<id>-<tag>.reflector and the peer matches on it.
830+
static void pushRtcServerWithIpv6(std::vector<RtcServer> &rtcServers, RtcServer &&rtcServer, std::string const &ipv6) {
831+
if (ipv6.empty()) {
832+
rtcServers.push_back(std::move(rtcServer));
833+
return;
834+
}
835+
RtcServer rtcServerV6 = rtcServer;
836+
rtcServerV6.host = ipv6;
837+
rtcServers.push_back(std::move(rtcServer));
838+
rtcServers.push_back(std::move(rtcServerV6));
839+
}
840+
827841
extern "C"
828842
JNIEXPORT jlong JNICALL Java_org_telegram_messenger_voip_NativeInstance_makeNativeInstance(
829843
JNIEnv *env, jclass clazz,
@@ -948,7 +962,7 @@ JNIEXPORT jlong JNICALL Java_org_telegram_messenger_voip_NativeInstance_makeNati
948962
rtcServer.login = tgvoip::jni::JavaStringToStdString(env, endpointObject.getStringField("username"));
949963
rtcServer.password = tgvoip::jni::JavaStringToStdString(env, endpointObject.getStringField("password"));
950964
rtcServer.isTurn = endpointObject.getBooleanField("turn");
951-
descriptor.rtcServers.push_back(std::move(rtcServer));
965+
pushRtcServerWithIpv6(descriptor.rtcServers, std::move(rtcServer), tgvoip::jni::JavaStringToStdString(env, endpointObject.getStringField("ipv6")));
952966
} else {
953967
RtcServer rtcServer;
954968
rtcServer.id = static_cast<uint8_t>(endpointObject.getIntField("reflectorId"));
@@ -958,7 +972,7 @@ JNIEXPORT jlong JNICALL Java_org_telegram_messenger_voip_NativeInstance_makeNati
958972
rtcServer.password = tgvoip::jni::JavaStringToStdString(env, endpointObject.getStringField("password"));
959973
rtcServer.isTurn = true;
960974
rtcServer.isTcp = endpointObject.getBooleanField("tcp");
961-
descriptor.rtcServers.push_back(std::move(rtcServer));
975+
pushRtcServerWithIpv6(descriptor.rtcServers, std::move(rtcServer), tgvoip::jni::JavaStringToStdString(env, endpointObject.getStringField("ipv6")));
962976

963977
Endpoint endpoint;
964978
endpoint.endpointId = endpointObject.getLongField("id");

‎TMessagesProj/jni/voip/webrtc/api/peer_connection_interface.cc‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@
1010

1111
#include "api/peer_connection_interface.h"
1212

13+
// TGCALLS SEAM: complete type for PeerConnectionDependencies::dtls_transport_factory
14+
// (the public header only forward-declares it).
15+
#include "p2p/base/dtls_transport_factory.h"
16+
1317
#include <utility>
1418

1519
#include "pc/media_factory.h"

0 commit comments

Comments
 (0)