Example #1
0
int main(int argc, char **argv)
{
    codec_register_all();

    struct codec_packet pkt;
    struct codec_frame frame;

    // decoder test
    struct codec_para para;
    para.media_format = CODEC_MEDIA_FORMAT_H264;
    para.is_encoder = 0;
    para.media_type = CODEC_MEDIA_TYPE_VIDEO;
    para.width = 1280;
    para.height = 720;
    struct codec_context *codec = codec_create(&para);
    codec_destroy(codec);

    // video encoder test
    memset(&para, 0, sizeof(struct codec_para));
    para.media_format = CODEC_MEDIA_FORMAT_H264;
    para.is_encoder = 1;
    para.media_type = CODEC_MEDIA_TYPE_VIDEO;
    para.width = 1280;
    para.height = 720;
    codec = codec_create(&para);
    pkt.data = (uint8_t *)malloc(1280 * 720 * 4);
    frame.key = 1;
    frame.data = (uint8_t *)malloc(1280 * 720 * 4);
    memset(frame.data, 256, 1000);
    codec_encode_frame(codec, &pkt, &frame);
    codec_destroy(codec);
    free(pkt.data);
    free(frame.data);

    // audio Encoder test
    memset(&para, 0, sizeof(struct codec_para));
    para.media_format = CODEC_MEDIA_FORMAT_AAC;
    para.is_encoder = 1;
    para.media_type = CODEC_MEDIA_TYPE_AUDIO;
    para.samplerate = 44100;
    para.channels = 2;
    codec = codec_create(&para);
    pkt.data = (uint8_t *)malloc(1280 * 720 * 4);
    pkt.size = 1280 * 720 * 4;
    frame.key = 1;
    frame.data = (uint8_t *)malloc(1280 * 720 * 4);
    frame.size = 44100*2;
    frame.nb_samples = 44100;
    codec_encode_frame(codec, &pkt, &frame);
    codec_destroy(codec);
    free(pkt.data);
    free(frame.data);

    return 0;
}
Example #2
0
void xiph_destroy (demux_t *demux, void *data)
{
    rtp_xiph_t *self = (rtp_xiph_t *)data;			// sunqueen modify

    if (!data)
        return;
    if (self->block)
    {
        self->block->i_flags |= BLOCK_FLAG_CORRUPTED;
        codec_decode (demux, self->id, self->block);
    }
    codec_destroy (demux, self->id);
    free (self);
}
Example #3
0
void xiph_decode (demux_t *demux, void *data, block_t *block)
{
    rtp_xiph_t *self = (rtp_xiph_t *)data;			// sunqueen modify

    if (!data || block->i_buffer < 4)
        goto drop;

    /* 32-bits RTP header (§2.2) */
    uint32_t ident = GetDWBE (block->p_buffer);
    block->i_buffer -= 4;
    block->p_buffer += 4;

    unsigned fragtype = (ident >> 6) & 3;
    unsigned datatype = (ident >> 4) & 3;
    unsigned pkts = (ident) & 15;
    ident >>= 8;

    /* RTP defragmentation */
    if (self->block && (block->i_flags & BLOCK_FLAG_DISCONTINUITY))
    {   /* Screwed! discontinuity within a fragmented packet */
        msg_Warn (demux, self->vorbis ?
                  "discontinuity in fragmented Vorbis packet" :
                  "discontinuity in fragmented Theora packet");
        block_Release (self->block);
        self->block = NULL;
    }

    if (fragtype <= 1)
    {
        if (self->block) /* Invalid first fragment */
        {
            block_Release (self->block);
            self->block = NULL;
        }
    }
    else
    {
        if (!self->block)
            goto drop; /* Invalid non-first fragment */
    }

    if (fragtype > 0)
    {   /* Fragment */
        if (pkts > 0 || block->i_buffer < 2)
            goto drop;

        size_t fraglen = GetWBE (block->p_buffer);
        if (block->i_buffer < (fraglen + 2))
            goto drop; /* Invalid payload length */
        block->i_buffer = fraglen;
        if (fragtype == 1)/* Keep first fragment */
        {
            block->i_buffer += 2;
            self->block = block;
        }
        else
        {   /* Append non-first fragment */
            size_t len = self->block->i_buffer;
            self->block = block_Realloc (self->block, 0, len + fraglen);
            if (!self->block)
            {
                block_Release (block);
                return;
            }
            memcpy (self->block->p_buffer + len, block->p_buffer + 2,
                    fraglen);
            block_Release (block);
        }
        if (fragtype < 3)
            return; /* Non-last fragment */

        /* Last fragment reached, process it */
        block = self->block;
        self->block = NULL;
        SetWBE (block->p_buffer, block->i_buffer - 2);
        pkts = 1;
    }

    /* RTP payload packets processing */
    while (pkts > 0)
    {
        if (block->i_buffer < 2)
            goto drop;

        size_t len = GetWBE (block->p_buffer);
        block->i_buffer -= 2;
        block->p_buffer += 2;
        if (block->i_buffer < len)
            goto drop;

        switch (datatype)
        {
            case 0: /* Raw payload */
            {
                if (self->ident != ident)
                {
                    msg_Warn (demux, self->vorbis ?
                        "ignoring raw Vorbis payload without configuration" :
                        "ignoring raw Theora payload without configuration");
                    break;
                }
                block_t *raw = block_Alloc (len);
                memcpy (raw->p_buffer, block->p_buffer, len);
                raw->i_pts = block->i_pts; /* FIXME: what about pkts > 1 */
                codec_decode (demux, self->id, raw);
                break;
            }

            case 1: /* Packed configuration frame (§3.1.1) */
            {
                if (self->ident == ident)
                    break; /* Ignore config retransmission */

                void *extv;
                ssize_t extc = xiph_header (&extv, block->p_buffer, len);
                if (extc < 0)
                    break;

                es_format_t fmt;
                es_format_Init (&fmt, self->vorbis ? AUDIO_ES : VIDEO_ES,
                                self->vorbis ? VLC_CODEC_VORBIS
                                             : VLC_CODEC_THEORA);
                fmt.p_extra = extv;
                fmt.i_extra = extc;
                codec_destroy (demux, self->id);
                msg_Dbg (demux, self->vorbis ?
                         "Vorbis packed configuration received (%06"PRIx32")" :
                         "Theora packed configuration received (%06"PRIx32")",
                         ident);
                self->ident = ident;
                self->id = (es_out_id_t *)codec_init (demux, &fmt);			// sunqueen modify
                break;
            }
        }

        block->i_buffer -= len;
        block->p_buffer += len;
        pkts--;
    }

drop:
    block_Release (block);
}
Example #4
0
static void iaxc_handle_connect(struct iax_event * e)
{
#ifdef USE_VIDEO
	int video_format_capability;
	int video_format_preferred;
#endif
	int video_format = 0;
	int format = 0;
	int callno;

	callno = iaxc_first_free_call();

	if ( callno < 0 )
	{
		iaxci_usermsg(IAXC_STATUS,
				"%i \n Incoming Call, but no appearances",
				callno);
		// XXX Reject this call!, or just ignore?
		//iax_reject(e->session, "Too many calls, we're busy!");
		iax_accept(e->session, audio_format_preferred & e->ies.capability);
		iax_busy(e->session);
		return;
	}

	/* negotiate codec */
	/* first, try _their_ preferred format */
	format = audio_format_capability & e->ies.format;
	if ( !format )
	{
		/* then, try our preferred format */
		format = audio_format_preferred & e->ies.capability;
	}

	if ( !format )
	{
		/* finally, see if we have one in common */
		format = audio_format_capability & e->ies.capability;

		/* now choose amongst these, if we got one */
		if ( format )
		{
			format = iaxc_choose_codec(format);
		}
	}

	if ( !format )
	{
		iax_reject(e->session, "Could not negotiate common codec");
		return;
	}

#ifdef USE_VIDEO
	iaxc_video_format_get_cap(&video_format_preferred,
			&video_format_capability);

	/* first, see if they even want video */
	video_format = (e->ies.format & IAXC_VIDEO_FORMAT_MASK);

	if ( video_format )
	{
		/* next, try _their_ preferred format */
		video_format &= video_format_capability;

		if ( !video_format )
		{
			/* then, try our preferred format */
			video_format = video_format_preferred &
				(e->ies.capability & IAXC_VIDEO_FORMAT_MASK);
		}

		if ( !video_format )
		{
			/* finally, see if we have one in common */
			video_format = video_format_capability &
				(e->ies.capability & IAXC_VIDEO_FORMAT_MASK);

			/* now choose amongst these, if we got one */
			if ( video_format )
			{
				video_format = iaxc_choose_codec(video_format);
			}
		}

		/* All video negotiations failed, then warn */
		if ( !video_format )
		{
			iaxci_usermsg(IAXC_NOTICE,
					"Notice: could not negotiate common video codec");
			iaxci_usermsg(IAXC_NOTICE,
					"Notice: switching to audio-only call");
		}
	}
#endif	/* USE_VIDEO */

	calls[callno].vformat = video_format;
	calls[callno].format = format;

	if ( e->ies.called_number )
		strncpy(calls[callno].local, e->ies.called_number,
				IAXC_EVENT_BUFSIZ);
	else
		strncpy(calls[callno].local, "unknown",
				IAXC_EVENT_BUFSIZ);

	if ( e->ies.called_context )
		strncpy(calls[callno].local_context, e->ies.called_context,
				IAXC_EVENT_BUFSIZ);
	else
		strncpy(calls[callno].local_context, "",
				IAXC_EVENT_BUFSIZ);

	if ( e->ies.calling_number )
		strncpy(calls[callno].remote, e->ies.calling_number,
				IAXC_EVENT_BUFSIZ);
	else
		strncpy(calls[callno].remote, "unknown",
				IAXC_EVENT_BUFSIZ);

	if ( e->ies.calling_name )
		strncpy(calls[callno].remote_name, e->ies.calling_name,
				IAXC_EVENT_BUFSIZ);
	else
		strncpy(calls[callno].remote_name, "unknown",
				IAXC_EVENT_BUFSIZ);

	iaxc_note_activity(callno);
	iaxci_usermsg(IAXC_STATUS, "Call from (%s)", calls[callno].remote);

	codec_destroy( callno );

	calls[callno].session = e->session;
	calls[callno].state = IAXC_CALL_STATE_ACTIVE|IAXC_CALL_STATE_RINGING;

	iax_accept(calls[callno].session, format | video_format);
	iax_ring_announce(calls[callno].session);

	iaxci_do_state_callback(callno);

	iaxci_usermsg(IAXC_STATUS, "Incoming call on line %d", callno);
}
Example #5
0
EXPORT int iaxc_call_ex(const char *num, const char* callerid_name, const char* callerid_number, int video)
{
	int video_format_capability = 0;
	int video_format_preferred = 0;
	int callNo = -1;
	struct iax_session *newsession;
	char *ext = strstr(num, "/");

	get_iaxc_lock();

	// if no call is selected, get a new appearance
	if ( selected_call < 0 )
	{
		callNo = iaxc_first_free_call();
	} else
	{
		// use selected call if not active, otherwise, get a new appearance
		if ( calls[selected_call].state  & IAXC_CALL_STATE_ACTIVE )
		{
			callNo = iaxc_first_free_call();
		} else
		{
			callNo = selected_call;
		}
	}

	if ( callNo < 0 )
	{
		iaxci_usermsg(IAXC_STATUS, "No free call appearances");
		goto iaxc_call_bail;
	}

	newsession = iax_session_new();
	if ( !newsession )
	{
		iaxci_usermsg(IAXC_ERROR, "Can't make new session");
		goto iaxc_call_bail;
	}

	calls[callNo].session = newsession;

	codec_destroy( callNo );

	if ( ext )
	{
		strncpy(calls[callNo].remote_name, num, IAXC_EVENT_BUFSIZ);
		strncpy(calls[callNo].remote,    ++ext, IAXC_EVENT_BUFSIZ);
	} else
	{
		strncpy(calls[callNo].remote_name, num, IAXC_EVENT_BUFSIZ);
		strncpy(calls[callNo].remote,      "" , IAXC_EVENT_BUFSIZ);
	}

	if ( callerid_number != NULL )
		strncpy(calls[callNo].callerid_number, callerid_number, IAXC_EVENT_BUFSIZ);

	if ( callerid_name != NULL )
		strncpy(calls[callNo].callerid_name, callerid_name, IAXC_EVENT_BUFSIZ);

	strncpy(calls[callNo].local        , calls[callNo].callerid_name, IAXC_EVENT_BUFSIZ);
	strncpy(calls[callNo].local_context, "default", IAXC_EVENT_BUFSIZ);

	calls[callNo].state = IAXC_CALL_STATE_ACTIVE | IAXC_CALL_STATE_OUTGOING;

	/* reset activity and ping "timers" */
	iaxc_note_activity(callNo);
	calls[callNo].last_ping = calls[callNo].last_activity;

#ifdef USE_VIDEO
	if ( video )
		iaxc_video_format_get_cap(&video_format_preferred, &video_format_capability);
#endif

	iaxci_usermsg(IAXC_NOTICE, "Originating an %s call",
			video_format_preferred ? "audio+video" : "audio only");
	iax_call(calls[callNo].session, calls[callNo].callerid_number,
			calls[callNo].callerid_name, num, NULL, 0,
			audio_format_preferred | video_format_preferred,
			audio_format_capability | video_format_capability);

	// does state stuff also
	iaxc_select_call(callNo);

iaxc_call_bail:
	put_iaxc_lock();

	return callNo;
}
Example #6
0
EXPORT int iaxc_call_ex(const char *num, const char* callerid_name, const char* callerid_number, int video)
{
	int video_format_capability = 0;
	int video_format_preferred = 0;
	int callNo = -1;
	struct iax_session *newsession;
	char *ext = strstr(num, "/");

	get_iaxc_lock();

	// if no call is selected, get a new appearance
	if ( selected_call < 0 )
	{
		callNo = iaxc_first_free_call();
	} else
	{
		// use selected call if not active, otherwise, get a new appearance
		if ( calls[selected_call].state & IAXC_CALL_STATE_ACTIVE )
		{
			callNo = iaxc_first_free_call();
		} else
		{
			callNo = selected_call;
		}
	}

	if ( callNo < 0 )
	{
		iaxci_usermsg(IAXC_STATUS, "No free call appearances");
		goto iaxc_call_bail;
	}

	newsession = iax_session_new();
	if ( !newsession )
	{
		iaxci_usermsg(IAXC_ERROR, "Can't make new session");
		goto iaxc_call_bail;
	}

	calls[callNo].session = newsession;

	codec_destroy( callNo );

	/* When the ACCEPT comes back from the other-end, these formats
	 * are set. Whether the format is set or not determines whether
	 * we are in the Linked state (see the iax2 rfc).
	 * These will have already been cleared by iaxc_clear_call(),
	 * but we reset them anyway just to be pedantic.
	 */
	calls[callNo].format = 0;
	calls[callNo].vformat = 0;

	if ( ext )
	{
		strncpy(calls[callNo].remote_name, num, IAXC_EVENT_BUFSIZ);
		strncpy(calls[callNo].remote,    ++ext, IAXC_EVENT_BUFSIZ);
	} else
	{
		strncpy(calls[callNo].remote_name, num, IAXC_EVENT_BUFSIZ);
		strncpy(calls[callNo].remote,      "" , IAXC_EVENT_BUFSIZ);
	}

	if ( callerid_number != NULL )
		strncpy(calls[callNo].callerid_number, callerid_number, IAXC_EVENT_BUFSIZ);

	if ( callerid_name != NULL )
		strncpy(calls[callNo].callerid_name, callerid_name, IAXC_EVENT_BUFSIZ);

	strncpy(calls[callNo].local        , calls[callNo].callerid_name, IAXC_EVENT_BUFSIZ);
	strncpy(calls[callNo].local_context, "default", IAXC_EVENT_BUFSIZ);

	calls[callNo].state = IAXC_CALL_STATE_OUTGOING;

	/* reset activity and ping "timers" */
	iaxc_note_activity(callNo);
	calls[callNo].last_ping = calls[callNo].last_activity;

#ifdef USE_VIDEO
	if ( video )
		iaxc_video_format_get_cap(&video_format_preferred, &video_format_capability);
#endif

	iaxci_usermsg(IAXC_NOTICE, "Originating an %s call",
			video_format_preferred ? "audio+video" : "audio only");
	iax_call(calls[callNo].session, calls[callNo].callerid_number,
			calls[callNo].callerid_name, num, NULL, 0,
			audio_format_preferred | video_format_preferred,
			audio_format_capability | video_format_capability);

	// does state stuff also
	iaxc_select_call(callNo);

iaxc_call_bail:
	put_iaxc_lock();

	return callNo;
}