示例#1
0
bool CConferenceInfo::mix_member_frame(CConferenceMember::pointer member, const CLockMap<CConferenceMember*, CMemberData::pointer> & audios, int & outTimestamp)
{
	BOOST_ASSERT (member.get() != 0);

	if (member->getClosed()) return false;

	bool result = false;
	bool first = true;
	boost::mutex::scoped_lock lock(const_cast<boost::mutex&>(audios.mutex()));
	CLockMap<CConferenceMember*, CMemberData::pointer>::const_iterator iter;
	for (iter=audios.begin(); iter!= audios.end(); iter++)
	{
		if (iter->second->getRtpParam() == member.get())
			continue;

		if (iter->second->isSilence())
			continue;

		result = true;
		member->audioBuffer()->remalloc(iter->second->getRtpData()->size());

		if (first)
		{
			first = false;
			member->audioBuffer()->set(iter->second->getRtpData()->data(), iter->second->getRtpData()->size());
		}else
		{
			mix_slinear_frames((char*)const_cast<void*>(member->audioBuffer()->buffer()), (const char*)iter->second->getRtpData()->data(), iter->second->getRtpData()->size()/2);
		}

		if (iter->second->getRtpData()->timestamp() > (unsigned int)outTimestamp)
			outTimestamp = iter->second->getRtpData()->timestamp();
	}

	return result;
}
struct ast_frame* get_outgoing_frame( struct ast_conference *conf, struct ast_conf_member* member, int samples ) 
{
    //
    // sanity checks
    //
	
    // check on conf
    if ( conf == NULL ) 
    {
    	ast_log( LOG_ERROR, "unable to queue null conference\n" ) ;
	return NULL ;
    }

    if ( conf->memberlist == NULL ) 
    {
    	ast_log( LOG_ERROR, "unable to queue for a null memberlist\n" ) ;
	return NULL ;
    }

    // check on member
    if ( member == NULL )
    {
    	ast_log( LOG_ERROR, "unable to queue frame for null member\n" ) ;
    	return NULL ;
    }

    //***********************************
    // Mixing procedure
    //***********************************

    int members =0;
    struct ast_frame *f = NULL;
    struct ast_conf_member *mixmember;
    short *dst = member->framedata;
    short *src = NULL;

    memset(member->framedata,0,sizeof(member->framedata));

    mixmember=conf->memberlist;
    while ( mixmember ) {
	if (
	    mixmember!=member && mixmember->is_speaking
	    &&
	    ( mixmember->type != MEMBERTYPE_CONSULTANT || ( mixmember->type == MEMBERTYPE_CONSULTANT && member->type == MEMBERTYPE_MASTER ) ) 
	   ) {
	    members++;

    	    src = mixmember->cbuf->buffer8k;
#if  ( APP_NCONFERENCE_DEBUG == 1 )
	    if(vdebug) 
	    ast_log(AST_CONF_DEBUG,
		"Mixing memb %s Chan %s Ind %d Samples %d "
		" bufpos: %p with offset %p  FOR MEMBER %s\n", 
		mixmember->id, mixmember->chan->name, mixmember->cbuf->index8k, samples,
		member->framedata, member->framedata + AST_FRIENDLY_OFFSET/sizeof(short),
		member->chan->name
	    );
#endif
	    mix_slinear_frames( 
		    dst, src,
		    samples, mixmember->cbuf->index8k, sizeof(mixmember->cbuf->buffer8k)/sizeof(short) 
	    );
	}
	mixmember=mixmember->next;
    }

    //Building the frame
    f = calloc(1, sizeof(struct ast_frame));
    if (f != NULL) {
        ast_fr_init_ex(f, AST_FRAME_VOICE, AST_FORMAT_SLINEAR, "Nconf");
	f->data = member->framedata;
	f->datalen = samples*sizeof(short);
	f->samples = samples;
	f->offset = 0;
    } else
	return NULL;

#if  ( APP_NCONFERENCE_DEBUG == 1 )
    if (vdebug && members) {
        int count=0;
        short *msrc;
	msrc = f->data + AST_FRIENDLY_OFFSET;

	if (vdebug) ast_log(AST_CONF_DEBUG,
			"Offset %d  OFO: %d    Data at %p  SRC at %p memberdata at %p \n",
			f->offset, AST_FRIENDLY_OFFSET,
			f->data, &msrc, member->framedata 
		    );

	for( count=0; count<f->samples; count++ ) {
    	    ast_log(AST_CONF_DEBUG,
		"DUMP POS %04d VALUE %08d    at %p \n",
		          count, msrc[count], &msrc[count] );
	}
    }
#endif
    return f ;
}