提交 e8060a81 authored 作者: Anthony Minessale's avatar Anthony Minessale

refactor

git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@16119 d0543943-73ff-0310-b7d9-9358b9ac24b2
上级 fb99b2ea
......@@ -1152,168 +1152,93 @@ static void *SWITCH_THREAD_FUNC conference_thread_run(switch_thread_t *thread, v
has_file_data = 1;
}
if (!conference->relationship_total) {
/* If there are no relationships meaning (user x can specificly not speal to and/or hear user y), use a more efficient muxing technique. */
if (ready || has_file_data) {
/* Use more bits in the main_frame to preserve the exact sum of the audio samples. */
int main_frame[SWITCH_RECOMMENDED_BUFFER_SIZE / 2] = { 0 };
int16_t write_frame[SWITCH_RECOMMENDED_BUFFER_SIZE / 2] = { 0 };
/* Init the main frame with file data if there is any. */
bptr = (int16_t *) file_frame;
if (has_file_data && file_sample_len) {
for (x = 0; x < bytes / 2; x++) {
if (x <= file_sample_len) {
main_frame[x] = (int32_t) bptr[x];
} else {
main_frame[x] = 255;
}
}
}
/* Copy audio from every member known to be producing audio into the main frame. */
for (omember = conference->members; omember; omember = omember->next) {
if (!(switch_test_flag(omember, MFLAG_RUNNING) && switch_test_flag(omember, MFLAG_HAS_AUDIO))) {
continue;
}
bptr = (int16_t *) omember->frame;
for (x = 0; x < omember->read / 2; x++) {
main_frame[x] += (int32_t) bptr[x];
}
}
/* Create write frame once per member who is not deaf for each sample in the main frame
check if our audio is involved and if so, subtract it from the sample so we don't hear ourselves.
Since main frame was 32 bit int, we did not lose any detail, now that we have to convert to 16 bit we can
cut it off at the min and max range if need be and write the frame to the output buffer.
*/
for (omember = conference->members; omember; omember = omember->next) {
switch_size_t ok = 1;
if (!switch_test_flag(omember, MFLAG_RUNNING)) {
continue;
}
if (ready || has_file_data) {
/* Use more bits in the main_frame to preserve the exact sum of the audio samples. */
int main_frame[SWITCH_RECOMMENDED_BUFFER_SIZE / 2] = { 0 };
int16_t write_frame[SWITCH_RECOMMENDED_BUFFER_SIZE / 2] = { 0 };
if (!switch_test_flag(omember, MFLAG_CAN_HEAR) && !switch_test_flag(omember, MFLAG_WASTE_BANDWIDTH)
&& !switch_test_flag(conference, CFLAG_WASTE_BANDWIDTH)) {
continue;
}
bptr = (int16_t *) omember->frame;
for (x = 0; x < bytes / 2; x++) {
z = main_frame[x];
/* bptr[x] represents my own contribution to this audio sample */
if (switch_test_flag(omember, MFLAG_HAS_AUDIO) && x <= omember->read / 2) {
z -= (int32_t) bptr[x];
}
/* Now we can convert to 16 bit.*/
switch_normalize_to_16bit(z);
write_frame[x] = (int16_t) z;
}
switch_mutex_lock(omember->audio_out_mutex);
ok = switch_buffer_write(omember->mux_buffer, write_frame, bytes);
switch_mutex_unlock(omember->audio_out_mutex);
if (!ok) {
goto end;
/* Init the main frame with file data if there is any. */
bptr = (int16_t *) file_frame;
if (has_file_data && file_sample_len) {
for (x = 0; x < bytes / 2; x++) {
if (x <= file_sample_len) {
main_frame[x] = (int32_t) bptr[x];
} else {
main_frame[x] = 255;
}
}
}
/* Copy audio from every member known to be producing audio into the main frame. */
for (omember = conference->members; omember; omember = omember->next) {
if (!(switch_test_flag(omember, MFLAG_RUNNING) && switch_test_flag(omember, MFLAG_HAS_AUDIO))) {
continue;
}
bptr = (int16_t *) omember->frame;
for (x = 0; x < omember->read / 2; x++) {
main_frame[x] += (int32_t) bptr[x];
}
}
} else {
if (ready || has_file_data) {
/* Build a muxed frame for every member that contains the mixed audio of everyone else */
for (omember = conference->members; omember; omember = omember->next) {
if (has_file_data && file_sample_len) {
uint32_t sample_bytes = file_sample_len * 2;
memcpy(omember->mux_frame, file_frame, sample_bytes);
if (sample_bytes < bytes) {
if (conference->comfort_noise_level) {
switch_generate_sln_silence((int16_t *) omember->mux_frame + sample_bytes,
(bytes - sample_bytes) / 2, conference->comfort_noise_level);
} else {
memset(omember->mux_frame + sample_bytes, 255, bytes - sample_bytes);
}
}
} else {
if (conference->comfort_noise_level) {
switch_generate_sln_silence((int16_t *) omember->mux_frame, bytes / 2, conference->comfort_noise_level);
} else {
memset(omember->mux_frame, 255, bytes);
}
}
for (imember = conference->members; imember; imember = imember->next) {
uint32_t x;
int16_t *muxed;
if (imember == omember || !imember->read) {
/* Don't add audio from yourself or if you didn't read any */
continue;
}
/* Create write frame once per member who is not deaf for each sample in the main frame
check if our audio is involved and if so, subtract it from the sample so we don't hear ourselves.
Since main frame was 32 bit int, we did not lose any detail, now that we have to convert to 16 bit we can
cut it off at the min and max range if need be and write the frame to the output buffer.
*/
for (omember = conference->members; omember; omember = omember->next) {
switch_size_t ok = 1;
/* If they are not supposed to talk to us then don't let them */
if (omember->relationships) {
conference_relationship_t *rel;
if (!switch_test_flag(omember, MFLAG_RUNNING)) {
continue;
}
if ((rel = member_get_relationship(omember, imember))) {
if (!switch_test_flag(rel, RFLAG_CAN_HEAR)) {
continue;
}
}
}
if (!switch_test_flag(omember, MFLAG_CAN_HEAR) && !switch_test_flag(omember, MFLAG_WASTE_BANDWIDTH)
&& !switch_test_flag(conference, CFLAG_WASTE_BANDWIDTH)) {
continue;
}
/* If we are not supposed to hear them then don't let it happen */
if (imember->relationships) {
bptr = (int16_t *) omember->frame;
for (x = 0; x < bytes / 2; x++) {
z = main_frame[x];
/* bptr[x] represents my own contribution to this audio sample */
if (switch_test_flag(omember, MFLAG_HAS_AUDIO) && x <= omember->read / 2) {
z -= (int32_t) bptr[x];
}
/* when there are relationships, we have to do more work by scouring all the members to see if there are any
reasons why we should not be hearing a paticular member, and if not, delete their samples as well.
*/
if (conference->relationship_total) {
for (imember = conference->members; imember; imember = imember->next) {
conference_relationship_t *rel;
if ((rel = member_get_relationship(imember, omember))) {
if (!switch_test_flag(rel, RFLAG_CAN_SPEAK)) {
continue;
for (rel = imember->relationships; rel; rel = rel->next) {
if (imember != omember && switch_test_flag(imember, MFLAG_HAS_AUDIO)) {
int16_t *rptr = (int16_t *) imember->frame;
if ((rel->id == omember->id || rel->id == 0) && !switch_test_flag(rel, RFLAG_CAN_SPEAK)) {
z -= (int32_t) rptr[x];
}
if ((rel->id == imember->id || rel->id == 0) && !switch_test_flag(rel, RFLAG_CAN_HEAR)) {
z -= (int32_t) rptr[x];
}
}
}
}
#if 0
if (nt && conference->not_talking_buf_len && !switch_test_flag(omember, MFLAG_HAS_AUDIO)) {
memcpy(omember->mux_frame, conference->not_talking_buf, conference->not_talking_buf_len);
continue;
}
#endif
bptr = (int16_t *) imember->frame;
muxed = (int16_t *) omember->mux_frame;
for (x = 0; x < imember->read / 2; x++) {
int32_t z = muxed[x] + bptr[x];
switch_normalize_to_16bit(z);
muxed[x] = (int16_t) z;
}
#if 0
if (total - ready > 1) {
conference->not_talking_buf_len = imember->read;
if (!conference->not_talking_buf) {
conference->not_talking_buf = switch_core_alloc(conference->pool, imember->read + 128);
}
memcpy(conference->not_talking_buf, muxed, conference->not_talking_buf_len);
nt++;
}
#endif
}
/* Now we can convert to 16 bit.*/
switch_normalize_to_16bit(z);
write_frame[x] = (int16_t) z;
}
if (bytes) {
/* Go back and write each member his dedicated copy of the audio frame that does not contain his own audio. */
for (imember = conference->members; imember; imember = imember->next) {
if (switch_test_flag(imember, MFLAG_RUNNING)) {
switch_size_t ok = 1;
switch_mutex_lock(imember->audio_out_mutex);
ok = switch_buffer_write(imember->mux_buffer, imember->mux_frame, bytes);
switch_mutex_unlock(imember->audio_out_mutex);
if (!ok) {
goto end;
}
}
}
switch_mutex_lock(omember->audio_out_mutex);
ok = switch_buffer_write(omember->mux_buffer, write_frame, bytes);
switch_mutex_unlock(omember->audio_out_mutex);
if (!ok) {
goto end;
}
}
}
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论