Пример #1
0
static int flv_read_header(AVFormatContext *s)
{
    int offset, flags;

    avio_skip(s->pb, 4);
    flags = avio_r8(s->pb);
    /* old flvtool cleared this field */
    /* FIXME: better fix needed */
    if (!flags) {
        flags = FLV_HEADER_FLAG_HASVIDEO | FLV_HEADER_FLAG_HASAUDIO;
        av_log(s, AV_LOG_WARNING, "Broken FLV file, which says no streams present, this might fail\n");
    }
    s->ctx_flags |= AVFMTCTX_NOHEADER;

    if(flags & FLV_HEADER_FLAG_HASVIDEO) {
        if(!create_stream(s, 0, AVMEDIA_TYPE_VIDEO))
            return AVERROR(ENOMEM);
    }
    if(flags & FLV_HEADER_FLAG_HASAUDIO) {
        if(!create_stream(s, 1, AVMEDIA_TYPE_AUDIO))
            return AVERROR(ENOMEM);
    }
    // Flag doesn't indicate whether or not there is script-data present. Must
    // create that stream if it's encountered.

    offset = avio_rb32(s->pb);
    avio_seek(s->pb, offset, SEEK_SET);
    avio_skip(s->pb, 4);

    s->start_time = 0;

    return 0;
}
Пример #2
0
void do_test_serializing_tls(int index)
{
  char sbuffer[128*1024]; // server buffer
  char cbuffer[128*1024]; // client buffer
  printf(">>> Performing serialization / deserialization\n");
  // 1. serialize TLS, destroy streams
  const size_t sbytes =
      server_test.stream->serialize_to(sbuffer, sizeof(sbuffer));
  assert(sbytes > 0 && "Its only failed if it returned zero");
  const size_t cbytes =
      client_test.stream->serialize_to(cbuffer, sizeof(cbuffer));
  assert(cbytes > 0 && "Its only failed if it returned zero");

  // 2. deserialize TLS, create new streams
  //printf("Now deserializing TLS state\n");

  // 2.1: create new transport streams
  auto server_side = create_stream(&ossl_fuzz_ptr);
  s2n_fuzz_ptr = server_side.get();
  auto client_side = create_stream(&s2n_fuzz_ptr);
  ossl_fuzz_ptr = client_side.get();

  // 2.2: deserialize TLS config/context
  s2n::serial_free_config();
  do_trash_memory();
  s2n::serial_create_config();

  // 2.3: deserialize TLS streams
  // 2.3.1:
  auto dstream = s2n::TLS_stream::deserialize_from(
                  s2n::serial_get_config(),
                  std::move(server_side),
                  false,
                  sbuffer, sbytes
                );
  assert(dstream != nullptr && "Deserialization must return stream");
  server_test.stream = dstream.release();

  dstream = s2n::TLS_stream::deserialize_from(
                  s2n::serial_get_config(),
                  std::move(client_side),
                  false,
                  cbuffer, cbytes
                );
  assert(dstream != nullptr && "Deserialization must return stream");
  client_test.stream = dstream.release();

  // 3. set all delegates again
  server_test.setup_callbacks();
  client_test.setup_callbacks();
}
Пример #3
0
void Service::start()
{
  printf("Service::start()\n");
  fs::memdisk().init_fs(
  [] (fs::error_t err, fs::File_system&) {
    assert(!err);
  });

  auto& filesys = fs::memdisk().fs();
  auto ca_cert = filesys.read_file("/test.pem");
  assert(ca_cert.is_valid());
  auto ca_key  = filesys.read_file("/test.key");
  assert(ca_key.is_valid());
  auto srv_key = filesys.read_file("/server.key");
  assert(srv_key.is_valid());
  printf("*** Loaded certificates and keys\n");

  // initialize S2N and store the certificate/key pair
  printf("*** Initializing S2N\n");
  s2n::serial_test(ca_cert.to_string(), ca_key.to_string());
  printf("*** Create S2N configuration\n");
  s2n::serial_create_config();

  printf("*** Create fuzzy S2N streams\n");
  // server fuzzy stream
  auto server_side = create_stream(&ossl_fuzz_ptr);
  s2n_fuzz_ptr = server_side.get();
  printf("*** - 1. server-side created\n");
  // client fuzzy stream
  auto client_side = create_stream(&s2n_fuzz_ptr);
  ossl_fuzz_ptr = client_side.get();
  printf("*** - 2. client-side created\n");

  server_test.index = 0;
  server_test.stream =
    new s2n::TLS_stream(s2n::serial_get_config(), std::move(server_side), false);
  client_test.index = 1;
  client_test.stream =
    new s2n::TLS_stream(s2n::serial_get_config(), std::move(client_side), true);

  server_test.setup_callbacks();
  client_test.setup_callbacks();
  printf("* TLS streams created!\n");

  // try serializing and deserializing just after creation
  printf("*** Starting test...\n");
  do_test_serializing_tls(0);
}
Пример #4
0
/*
 * Add a stream to the list.
 */
int find_stream(int addr, int ts, int next, int m)
{
    stream *element;
    /* packet belongs to the last seen stream */
    if ((last!=NULL)&&(addr==last->addr)) {
        last->seq+=1;
        if (ts != last->next_ts && !m)
            last->seq+=1;   /* approximate missing some packets */
        last->next_ts = next;
        return(last->seq);
    }
    if((middle!=NULL)&&(addr>=middle->addr))
        element=middle;
    else
        element=head;
    for(; (element!=NULL)&&(element->addr<=addr); element=element->next) {
        if(element->addr==addr) {
            element->seq+=1;
            if (ts != element->next_ts && !m)
                element->seq += 1;  /* approximate missing some packets */
            element->next_ts = next;
            return (element->seq);
        }
    }
    return(create_stream(addr, next));
}
Пример #5
0
void create_memory_stream(struct memory_stream_t **memory_stream_pointer) {
    /* calculates the size of the memory stream structure and
    then uses this value to allocate  */
    size_t memory_stream_size = sizeof(struct memory_stream_t);
    struct memory_stream_t *memory_stream =\
        (struct memory_stream_t *) MALLOC(memory_stream_size);

    /* creates the stream (structure) and sets the
    current memory stream as the lower substrate */
    create_stream(&memory_stream->stream);
    memory_stream->stream->lower = (void *) memory_stream;

    /* sets the memory parameters in the memory stream, the values
    are set with the original (unset) values */
    memory_stream->buffer = NULL;
    memory_stream->buffer_size = 0;
    memory_stream->size = 0;
    memory_stream->position = 0;

    /* sets the various functions of the stream */
    memory_stream->stream->open = open_memory_stream;
    memory_stream->stream->close = close_memory_stream;
    memory_stream->stream->read = read_memory_stream;
    memory_stream->stream->write = write_memory_stream;
    memory_stream->stream->flush = flush_memory_stream;
    memory_stream->stream->seek = seek_memory_stream;
    memory_stream->stream->size = size_memory_stream;
    memory_stream->stream->tell = tell_memory_stream;

    /* sets the memory stream in the memory stream pointer */
    *memory_stream_pointer = memory_stream;
}
Пример #6
0
void process_tcp_packet(struct packet * pkt) {
  struct stream * s;
  /* does a stream already exist? */
  if ((s = find_stream(pkt->ip_header->ip_src,pkt->tcp_header->th_sport,pkt->ip_header->ip_dst,pkt->tcp_header->th_dport))==NULL) {
    /* no -> create one */
    s = create_stream(pkt->ip_header->ip_src,pkt->tcp_header->th_sport,pkt->ip_header->ip_dst,pkt->tcp_header->th_dport);
    /* set a module for the newly created stream */
    set_tcp_module(s,find_tcp_module(pkt->ip_header->ip_src,pkt->tcp_header->th_sport,pkt->ip_header->ip_dst,pkt->tcp_header->th_dport));
  }

  if (!stream_evaluated(s)) {
    stream_add_packet(s,pkt);
    if (stream_client_closed(s) && stream_server_closed(s)) {
      stream_set_bad(s);
    } else {
      stream_try_evaluate(s);
    }

    if (stream_evaluated(s)) {
      stream_output_all(s);
    }

  } else {
    do_output_packet(s,pkt);
  }

  remove_old_streams();
}
Пример #7
0
status_t ocl_engine_t::init() {
    CHECK(cl_engine_t::init());

    cl_int err = CL_SUCCESS;
    if (is_user_context_) {
        err = clRetainContext(context_);
        if (err != CL_SUCCESS)
            context_ = nullptr;
    } else {
        context_
                = clCreateContext(nullptr, 1, &device_, nullptr, nullptr, &err);
    }

    OCL_CHECK(err);

    status_t status
            = ocl_utils::check_device(engine_kind::gpu, device_, context_);
    if (status != status::success)
        return status;

    stream_t *service_stream_ptr;
    status = create_stream(&service_stream_ptr, stream_flags::default_flags);
    if (status != status::success)
        return status;
    service_stream_.reset(service_stream_ptr);
    return status::success;
}
Пример #8
0
/* Function: alureBufferDataFromMemory
 *
 * Loads a file image from memory into an existing OpenAL buffer object,
 * similar to alureBufferDataFromFile. Requires an active context.
 *
 * Returns:
 * AL_FALSE on error.
 *
 * See Also:
 * <alureCreateBufferFromMemory>
 */
ALURE_API ALboolean ALURE_APIENTRY alureBufferDataFromMemory(const ALubyte *fdata, ALsizei length, ALuint buffer)
{
    if(alGetError() != AL_NO_ERROR)
    {
        SetError("Existing OpenAL error");
        return AL_FALSE;
    }

    if(!buffer || !alIsBuffer(buffer))
    {
        SetError("Invalid buffer ID");
        return false;
    }

    if(length < 0)
    {
        SetError("Invalid data length");
        return AL_FALSE;
    }

    MemDataInfo memData;
    memData.Data = fdata;
    memData.Length = length;
    memData.Pos = 0;

    if(load_stream(create_stream(memData), buffer) == false)
        return AL_FALSE;
    return AL_TRUE;
}
Пример #9
0
static int flv_data_packet(AVFormatContext *s, AVPacket *pkt,
                           int64_t dts, int64_t next)
{
    int ret = AVERROR_INVALIDDATA, i;
    AVIOContext *pb = s->pb;
    AVStream *st = NULL;
    AMFDataType type;
    char buf[20];
    int length;

    type = avio_r8(pb);
    if (type == AMF_DATA_TYPE_MIXEDARRAY)
        avio_seek(pb, 4, SEEK_CUR);
    else if (type != AMF_DATA_TYPE_OBJECT)
        goto out;

    amf_get_string(pb, buf, sizeof(buf));
    if (strcmp(buf, "type") || avio_r8(pb) != AMF_DATA_TYPE_STRING)
        goto out;

    amf_get_string(pb, buf, sizeof(buf));
    //FIXME parse it as codec_id
    amf_get_string(pb, buf, sizeof(buf));
    if (strcmp(buf, "text") || avio_r8(pb) != AMF_DATA_TYPE_STRING)
        goto out;

    length = avio_rb16(pb);
    ret = av_get_packet(s->pb, pkt, length);
    if (ret < 0) {
        ret = AVERROR(EIO);
        goto out;
    }

    for (i = 0; i < s->nb_streams; i++) {
        st = s->streams[i];
        if (st->id == 2)
            break;
    }

    if (i == s->nb_streams) {
        st = create_stream(s, 2, AVMEDIA_TYPE_DATA);
        if (!st)
            goto out;
        st->codec->codec_id = CODEC_ID_TEXT;
    }

    pkt->dts  = dts;
    pkt->pts  = dts;
    pkt->size = ret;

    pkt->stream_index = st->index;
    pkt->flags |= AV_PKT_FLAG_KEY;

    avio_seek(s->pb, next + 4, SEEK_SET);
out:
    return ret;
}
Пример #10
0
 stream(pluginservice_proxy& pluginService,
        astra_streamset_t streamSet,
        stream_description description)
     : pluginService_(pluginService),
       streamSet_(streamSet),
       description_(description)
 {
     create_stream(description);
 }
Пример #11
0
static void test_create_reader(void)
{
    HRESULT hr;
    IWICComponentFactory *factory;
    IStream *stream;
    IWICMetadataReader *reader;
    UINT count=0;
    GUID format;

    hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER,
        &IID_IWICComponentFactory, (void**)&factory);
    todo_wine ok(hr == S_OK, "CoCreateInstance failed, hr=%x\n", hr);
    if (FAILED(hr)) return;

    stream = create_stream(metadata_tEXt, sizeof(metadata_tEXt));

    hr = IWICComponentFactory_CreateMetadataReaderFromContainer(factory,
        &GUID_ContainerFormatPng, NULL, WICPersistOptionsDefault,
        stream, &reader);
    ok(hr == S_OK, "CreateMetadataReaderFromContainer failed, hr=%x\n", hr);

    if (SUCCEEDED(hr))
    {
        hr = IWICMetadataReader_GetCount(reader, &count);
        ok(hr == S_OK, "GetCount failed, hr=%x\n", hr);
        ok(count == 1, "unexpected count %i\n", count);

        hr = IWICMetadataReader_GetMetadataFormat(reader, &format);
        ok(hr == S_OK, "GetMetadataFormat failed, hr=%x\n", hr);
        ok(IsEqualGUID(&format, &GUID_MetadataFormatChunktEXt), "unexpected format %s\n", debugstr_guid(&format));

        IWICMetadataReader_Release(reader);
    }

    hr = IWICComponentFactory_CreateMetadataReaderFromContainer(factory,
        &GUID_ContainerFormatWmp, NULL, WICPersistOptionsDefault,
        stream, &reader);
    ok(hr == S_OK, "CreateMetadataReaderFromContainer failed, hr=%x\n", hr);

    if (SUCCEEDED(hr))
    {
        hr = IWICMetadataReader_GetCount(reader, &count);
        ok(hr == S_OK, "GetCount failed, hr=%x\n", hr);
        ok(count == 1, "unexpected count %i\n", count);

        hr = IWICMetadataReader_GetMetadataFormat(reader, &format);
        ok(hr == S_OK, "GetMetadataFormat failed, hr=%x\n", hr);
        ok(IsEqualGUID(&format, &GUID_MetadataFormatUnknown), "unexpected format %s\n", debugstr_guid(&format));

        IWICMetadataReader_Release(reader);
    }

    IStream_Release(stream);

    IWICComponentFactory_Release(factory);
}
Пример #12
0
Файл: ps2.c Проект: sjrct/Frosk
// device should be disabled
static void detect_device(uint port, uchar enable, uchar test, uchar mask)
{
	ps2_device * ps2d;
	uchar check = 0;
	ushort type = 0;

	if (get_config() & mask) {
		outb(PS2_CMND, enable);

		if (!(get_config() & mask)) {
			outb(PS2_CMND, test);
			do_assert(wait_read());

			if (!inb(PS2_DATA)) {
				ps2_command(port, 0xFF, &check, 1);

				if (check == 0xAA) {
					ps2_command(port, 0xF5, NULL, 0);
					ps2_command(port, 0xF2, (uchar *)(&type), 2);

					if (type == PS2_NO_DEVICE) {
						type = PS2_KB_NORMAL;
					}

					if (type == PS2_KB_NORMAL || type == PS2_KB_MF2) {
						ps2_devs[port] = create_stream(
								sizeof(unsigned),
								ps2_kb_enable,
								ps2_kb_disable,
								ps2_kb_read,
								NULL
						);

						ps2d = kalloc(sizeof(ps2_device));
						ps2d->type = type;
						ps2d->port = port;
						ps2_devs[port]->data = ps2d;

						reg_dev(DEVICE_INPUT, ps2_devs[port]->hndl);
						enable_device(ps2_devs[port]);
					} else {
						ps2_devs[port] = NULL; //TODO: implement
					}

					kprintf("PS/2 Device %x detected.\n", type);
				}
			} else {
				outb(PS2_CMND, enable - 1);
			}
		}
	}
}
Пример #13
0
static void add_content(GMimeContentEncoding en, const gchar* fn, GMimePart* pt)
{
    GMimeStream* st = create_stream(en, fn);

    if ( pt ) {
        GMimeDataWrapper* co = g_mime_data_wrapper_new_with_stream(st, en);

        g_mime_data_wrapper_set_encoding(co, en);
        g_mime_part_set_content_object(pt, co);
        g_object_unref(co);
    }

    g_object_unref(st);
}
Пример #14
0
/* Function: alureBufferDataFromFile
 *
 * Loads the given file into an existing OpenAL buffer object. The previous
 * contents of the buffer are replaced. Requires an active context.
 *
 * Returns:
 * AL_FALSE on error.
 *
 * See Also:
 * <alureCreateBufferFromFile>
 */
ALURE_API ALboolean ALURE_APIENTRY alureBufferDataFromFile(const ALchar *fname, ALuint buffer)
{
    if(alGetError() != AL_NO_ERROR)
    {
        SetError("Existing OpenAL error");
        return AL_FALSE;
    }

    if(!buffer || !alIsBuffer(buffer))
    {
        SetError("Invalid buffer ID");
        return false;
    }

    if(load_stream(create_stream(fname), buffer) == false)
        return AL_FALSE;
    return AL_TRUE;
}
Пример #15
0
static void load_stream(IUnknown *reader, const char *data, int data_size)
{
    HRESULT hr;
    IWICPersistStream *persist;
    IStream *stream;

    stream = create_stream(data, data_size);
    if (!stream)
        return;

    hr = IUnknown_QueryInterface(reader, &IID_IWICPersistStream, (void**)&persist);
    ok(hr == S_OK, "QueryInterface failed, hr=%x\n", hr);

    if (SUCCEEDED(hr))
    {
        hr = IWICPersistStream_LoadEx(persist, stream, NULL, WICPersistOptionsDefault);
        ok(hr == S_OK, "LoadEx failed, hr=%x\n", hr);

        IWICPersistStream_Release(persist);
    }

    IStream_Release(stream);
}
Пример #16
0
int thread_add(int wfd, int rfd) 
{
    static int i = 0;
    if (i >= wet->evno) {
        log("thread add error, out of bouder\n");
        return -1;
    }
    event_set(&(wet->ev[i].e), wfd, EV_WRITE | EV_PERSIST, event_handler, (void*)&(wet->ev[i]));
    event_base_set(wet->base, &(wet->ev[i].e));
    event_add(&(wet->ev[i].e), 0);
    alloc_buffer(&wet->ev[i].buffer, 4096);
    wet->ev[i].fd = wfd;
    
    struct fdev_t* evs = ret->evs;
    event_set(&evs[i].ev, rfd, EV_READ | EV_PERSIST, revent_handler, (void*)&evs[i]);
    event_base_set(ret->base, &evs[i].ev);
    event_add(&evs[i].ev, 0);
    create_stream(&evs[i].stream, 4096);
    evs[i].stream.fd = rfd;

    ++i;
    return 0;
}
Пример #17
0
int thread_init(int num)
{
    if (cmalloc((void**)&wet, (sizeof(WRITE_EV_THREAD) + num * sizeof(WEVENT_T))) < 0 || wet == NULL) {
        error(EXIT_FAILURE, errno, "not enough memory\n");
        return -1;
    } 
    // wet = (WRITE_EV_THREAD*)cmalloc(sizeof(WRITE_EV_THREAD) + num * sizeof(WEVENT_T));
    wet->base = event_init();
    wet->evno = num;
    wet->st = STAT_READ_MORE;
    memset(&wet->ev, 0, num * sizeof(WEVENT_T));
    create_stream(&wet->stream, 4096 * 1024);
    wet->stream.fd = STDIN_FILENO;

    // ret = (READ_EV_THREAD*)cmalloc(sizeof(READ_EV_THREAD) + num * sizeof(struct fdev_t));
    if (cmalloc((void**)&ret, (sizeof(READ_EV_THREAD) + num * sizeof(struct fdev_t))) < 0 || ret == NULL) {
        error(EXIT_FAILURE, errno, "not enough memory\n");
        return -1;
    }
    ret->base = event_init();
    ret->evno = num;
    return 0;
}
Пример #18
0
/*
 * main()
 */
int main(int argc, char *argv[])
{
    pj_caching_pool cp;
    pjmedia_endpt *med_endpt;
    pj_pool_t *pool;
    pjmedia_vid_stream *stream = NULL;
    pjmedia_port *enc_port, *dec_port;
    pj_status_t status; 

    pjmedia_vid_port *capture=NULL, *renderer=NULL;
    pjmedia_vid_port_param vpp;

#if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0)
    /* SRTP variables */
    pj_bool_t use_srtp = PJ_FALSE;
    char tmp_tx_key[64];
    char tmp_rx_key[64];
    pj_str_t  srtp_tx_key = {NULL, 0};
    pj_str_t  srtp_rx_key = {NULL, 0};
    pj_str_t  srtp_crypto_suite = {NULL, 0};
    int	tmp_key_len;
#endif

    /* Default values */
    const pjmedia_vid_codec_info *codec_info;
    pjmedia_vid_codec_param codec_param;
    pjmedia_dir dir = PJMEDIA_DIR_DECODING;
    pj_sockaddr_in remote_addr;
    pj_uint16_t local_port = 4000;
    char *codec_id = NULL;
    pjmedia_rect_size tx_size = {0};
    pj_int8_t rx_pt = -1, tx_pt = -1;

    play_file_data play_file = { NULL };
    pjmedia_port *play_port = NULL;
    pjmedia_vid_codec *play_decoder = NULL;
    pjmedia_clock *play_clock = NULL;

    enum {
	OPT_CODEC	= 'c',
	OPT_LOCAL_PORT	= 'p',
	OPT_REMOTE	= 'r',
	OPT_PLAY_FILE	= 'f',
	OPT_SEND_RECV	= 'b',
	OPT_SEND_ONLY	= 's',
	OPT_RECV_ONLY	= 'i',
	OPT_SEND_WIDTH	= 'W',
	OPT_SEND_HEIGHT	= 'H',
	OPT_RECV_PT	= 't',
	OPT_SEND_PT	= 'T',
#if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0)
	OPT_USE_SRTP	= 'S',
#endif
	OPT_SRTP_TX_KEY	= 'x',
	OPT_SRTP_RX_KEY	= 'y',
	OPT_HELP	= 'h',
    };

    struct pj_getopt_option long_options[] = {
	{ "codec",	    1, 0, OPT_CODEC },
	{ "local-port",	    1, 0, OPT_LOCAL_PORT },
	{ "remote",	    1, 0, OPT_REMOTE },
	{ "play-file",	    1, 0, OPT_PLAY_FILE },
	{ "send-recv",      0, 0, OPT_SEND_RECV },
	{ "send-only",      0, 0, OPT_SEND_ONLY },
	{ "recv-only",      0, 0, OPT_RECV_ONLY },
	{ "send-width",     1, 0, OPT_SEND_WIDTH },
	{ "send-height",    1, 0, OPT_SEND_HEIGHT },
	{ "recv-pt",        1, 0, OPT_RECV_PT },
	{ "send-pt",        1, 0, OPT_SEND_PT },
#if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0)
	{ "use-srtp",	    2, 0, OPT_USE_SRTP },
	{ "srtp-tx-key",    1, 0, OPT_SRTP_TX_KEY },
	{ "srtp-rx-key",    1, 0, OPT_SRTP_RX_KEY },
#endif
	{ "help",	    0, 0, OPT_HELP },
	{ NULL, 0, 0, 0 },
    };

    int c;
    int option_index;


    pj_bzero(&remote_addr, sizeof(remote_addr));


    /* init PJLIB : */
    status = pj_init();
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);


    /* Parse arguments */
    pj_optind = 0;
    while((c=pj_getopt_long(argc,argv, "h", long_options, &option_index))!=-1)
    {
	switch (c) {
	case OPT_CODEC:
	    codec_id = pj_optarg;
	    break;

	case OPT_LOCAL_PORT:
	    local_port = (pj_uint16_t) atoi(pj_optarg);
	    if (local_port < 1) {
		printf("Error: invalid local port %s\n", pj_optarg);
		return 1;
	    }
	    break;

	case OPT_REMOTE:
	    {
		pj_str_t ip = pj_str(strtok(pj_optarg, ":"));
		pj_uint16_t port = (pj_uint16_t) atoi(strtok(NULL, ":"));

		status = pj_sockaddr_in_init(&remote_addr, &ip, port);
		if (status != PJ_SUCCESS) {
		    app_perror(THIS_FILE, "Invalid remote address", status);
		    return 1;
		}
	    }
	    break;

	case OPT_PLAY_FILE:
	    play_file.file_name = pj_optarg;
	    break;

	case OPT_SEND_RECV:
	    dir = PJMEDIA_DIR_ENCODING_DECODING;
	    break;

	case OPT_SEND_ONLY:
	    dir = PJMEDIA_DIR_ENCODING;
	    break;

	case OPT_RECV_ONLY:
	    dir = PJMEDIA_DIR_DECODING;
	    break;

	case OPT_SEND_WIDTH:
	    tx_size.w = (unsigned)atoi(pj_optarg);
	    break;

	case OPT_SEND_HEIGHT:
	    tx_size.h = (unsigned)atoi(pj_optarg);
	    break;

	case OPT_RECV_PT:
	    rx_pt = (pj_int8_t)atoi(pj_optarg);
	    break;

	case OPT_SEND_PT:
	    tx_pt = (pj_int8_t)atoi(pj_optarg);
	    break;

#if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0)
	case OPT_USE_SRTP:
	    use_srtp = PJ_TRUE;
	    if (pj_optarg) {
		pj_strset(&srtp_crypto_suite, pj_optarg, strlen(pj_optarg));
	    } else {
		srtp_crypto_suite = pj_str("AES_CM_128_HMAC_SHA1_80");
	    }
	    break;

	case OPT_SRTP_TX_KEY:
	    tmp_key_len = hex_string_to_octet_string(tmp_tx_key, pj_optarg, 
						     strlen(pj_optarg));
	    pj_strset(&srtp_tx_key, tmp_tx_key, tmp_key_len/2);
	    break;

	case OPT_SRTP_RX_KEY:
	    tmp_key_len = hex_string_to_octet_string(tmp_rx_key, pj_optarg,
						     strlen(pj_optarg));
	    pj_strset(&srtp_rx_key, tmp_rx_key, tmp_key_len/2);
	    break;
#endif

	case OPT_HELP:
	    usage();
	    return 1;

	default:
	    printf("Invalid options %s\n", argv[pj_optind]);
	    return 1;
	}

    }


    /* Verify arguments. */
    if (dir & PJMEDIA_DIR_ENCODING) {
	if (remote_addr.sin_addr.s_addr == 0) {
	    printf("Error: remote address must be set\n");
	    return 1;
	}
    }

    if (play_file.file_name != NULL && dir != PJMEDIA_DIR_ENCODING) {
	printf("Direction is set to --send-only because of --play-file\n");
	dir = PJMEDIA_DIR_ENCODING;
    }

#if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0)
    /* SRTP validation */
    if (use_srtp) {
	if (!srtp_tx_key.slen || !srtp_rx_key.slen)
	{
	    printf("Error: Key for each SRTP stream direction must be set\n");
	    return 1;
	}
    }
#endif

    /* Must create a pool factory before we can allocate any memory. */
    pj_caching_pool_init(&cp, &pj_pool_factory_default_policy, 0);

    /* 
     * Initialize media endpoint.
     * This will implicitly initialize PJMEDIA too.
     */
    status = pjmedia_endpt_create(&cp.factory, NULL, 1, &med_endpt);
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);

    /* Create memory pool for application purpose */
    pool = pj_pool_create( &cp.factory,	    /* pool factory	    */
			   "app",	    /* pool name.	    */
			   4000,	    /* init size	    */
			   4000,	    /* increment size	    */
			   NULL		    /* callback on error    */
			   );

    /* Init video format manager */
    pjmedia_video_format_mgr_create(pool, 64, 0, NULL);

    /* Init video converter manager */
    pjmedia_converter_mgr_create(pool, NULL);

    /* Init event manager */
    pjmedia_event_mgr_create(pool, 0, NULL);

    /* Init video codec manager */
    pjmedia_vid_codec_mgr_create(pool, NULL);

    /* Init video subsystem */
    pjmedia_vid_dev_subsys_init(&cp.factory);

    /* Register all supported codecs */
    status = init_codecs(&cp.factory);
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);


    /* Find which codec to use. */
    if (codec_id) {
	unsigned count = 1;
	pj_str_t str_codec_id = pj_str(codec_id);

        status = pjmedia_vid_codec_mgr_find_codecs_by_id(NULL,
						         &str_codec_id, &count,
						         &codec_info, NULL);
	if (status != PJ_SUCCESS) {
	    printf("Error: unable to find codec %s\n", codec_id);
	    return 1;
	}
    } else {
        static pjmedia_vid_codec_info info[1];
        unsigned count = PJ_ARRAY_SIZE(info);

	/* Default to first codec */
	pjmedia_vid_codec_mgr_enum_codecs(NULL, &count, info, NULL);
        codec_info = &info[0];
    }

    /* Get codec default param for info */
    status = pjmedia_vid_codec_mgr_get_default_param(NULL, codec_info, 
				                     &codec_param);
    pj_assert(status == PJ_SUCCESS);
    
    /* Set outgoing video size */
    if (tx_size.w && tx_size.h)
        codec_param.enc_fmt.det.vid.size = tx_size;

#if DEF_RENDERER_WIDTH && DEF_RENDERER_HEIGHT
    /* Set incoming video size */
    if (DEF_RENDERER_WIDTH > codec_param.dec_fmt.det.vid.size.w)
	codec_param.dec_fmt.det.vid.size.w = DEF_RENDERER_WIDTH;
    if (DEF_RENDERER_HEIGHT > codec_param.dec_fmt.det.vid.size.h)
	codec_param.dec_fmt.det.vid.size.h = DEF_RENDERER_HEIGHT;
#endif

    if (play_file.file_name) {
	pjmedia_video_format_detail *file_vfd;
        pjmedia_clock_param clock_param;
        char fmt_name[5];

	/* Create file player */
	status = create_file_player(pool, play_file.file_name, &play_port);
	if (status != PJ_SUCCESS)
	    goto on_exit;

	/* Collect format info */
	file_vfd = pjmedia_format_get_video_format_detail(&play_port->info.fmt,
							  PJ_TRUE);
	PJ_LOG(2, (THIS_FILE, "Reading video stream %dx%d %s @%.2ffps",
		   file_vfd->size.w, file_vfd->size.h,
		   pjmedia_fourcc_name(play_port->info.fmt.id, fmt_name),
		   (1.0*file_vfd->fps.num/file_vfd->fps.denum)));

	/* Allocate file read buffer */
	play_file.read_buf_size = PJMEDIA_MAX_VIDEO_ENC_FRAME_SIZE;
	play_file.read_buf = pj_pool_zalloc(pool, play_file.read_buf_size);

	/* Create decoder, if the file and the stream uses different codec */
	if (codec_info->fmt_id != (pjmedia_format_id)play_port->info.fmt.id) {
	    const pjmedia_video_format_info *dec_vfi;
	    pjmedia_video_apply_fmt_param dec_vafp = {0};
	    const pjmedia_vid_codec_info *codec_info2;
	    pjmedia_vid_codec_param codec_param2;

	    /* Find decoder */
	    status = pjmedia_vid_codec_mgr_get_codec_info2(NULL,
							   play_port->info.fmt.id,
							   &codec_info2);
	    if (status != PJ_SUCCESS)
		goto on_exit;

	    /* Init decoder */
	    status = pjmedia_vid_codec_mgr_alloc_codec(NULL, codec_info2,
						       &play_decoder);
	    if (status != PJ_SUCCESS)
		goto on_exit;

	    status = play_decoder->op->init(play_decoder, pool);
	    if (status != PJ_SUCCESS)
		goto on_exit;

	    /* Open decoder */
	    status = pjmedia_vid_codec_mgr_get_default_param(NULL, codec_info2,
							     &codec_param2);
	    if (status != PJ_SUCCESS)
		goto on_exit;

	    codec_param2.dir = PJMEDIA_DIR_DECODING;
	    status = play_decoder->op->open(play_decoder, &codec_param2);
	    if (status != PJ_SUCCESS)
		goto on_exit;

	    /* Get decoder format info and apply param */
	    dec_vfi = pjmedia_get_video_format_info(NULL,
						    codec_info2->dec_fmt_id[0]);
	    if (!dec_vfi || !dec_vfi->apply_fmt) {
		status = PJ_ENOTSUP;
		goto on_exit;
	    }
	    dec_vafp.size = file_vfd->size;
	    (*dec_vfi->apply_fmt)(dec_vfi, &dec_vafp);

	    /* Allocate buffer to receive decoder output */
	    play_file.dec_buf_size = dec_vafp.framebytes;
	    play_file.dec_buf = pj_pool_zalloc(pool, play_file.dec_buf_size);
	}

	/* Create player clock */
        clock_param.usec_interval = PJMEDIA_PTIME(&file_vfd->fps);
        clock_param.clock_rate = codec_info->clock_rate;
	status = pjmedia_clock_create2(pool, &clock_param,
				       PJMEDIA_CLOCK_NO_HIGHEST_PRIO,
				       &clock_cb, &play_file, &play_clock);
	if (status != PJ_SUCCESS)
	    goto on_exit;

	/* Override stream codec param for encoding direction */
	codec_param.enc_fmt.det.vid.size = file_vfd->size;
	codec_param.enc_fmt.det.vid.fps  = file_vfd->fps;

    } else {
        pjmedia_vid_port_param_default(&vpp);

        /* Set as active for all video devices */
        vpp.active = PJ_TRUE;

	/* Create video device port. */
        if (dir & PJMEDIA_DIR_ENCODING) {
            /* Create capture */
            status = pjmedia_vid_dev_default_param(
					pool,
					PJMEDIA_VID_DEFAULT_CAPTURE_DEV,
					&vpp.vidparam);
            if (status != PJ_SUCCESS)
	        goto on_exit;

            pjmedia_format_copy(&vpp.vidparam.fmt, &codec_param.enc_fmt);
	    vpp.vidparam.fmt.id = codec_param.dec_fmt.id;
            vpp.vidparam.dir = PJMEDIA_DIR_CAPTURE;
            
            status = pjmedia_vid_port_create(pool, &vpp, &capture);
            if (status != PJ_SUCCESS)
	        goto on_exit;
        }
	
        if (dir & PJMEDIA_DIR_DECODING) {
            /* Create renderer */
            status = pjmedia_vid_dev_default_param(
					pool,
					PJMEDIA_VID_DEFAULT_RENDER_DEV,
					&vpp.vidparam);
            if (status != PJ_SUCCESS)
	        goto on_exit;

            pjmedia_format_copy(&vpp.vidparam.fmt, &codec_param.dec_fmt);
            vpp.vidparam.dir = PJMEDIA_DIR_RENDER;
            vpp.vidparam.disp_size = vpp.vidparam.fmt.det.vid.size;
	    vpp.vidparam.flags |= PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW_FLAGS;
	    vpp.vidparam.window_flags = PJMEDIA_VID_DEV_WND_BORDER |
					PJMEDIA_VID_DEV_WND_RESIZABLE;

            status = pjmedia_vid_port_create(pool, &vpp, &renderer);
            if (status != PJ_SUCCESS)
	        goto on_exit;
        }
    }

    /* Set to ignore fmtp */
    codec_param.ignore_fmtp = PJ_TRUE;

    /* Create stream based on program arguments */
    status = create_stream(pool, med_endpt, codec_info, &codec_param,
                           dir, rx_pt, tx_pt, local_port, &remote_addr, 
#if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0)
			   use_srtp, &srtp_crypto_suite, 
			   &srtp_tx_key, &srtp_rx_key,
#endif
			   &stream);
    if (status != PJ_SUCCESS)
	goto on_exit;

    /* Get the port interface of the stream */
    status = pjmedia_vid_stream_get_port(stream, PJMEDIA_DIR_ENCODING,
				         &enc_port);
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);

    status = pjmedia_vid_stream_get_port(stream, PJMEDIA_DIR_DECODING,
				         &dec_port);
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);

    /* Start streaming */
    status = pjmedia_vid_stream_start(stream);
    if (status != PJ_SUCCESS)
        goto on_exit;

    /* Start renderer */
    if (renderer) {
        status = pjmedia_vid_port_connect(renderer, dec_port, PJ_FALSE);
        if (status != PJ_SUCCESS)
	    goto on_exit;
        status = pjmedia_vid_port_start(renderer);
        if (status != PJ_SUCCESS)
            goto on_exit;
    }

    /* Start capture */
    if (capture) {
        status = pjmedia_vid_port_connect(capture, enc_port, PJ_FALSE);
        if (status != PJ_SUCCESS)
	    goto on_exit;
        status = pjmedia_vid_port_start(capture);
        if (status != PJ_SUCCESS)
            goto on_exit;
    }

    /* Start playing file */
    if (play_file.file_name) {

#if HAS_LOCAL_RENDERER_FOR_PLAY_FILE
        /* Create local renderer */
        pjmedia_vid_port_param_default(&vpp);
        vpp.active = PJ_FALSE;
        status = pjmedia_vid_dev_default_param(
				pool,
				PJMEDIA_VID_DEFAULT_RENDER_DEV,
				&vpp.vidparam);
        if (status != PJ_SUCCESS)
	    goto on_exit;

        vpp.vidparam.dir = PJMEDIA_DIR_RENDER;
        pjmedia_format_copy(&vpp.vidparam.fmt, &codec_param.dec_fmt);
	vpp.vidparam.fmt.det.vid.size = play_port->info.fmt.det.vid.size;
	vpp.vidparam.fmt.det.vid.fps = play_port->info.fmt.det.vid.fps;
        vpp.vidparam.disp_size = vpp.vidparam.fmt.det.vid.size;

	status = pjmedia_vid_port_create(pool, &vpp, &renderer);
        if (status != PJ_SUCCESS)
	    goto on_exit;
        status = pjmedia_vid_port_start(renderer);
        if (status != PJ_SUCCESS)
            goto on_exit;
#endif

	/* Init play file data */
	play_file.play_port = play_port;
	play_file.stream_port = enc_port;
	play_file.decoder = play_decoder;
	if (renderer) {
	    play_file.renderer = pjmedia_vid_port_get_passive_port(renderer);
	}

	status = pjmedia_clock_start(play_clock);
	if (status != PJ_SUCCESS)
	    goto on_exit;
    }

    /* Done */

    if (dir == PJMEDIA_DIR_DECODING)
	printf("Stream is active, dir is recv-only, local port is %d\n",
	       local_port);
    else if (dir == PJMEDIA_DIR_ENCODING)
	printf("Stream is active, dir is send-only, sending to %s:%d\n",
	       pj_inet_ntoa(remote_addr.sin_addr),
	       pj_ntohs(remote_addr.sin_port));
    else
	printf("Stream is active, send/recv, local port is %d, "
	       "sending to %s:%d\n",
	       local_port,
	       pj_inet_ntoa(remote_addr.sin_addr),
	       pj_ntohs(remote_addr.sin_port));

    if (dir & PJMEDIA_DIR_ENCODING)
	PJ_LOG(2, (THIS_FILE, "Sending %dx%d %.*s @%.2ffps",
		   codec_param.enc_fmt.det.vid.size.w,
		   codec_param.enc_fmt.det.vid.size.h,
		   codec_info->encoding_name.slen,
		   codec_info->encoding_name.ptr,
		   (1.0*codec_param.enc_fmt.det.vid.fps.num/
		    codec_param.enc_fmt.det.vid.fps.denum)));

    for (;;) {
	char tmp[10];

	puts("");
	puts("Commands:");
	puts("  q     Quit");
	puts("");

	printf("Command: "); fflush(stdout);

	if (fgets(tmp, sizeof(tmp), stdin) == NULL) {
	    puts("EOF while reading stdin, will quit now..");
	    break;
	}

	if (tmp[0] == 'q')
	    break;

    }



    /* Start deinitialization: */
on_exit:

    /* Stop and destroy file clock */
    if (play_clock) {
	pjmedia_clock_stop(play_clock);
	pjmedia_clock_destroy(play_clock);
    }

    /* Destroy file reader/player */
    if (play_port)
	pjmedia_port_destroy(play_port);

    /* Destroy file decoder */
    if (play_decoder) {
	play_decoder->op->close(play_decoder);
	pjmedia_vid_codec_mgr_dealloc_codec(NULL, play_decoder);
    }

    /* Destroy video devices */
    if (capture)
	pjmedia_vid_port_destroy(capture);
    if (renderer)
	pjmedia_vid_port_destroy(renderer);

    /* Destroy stream */
    if (stream) {
	pjmedia_transport *tp;

	tp = pjmedia_vid_stream_get_transport(stream);
	pjmedia_vid_stream_destroy(stream);
	
	pjmedia_transport_close(tp);
    }

    /* Deinit codecs */
    deinit_codecs();

    /* Shutdown video subsystem */
    pjmedia_vid_dev_subsys_shutdown();

    /* Destroy event manager */
    pjmedia_event_mgr_destroy(NULL);

    /* Release application pool */
    pj_pool_release( pool );

    /* Destroy media endpoint. */
    pjmedia_endpt_destroy( med_endpt );

    /* Destroy pool factory */
    pj_caching_pool_destroy( &cp );

    /* Shutdown PJLIB */
    pj_shutdown();

    return (status == PJ_SUCCESS) ? 0 : 1;
}
Пример #19
0
static gboolean
perform_step (gpointer pstep)
{
  gint step = GPOINTER_TO_INT (pstep);

  switch (step) {
    case 0:
      /* live stream locks on to running_time, pipeline configures latency. */
      g_print ("creating bin1\n");
      bin1 =
          create_stream
          ("( v4l2src ! ffmpegcolorspace ! timeoverlay ! queue ! xvimagesink name=v4llive )");
      pause_play_stream (bin1, 0);
      g_timeout_add (1000, (GSourceFunc) perform_step, GINT_TO_POINTER (1));
      break;
    case 1:
      /* live stream locks on to running_time, pipeline reconfigures latency
       * together with the previously added bin so that they run synchronized. */
      g_print ("creating bin2\n");
      bin2 = create_stream ("( alsasrc ! queue ! alsasink name=alsalive )");
      pause_play_stream (bin2, 0);
      g_timeout_add (1000, (GSourceFunc) perform_step, GINT_TO_POINTER (2));
      break;
    case 2:
      /* non-live stream, need base_time to align with current running live sources. */
      g_print ("creating bin3\n");
      bin3 = create_stream ("( audiotestsrc ! alsasink name=atnonlive )");
      pause_play_stream (bin3, 0);
      g_timeout_add (1000, (GSourceFunc) perform_step, GINT_TO_POINTER (3));
      break;
    case 3:
      g_print ("creating bin4\n");
      bin4 =
          create_stream
          ("( videotestsrc ! timeoverlay ! ffmpegcolorspace ! ximagesink name=vtnonlive )");
      pause_play_stream (bin4, 0);
      g_timeout_add (1000, (GSourceFunc) perform_step, GINT_TO_POINTER (4));
      break;
    case 4:
      /* live stream locks on to running_time */
      g_print ("creating bin5\n");
      bin5 =
          create_stream
          ("( videotestsrc is-live=1 ! timeoverlay ! ffmpegcolorspace ! ximagesink name=vtlive )");
      pause_play_stream (bin5, 0);
      g_timeout_add (1000, (GSourceFunc) perform_step, GINT_TO_POINTER (5));
      break;
    case 5:
      /* pause the fist live stream for 2 seconds */
      g_print ("PAUSE bin1 for 2 seconds\n");
      pause_play_stream (bin1, 2);
      /* pause the non-live stream for 2 seconds */
      g_print ("PAUSE bin4 for 2 seconds\n");
      pause_play_stream (bin4, 2);
      /* pause the pseudo live stream for 2 seconds */
      g_print ("PAUSE bin5 for 2 seconds\n");
      pause_play_stream (bin5, 2);
      g_print ("Waiting 5 seconds\n");
      g_timeout_add (5000, (GSourceFunc) perform_step, GINT_TO_POINTER (6));
      break;
    case 6:
      g_print ("quiting\n");
      g_main_loop_quit (loop);
      break;
    default:
      break;
  }
  return FALSE;
}
Пример #20
0
/*
 * main()
 */
int main(int argc, char *argv[])
{
    pj_caching_pool cp;
    pjmedia_endpt *med_endpt;
    pj_pool_t *pool;
    pjmedia_port *rec_file_port = NULL, *play_file_port = NULL;
    pjmedia_master_port *master_port = NULL;
    pjmedia_snd_port *snd_port = NULL;
    pjmedia_stream *stream = NULL;
    pjmedia_port *stream_port;
    char tmp[10];
    pj_status_t status; 

#if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0)
    /* SRTP variables */
    pj_bool_t use_srtp = PJ_FALSE;
    char tmp_tx_key[64];
    char tmp_rx_key[64];
    pj_str_t  srtp_tx_key = {NULL, 0};
    pj_str_t  srtp_rx_key = {NULL, 0};
    pj_str_t  srtp_crypto_suite = {NULL, 0};
    int	tmp_key_len;
#endif

    /* Default values */
    const pjmedia_codec_info *codec_info;
    pjmedia_codec_param codec_param;
    pjmedia_dir dir = PJMEDIA_DIR_DECODING;
    pj_sockaddr_in remote_addr;
    pj_uint16_t local_port = 4000;
    char *codec_id = NULL;
    char *rec_file = NULL;
    char *play_file = NULL;

    enum {
	OPT_CODEC	= 'c',
	OPT_LOCAL_PORT	= 'p',
	OPT_REMOTE	= 'r',
	OPT_PLAY_FILE	= 'w',
	OPT_RECORD_FILE	= 'R',
	OPT_SEND_RECV	= 'b',
	OPT_SEND_ONLY	= 's',
	OPT_RECV_ONLY	= 'i',
#if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0)
	OPT_USE_SRTP	= 'S',
#endif
	OPT_SRTP_TX_KEY	= 'x',
	OPT_SRTP_RX_KEY	= 'y',
	OPT_HELP	= 'h',
    };

    struct pj_getopt_option long_options[] = {
	{ "codec",	    1, 0, OPT_CODEC },
	{ "local-port",	    1, 0, OPT_LOCAL_PORT },
	{ "remote",	    1, 0, OPT_REMOTE },
	{ "play-file",	    1, 0, OPT_PLAY_FILE },
	{ "record-file",    1, 0, OPT_RECORD_FILE },
	{ "send-recv",      0, 0, OPT_SEND_RECV },
	{ "send-only",      0, 0, OPT_SEND_ONLY },
	{ "recv-only",      0, 0, OPT_RECV_ONLY },
#if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0)
	{ "use-srtp",	    2, 0, OPT_USE_SRTP },
	{ "srtp-tx-key",    1, 0, OPT_SRTP_TX_KEY },
	{ "srtp-rx-key",    1, 0, OPT_SRTP_RX_KEY },
#endif
	{ "help",	    0, 0, OPT_HELP },
	{ NULL, 0, 0, 0 },
    };

    int c;
    int option_index;


    pj_bzero(&remote_addr, sizeof(remote_addr));


    /* init PJLIB : */
    status = pj_init();
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);


    /* Parse arguments */
    pj_optind = 0;
    while((c=pj_getopt_long(argc,argv, "h", long_options, &option_index))!=-1) {

	switch (c) {
	case OPT_CODEC:
	    codec_id = pj_optarg;
	    break;

	case OPT_LOCAL_PORT:
	    local_port = (pj_uint16_t) atoi(pj_optarg);
	    if (local_port < 1) {
		printf("Error: invalid local port %s\n", pj_optarg);
		return 1;
	    }
	    break;

	case OPT_REMOTE:
	    {
		pj_str_t ip = pj_str(strtok(pj_optarg, ":"));
		pj_uint16_t port = (pj_uint16_t) atoi(strtok(NULL, ":"));

		status = pj_sockaddr_in_init(&remote_addr, &ip, port);
		if (status != PJ_SUCCESS) {
		    app_perror(THIS_FILE, "Invalid remote address", status);
		    return 1;
		}
	    }
	    break;

	case OPT_PLAY_FILE:
	    play_file = pj_optarg;
	    break;

	case OPT_RECORD_FILE:
	    rec_file = pj_optarg;
	    break;

	case OPT_SEND_RECV:
	    dir = PJMEDIA_DIR_ENCODING_DECODING;
	    break;

	case OPT_SEND_ONLY:
	    dir = PJMEDIA_DIR_ENCODING;
	    break;

	case OPT_RECV_ONLY:
	    dir = PJMEDIA_DIR_DECODING;
	    break;

#if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0)
	case OPT_USE_SRTP:
	    use_srtp = PJ_TRUE;
	    if (pj_optarg) {
		pj_strset(&srtp_crypto_suite, pj_optarg, strlen(pj_optarg));
	    } else {
		srtp_crypto_suite = pj_str("AES_CM_128_HMAC_SHA1_80");
	    }
	    break;

	case OPT_SRTP_TX_KEY:
	    tmp_key_len = hex_string_to_octet_string(tmp_tx_key, pj_optarg, 
						     (int)strlen(pj_optarg));
	    pj_strset(&srtp_tx_key, tmp_tx_key, tmp_key_len/2);
	    break;

	case OPT_SRTP_RX_KEY:
	    tmp_key_len = hex_string_to_octet_string(tmp_rx_key, pj_optarg, 
						     (int)strlen(pj_optarg));
	    pj_strset(&srtp_rx_key, tmp_rx_key, tmp_key_len/2);
	    break;
#endif

	case OPT_HELP:
	    usage();
	    return 1;

	default:
	    printf("Invalid options %s\n", argv[pj_optind]);
	    return 1;
	}

    }


    /* Verify arguments. */
    if (dir & PJMEDIA_DIR_ENCODING) {
	if (remote_addr.sin_addr.s_addr == 0) {
	    printf("Error: remote address must be set\n");
	    return 1;
	}
    }

    if (play_file != NULL && dir != PJMEDIA_DIR_ENCODING) {
	printf("Direction is set to --send-only because of --play-file\n");
	dir = PJMEDIA_DIR_ENCODING;
    }

#if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0)
    /* SRTP validation */
    if (use_srtp) {
	if (!srtp_tx_key.slen || !srtp_rx_key.slen)
	{
	    printf("Error: Key for each SRTP stream direction must be set\n");
	    return 1;
	}
    }
#endif

    /* Must create a pool factory before we can allocate any memory. */
    pj_caching_pool_init(&cp, &pj_pool_factory_default_policy, 0);

    /* 
     * Initialize media endpoint.
     * This will implicitly initialize PJMEDIA too.
     */
    status = pjmedia_endpt_create(&cp.factory, NULL, 1, &med_endpt);
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);

    /* Create memory pool for application purpose */
    pool = pj_pool_create( &cp.factory,	    /* pool factory	    */
			   "app",	    /* pool name.	    */
			   4000,	    /* init size	    */
			   4000,	    /* increment size	    */
			   NULL		    /* callback on error    */
			   );


    /* Register all supported codecs */
    status = init_codecs(med_endpt);
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);


    /* Find which codec to use. */
    if (codec_id) {
	unsigned count = 1;
	pj_str_t str_codec_id = pj_str(codec_id);
	pjmedia_codec_mgr *codec_mgr = pjmedia_endpt_get_codec_mgr(med_endpt);
	status = pjmedia_codec_mgr_find_codecs_by_id( codec_mgr,
						      &str_codec_id, &count,
						      &codec_info, NULL);
	if (status != PJ_SUCCESS) {
	    printf("Error: unable to find codec %s\n", codec_id);
	    return 1;
	}
    } else {
	/* Default to pcmu */
	pjmedia_codec_mgr_get_codec_info( pjmedia_endpt_get_codec_mgr(med_endpt),
					  0, &codec_info);
    }

    /* Create stream based on program arguments */
    status = create_stream(pool, med_endpt, codec_info, dir, local_port, 
			   &remote_addr, 
#if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0)
			   use_srtp, &srtp_crypto_suite, 
			   &srtp_tx_key, &srtp_rx_key,
#endif
			   &stream);
    if (status != PJ_SUCCESS)
	goto on_exit;

    /* Get codec default param for info */
    status = pjmedia_codec_mgr_get_default_param(
				    pjmedia_endpt_get_codec_mgr(med_endpt), 
				    codec_info, 
				    &codec_param);
    /* Should be ok, as create_stream() above succeeded */
    pj_assert(status == PJ_SUCCESS);

    /* Get the port interface of the stream */
    status = pjmedia_stream_get_port( stream, &stream_port);
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);


    if (play_file) {
	unsigned wav_ptime;

	wav_ptime = PJMEDIA_PIA_PTIME(&stream_port->info);
	status = pjmedia_wav_player_port_create(pool, play_file, wav_ptime,
						0, -1, &play_file_port);
	if (status != PJ_SUCCESS) {
	    app_perror(THIS_FILE, "Unable to use file", status);
	    goto on_exit;
	}

	status = pjmedia_master_port_create(pool, play_file_port, stream_port,
					    0, &master_port);
	if (status != PJ_SUCCESS) {
	    app_perror(THIS_FILE, "Unable to create master port", status);
	    goto on_exit;
	}

	status = pjmedia_master_port_start(master_port);
	if (status != PJ_SUCCESS) {
	    app_perror(THIS_FILE, "Error starting master port", status);
	    goto on_exit;
	}

	printf("Playing from WAV file %s..\n", play_file);

    } else if (rec_file) {

	status = pjmedia_wav_writer_port_create(pool, rec_file,
					        PJMEDIA_PIA_SRATE(&stream_port->info),
					        PJMEDIA_PIA_CCNT(&stream_port->info),
					        PJMEDIA_PIA_SPF(&stream_port->info),
					        PJMEDIA_PIA_BITS(&stream_port->info),
						0, 0, &rec_file_port);
	if (status != PJ_SUCCESS) {
	    app_perror(THIS_FILE, "Unable to use file", status);
	    goto on_exit;
	}

	status = pjmedia_master_port_create(pool, stream_port, rec_file_port, 
					    0, &master_port);
	if (status != PJ_SUCCESS) {
	    app_perror(THIS_FILE, "Unable to create master port", status);
	    goto on_exit;
	}

	status = pjmedia_master_port_start(master_port);
	if (status != PJ_SUCCESS) {
	    app_perror(THIS_FILE, "Error starting master port", status);
	    goto on_exit;
	}

	printf("Recording to WAV file %s..\n", rec_file);
	
    } else {

	/* Create sound device port. */
	if (dir == PJMEDIA_DIR_ENCODING_DECODING)
	    status = pjmedia_snd_port_create(pool, -1, -1, 
					PJMEDIA_PIA_SRATE(&stream_port->info),
					PJMEDIA_PIA_CCNT(&stream_port->info),
					PJMEDIA_PIA_SPF(&stream_port->info),
					PJMEDIA_PIA_BITS(&stream_port->info),
					0, &snd_port);
	else if (dir == PJMEDIA_DIR_ENCODING)
	    status = pjmedia_snd_port_create_rec(pool, -1, 
					PJMEDIA_PIA_SRATE(&stream_port->info),
					PJMEDIA_PIA_CCNT(&stream_port->info),
					PJMEDIA_PIA_SPF(&stream_port->info),
					PJMEDIA_PIA_BITS(&stream_port->info),
					0, &snd_port);
	else
	    status = pjmedia_snd_port_create_player(pool, -1, 
					PJMEDIA_PIA_SRATE(&stream_port->info),
					PJMEDIA_PIA_CCNT(&stream_port->info),
					PJMEDIA_PIA_SPF(&stream_port->info),
					PJMEDIA_PIA_BITS(&stream_port->info),
					0, &snd_port);


	if (status != PJ_SUCCESS) {
	    app_perror(THIS_FILE, "Unable to create sound port", status);
	    goto on_exit;
	}

	/* Connect sound port to stream */
	status = pjmedia_snd_port_connect( snd_port, stream_port );
	PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);

    }

    /* Start streaming */
    pjmedia_stream_start(stream);


    /* Done */

    if (dir == PJMEDIA_DIR_DECODING)
	printf("Stream is active, dir is recv-only, local port is %d\n",
	       local_port);
    else if (dir == PJMEDIA_DIR_ENCODING)
	printf("Stream is active, dir is send-only, sending to %s:%d\n",
	       pj_inet_ntoa(remote_addr.sin_addr),
	       pj_ntohs(remote_addr.sin_port));
    else
	printf("Stream is active, send/recv, local port is %d, "
	       "sending to %s:%d\n",
	       local_port,
	       pj_inet_ntoa(remote_addr.sin_addr),
	       pj_ntohs(remote_addr.sin_port));


    for (;;) {

	puts("");
	puts("Commands:");
	puts("  s     Display media statistics");
	puts("  q     Quit");
	puts("");

	printf("Command: "); fflush(stdout);

	if (fgets(tmp, sizeof(tmp), stdin) == NULL) {
	    puts("EOF while reading stdin, will quit now..");
	    break;
	}

	if (tmp[0] == 's')
	    print_stream_stat(stream, &codec_param);
	else if (tmp[0] == 'q')
	    break;

    }



    /* Start deinitialization: */
on_exit:

    /* Destroy sound device */
    if (snd_port) {
	pjmedia_snd_port_destroy( snd_port );
	PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
    }

    /* If there is master port, then we just need to destroy master port
     * (it will recursively destroy upstream and downstream ports, which
     * in this case are file_port and stream_port).
     */
    if (master_port) {
	pjmedia_master_port_destroy(master_port, PJ_TRUE);
	play_file_port = NULL;
	stream = NULL;
    }

    /* Destroy stream */
    if (stream) {
	pjmedia_transport *tp;

	tp = pjmedia_stream_get_transport(stream);
	pjmedia_stream_destroy(stream);
	
	pjmedia_transport_close(tp);
    }

    /* Destroy file ports */
    if (play_file_port)
	pjmedia_port_destroy( play_file_port );
    if (rec_file_port)
	pjmedia_port_destroy( rec_file_port );


    /* Release application pool */
    pj_pool_release( pool );

    /* Destroy media endpoint. */
    pjmedia_endpt_destroy( med_endpt );

    /* Destroy pool factory */
    pj_caching_pool_destroy( &cp );

    /* Shutdown PJLIB */
    pj_shutdown();


    return (status == PJ_SUCCESS) ? 0 : 1;
}
Пример #21
0
static int amf_parse_object(AVFormatContext *s, AVStream *astream, AVStream *vstream, const char *key, int64_t max_pos, int depth) {
    AVCodecContext *acodec, *vcodec;
    AVIOContext *ioc;
    AMFDataType amf_type;
    char str_val[256];
    double num_val;

    num_val = 0;
    ioc = s->pb;

    amf_type = avio_r8(ioc);

    switch(amf_type) {
    case AMF_DATA_TYPE_NUMBER:
        num_val = av_int2double(avio_rb64(ioc));
        break;
    case AMF_DATA_TYPE_BOOL:
        num_val = avio_r8(ioc);
        break;
    case AMF_DATA_TYPE_STRING:
        if(amf_get_string(ioc, str_val, sizeof(str_val)) < 0)
            return -1;
        break;
    case AMF_DATA_TYPE_OBJECT:
        if ((vstream || astream) && ioc->seekable && key && !strcmp(KEYFRAMES_TAG, key) && depth == 1)
            if (parse_keyframes_index(s, ioc, vstream ? vstream : astream,
                                      max_pos) < 0)
                av_log(s, AV_LOG_ERROR, "Keyframe index parsing failed\n");

        while (avio_tell(ioc) < max_pos - 2 && amf_get_string(ioc, str_val, sizeof(str_val)) > 0) {
            if (amf_parse_object(s, astream, vstream, str_val, max_pos, depth + 1) < 0)
                return -1; //if we couldn't skip, bomb out.
        }
        if(avio_r8(ioc) != AMF_END_OF_OBJECT)
            return -1;
        break;
    case AMF_DATA_TYPE_NULL:
    case AMF_DATA_TYPE_UNDEFINED:
    case AMF_DATA_TYPE_UNSUPPORTED:
        break; //these take up no additional space
    case AMF_DATA_TYPE_MIXEDARRAY:
        avio_skip(ioc, 4); //skip 32-bit max array index
        while(avio_tell(ioc) < max_pos - 2 && amf_get_string(ioc, str_val, sizeof(str_val)) > 0) {
            //this is the only case in which we would want a nested parse to not skip over the object
            if(amf_parse_object(s, astream, vstream, str_val, max_pos, depth + 1) < 0)
                return -1;
        }
        if(avio_r8(ioc) != AMF_END_OF_OBJECT)
            return -1;
        break;
    case AMF_DATA_TYPE_ARRAY: {
        unsigned int arraylen, i;

        arraylen = avio_rb32(ioc);
        for(i = 0; i < arraylen && avio_tell(ioc) < max_pos - 1; i++) {
            if(amf_parse_object(s, NULL, NULL, NULL, max_pos, depth + 1) < 0)
                return -1; //if we couldn't skip, bomb out.
        }
    }
    break;
    case AMF_DATA_TYPE_DATE:
        avio_skip(ioc, 8 + 2); //timestamp (double) and UTC offset (int16)
        break;
    default: //unsupported type, we couldn't skip
        return -1;
    }

    if(depth == 1 && key) { //only look for metadata values when we are not nested and key != NULL
        acodec = astream ? astream->codec : NULL;
        vcodec = vstream ? vstream->codec : NULL;

        if (amf_type == AMF_DATA_TYPE_NUMBER) {
            if (!strcmp(key, "duration"))
                s->duration = num_val * AV_TIME_BASE;
            else if (!strcmp(key, "videodatarate") && vcodec && 0 <= (int)(num_val * 1024.0))
                vcodec->bit_rate = num_val * 1024.0;
            else if (!strcmp(key, "audiodatarate") && acodec && 0 <= (int)(num_val * 1024.0))
                acodec->bit_rate = num_val * 1024.0;
            else if (!strcmp(key, "datastream")) {
                AVStream *st = create_stream(s, 2, AVMEDIA_TYPE_DATA);
                if (!st)
                    return AVERROR(ENOMEM);
                st->codec->codec_id = CODEC_ID_TEXT;
            }
        }

        if (amf_type == AMF_DATA_TYPE_OBJECT && s->nb_streams == 1 &&
                ((!acodec && !strcmp(key, "audiocodecid")) ||
                 (!vcodec && !strcmp(key, "videocodecid"))))
            s->ctx_flags &= ~AVFMTCTX_NOHEADER; //If there is either audio/video missing, codecid will be an empty object

        if (!strcmp(key, "duration")        ||
                !strcmp(key, "filesize")        ||
                !strcmp(key, "width")           ||
                !strcmp(key, "height")          ||
                !strcmp(key, "videodatarate")   ||
                !strcmp(key, "framerate")       ||
                !strcmp(key, "videocodecid")    ||
                !strcmp(key, "audiodatarate")   ||
                !strcmp(key, "audiosamplerate") ||
                !strcmp(key, "audiosamplesize") ||
                !strcmp(key, "stereo")          ||
                !strcmp(key, "audiocodecid"))
            return 0;

        if(amf_type == AMF_DATA_TYPE_BOOL) {
            av_strlcpy(str_val, num_val > 0 ? "true" : "false", sizeof(str_val));
            av_dict_set(&s->metadata, key, str_val, 0);
        } else if(amf_type == AMF_DATA_TYPE_NUMBER) {
            snprintf(str_val, sizeof(str_val), "%.f", num_val);
            av_dict_set(&s->metadata, key, str_val, 0);
        } else if (amf_type == AMF_DATA_TYPE_STRING)
            av_dict_set(&s->metadata, key, str_val, 0);
    }

    return 0;
}
Пример #22
0
int set_ea(char FAR *i_eas, char *name)
{
 #ifdef HAVE_EAS
  int rc=0;
  char FAR *eas;
  unsigned int i, total;
  #if TARGET==OS2
   #ifdef __32BIT__
    FILESTATUS4 fs;
    EAOP2 eaop;
    char FAR *real_pfeal;
    PFEA2LIST pfeal;
    PFEA2 pf, opf;
   #else
    EAOP eaop;
    PFEALIST pfeal;
    PFEA pf;
    FILESTATUS2 fs;
    SEL selector;
   #endif
  #elif TARGET==WIN32
   PFEALIST pfeal0, pfeal;
   PFEA pf;
   struct nt_sid *sid;
   unsigned char *pstreambuf, *streambuf;
   WIN32_STREAM_ID w32sid;
   unsigned long stream_len;
  #endif

  eas=i_eas;
  if(discard_ea(name))
   return(-1);
  if((total=mget_word(eas))==0)
   return(0);
  #if TARGET==OS2
   #ifdef __32BIT__
    /* This takes the 4-byte prefixes into account (are the V1.2 EAs still
       valid if they flow beyond 64K when the oNextEntryOffset is applied?).
       Also, we ensure that it is aligned properly. In theory, there may be
       a way to crash this (72K doesn't consider the multitude of EAs) but we
       don't know/care about it -- ASR 17/10/2000 */
    real_pfeal=(char FAR *)farmalloc_msg(73728);
    pfeal=(PFEA2LIST)align_dword(real_pfeal);
    eaop.fpFEA2List=pfeal;
   #else
    if(DosAllocSeg(65535U, &selector, SEG_NONSHARED))
     return(-1);
    pfeal=(PFEALIST)MAKEP(selector, 0);
    eaop.fpFEAList=pfeal;
   #endif
  #elif TARGET==WIN32
   pstreambuf=(char *)farmalloc_msg(65536+260*total);
   pfeal=pfeal0=(PFEALIST)(streambuf=align_dword(pstreambuf));
  #endif
  eas+=2;
  pf=&pfeal->list[0];
  for(i=0; i<total; i++)
  {
   #if TARGET==OS2&&defined(__32BIT__)
    opf=pf;
   #endif
   #if TARGET==WIN32
    pf=&pfeal->list[0];
   #endif
   pf->fEA=mget_byte(eas++);
   pf->cbName=mget_byte(eas++);
   pf->cbValue=mget_word(eas);
   eas+=2;
   #if TARGET==OS2&&defined(__32BIT__)
     far_memmove((char FAR *)pf+sizeof(FEA2)-1, eas, pf->cbName);
     *((char FAR *)pf+sizeof(FEA2)-1+pf->cbName)='\0';
   #else /* Win32 or OS/2-16 */
     far_memmove((char FAR *)pf+sizeof(FEA), eas, pf->cbName);
     *((char FAR *)pf+sizeof(FEA)+pf->cbName)='\0';
   #endif
   eas+=pf->cbName;
   #if TARGET==OS2&&defined(__32BIT__)
    far_memmove((char FAR *)pf+sizeof(FEA2)+pf->cbName, eas, pf->cbValue);
   #else /* Win32 or OS/2-16 */
    far_memmove((char FAR *)pf+sizeof(FEA)+pf->cbName+1, eas, pf->cbValue);
   #endif
   eas+=pf->cbValue;
   #if SFX_LEVEL>=ARJ
    #if TARGET==OS2&&defined(__32BIT__)
     if(ea_filter((char FAR *)pf+sizeof(FEA2), 0)&&((pf->fEA&FEA_NEEDEA)||!crit_eas))
    #else /* Win32 or OS/2-16 */
     if(ea_filter((char FAR *)pf+sizeof(FEA), 0)&&((pf->fEA&FEA_NEEDEA)||!crit_eas))
    #endif
   #endif
   /* Update the offsets */
   #if TARGET==OS2
    #ifdef __32BIT__
     pf=(PFEA2)((char FAR *)pf+sizeof(FEA2)+pf->cbName+pf->cbValue);
    #else
     pf=(PFEA)((char FAR *)pf+sizeof(FEA)+pf->cbName+1+pf->cbValue);
    #endif
    /* Align at DWORD boundary and issue the list fixups */
    #ifdef __32BIT__
     pf=(PFEA2)align_dword((char FAR *)pf);
     opf->oNextEntryOffset=(i+1==total)?0:(char FAR *)pf-(char FAR *)opf;
    #endif
   #elif TARGET==WIN32
    pfeal=(PFEALIST)((char FAR *)pfeal+sizeof(FEALIST)+pf->cbName+1+pf->cbValue);
    if(i<total-1)
     pfeal=(PFEALIST)align_dword((char FAR*)pfeal);
    pfeal0->cbList=(i==total-1)?
                   0:
                   (((char FAR *)pfeal)-((char FAR *)pfeal0));
    pfeal0=pfeal;
   #endif
  }
  #if TARGET==OS2
   pfeal->cbList=(char FAR *)pf-(char FAR *)pfeal;
   #ifdef __32BIT__
    rc=DosSetPathInfo((PSZ)name, FIL_QUERYEASIZE, (PBYTE)&eaop, sizeof(eaop), 0);
    farfree(real_pfeal);
   #else
    rc=DosSetPathInfo((PSZ)name, FIL_QUERYEASIZE, (PBYTE)&eaop, sizeof(eaop), 0, 0L);
    DosFreeSeg(selector);
   #endif
   if(!rc)
   {
    #ifdef __32BIT__
     if(DosQueryPathInfo(name, FIL_QUERYEASIZE, (PVOID)&fs, sizeof(fs)))
    #else
     if(DosQPathInfo(name, FIL_QUERYEASIZE, (PVOID)&fs, sizeof(fs), 0L))
    #endif
     rc=-1;
    else
     if(fs.cbList<=4)
      rc=-1;
   }
  #elif TARGET==WIN32
   if((sid=open_streams(name, 1))==NULL)
    rc=-1;
   else
   {
    memset(&w32sid, 0, sizeof(w32sid));
    w32sid.dwStreamId=BACKUP_EA_DATA;
    w32sid.Size.LowPart=stream_len=(((char FAR *)pfeal)-streambuf);
    if(create_stream(&w32sid, sid)||write_stream(streambuf, stream_len, sid)<stream_len)
     rc=-1;
    close_streams(sid);
   }
   free(pstreambuf);
  #endif
  return(rc);
 #else
  return(-1);
 #endif
}
Пример #23
0
void qcdoc_merge( char *name)
{
  int dum = defargcount(5);

  /*Integer register usage*/
  alreg(outptr,Iregs);
  alreg(vec1ptr,Iregs);
  alreg(vec2ptr,Iregs);
  alreg(counter,Iregs);

  /*Floating register usage*/
  reg_array_1d(vec1,Cregs,3);
  reg_array_1d(vec2,Cregs,3);
  reg_array_1d(oreg,Cregs,6);
  alreg(permreg,Cregs);

  def_off(ZERO,SpinorType,0);
  def_off (IN_ATOM,SpinorType,6*nsimd()); // 2spins worth, 3 colors x complex 
  def_off (OUT_ATOM,SpinorType,12*nsimd());// 2spins worth, 3 colors x complex x simd  
  def_off(bits16,Byte,0xFFFF);
  def_off(thirtytwo,Byte,32);
  def_off(sixteen,Byte,16);


  offset_2d(CHI_IMM,SpinorType,6,2*nsimd());

  int Isize = PROC->I_size;
  int word_size = def_offset(Isize,Byte,"word_size");

  struct stream *PreOut;
  struct stream *PreVec1;
  struct stream *PreVec2;

  int brchno,retno; /*Branch target handles*/
  int co;

  make_inst(DIRECTIVE,Enter_Routine,name);
  int bias = grab_stack(64);
  save_regs();
  queue_iadd_imm(PROC->StackPointer,PROC->StackPointer,bias);

  getarg(outptr);           /*Get args*/
  getarg(vec1ptr);  
  getarg(vec2ptr);
  getarg(counter);

  alreg(Mask,Iregs);
  alreg(Convert1,Iregs);
  alreg(Convert2,Iregs);
  int memory = PROC->StackPointer;

  for (int i =0; i<6; i++ ) { 
    need_constant(i*2*SizeofDatum(SpinorType)*nsimd());
  }
  need_constant(64);
  complex_simd_init(permreg);

  if ( half_precision ) {
    queue_iload_imm(Mask,ZERO);
    queue_ori(Mask,Mask,bits16);
    queue_lshift(Mask,Mask,thirtytwo);
    queue_ori(Mask,Mask,bits16);
    queue_lshift(Mask,Mask,sixteen);
  }

  /*
   * Insert a label to prevent reordering
   */
  make_inst(DIRECTIVE,Target,get_target_label());

  PreVec1= create_stream(IN_ATOM,vec1ptr ,counter,STREAM_IN ,LINEAR);
  PreVec2= create_stream(IN_ATOM,vec2ptr ,counter,STREAM_IN ,LINEAR);
  PreOut = create_stream(OUT_ATOM,outptr  ,counter,STREAM_OUT ,LINEAR);

  /*Branch to stack restore if length <1*/
  retno = get_target_label();
  check_iterations(counter,retno); 

  /*
   * Start software pipeline
   */

  brchno = start_loop(counter);

  int indco[3]={0,1,2};
  int permute_mu=3;

  for(int ico=0;ico<3;ico++){
    co = indco[ico];
    // Could do entirely in integer unit for half precision to accelerate this
    if ( half_precision ) { 
      complex_load_half(vec1[co],CHI_IMM[co][0],vec1ptr,memory,Convert1,Convert2,Mask);
      complex_load_half(vec2[co],CHI_IMM[co][0],vec2ptr,memory,Convert1,Convert2,Mask);
    } else { 
      complex_load(vec1[co],CHI_IMM[co][0],vec1ptr,SpinorType);
      complex_load(vec2[co],CHI_IMM[co][0],vec2ptr,SpinorType);
    }
  }

  {
    // Merge the vectors
    for(co=0;co<3;co++) complex_simd_merge (0,permute_mu,oreg[co*2]  ,vec1[co],vec2[co]);
    for(co=0;co<3;co++) complex_simd_merge (1,permute_mu,oreg[co*2+1],vec1[co],vec2[co]);
  }
  //  make_inst(DIRECTIVE,LS_BARRIER);
  for(int i=0;i<6;i++){ // 2 SIMD sites, 3 colors, 2 spins 2 complex == 24 floats
    if ( half_precision ) { 
      complex_store_half(oreg[i],CHI_IMM[i][0],outptr,memory,Convert1,Convert2,Mask);
    } else { 
      complex_store(oreg[i],CHI_IMM[i][0],outptr,SpinorType);
    }
  }

  iterate_stream(PreVec1);
  iterate_stream(PreVec2);

  do_prefetch(vec1ptr,0);
  do_prefetch(vec2ptr,0);
  do_prefetch(vec1ptr,1);
  do_prefetch(vec2ptr,1);


  iterate_stream(PreOut);

  stop_loop(brchno,counter);
  
  make_inst(DIRECTIVE,Target,retno);

  queue_isub_imm(PROC->StackPointer,PROC->StackPointer,bias);
  restore_regs();
  free_stack();
  make_inst(DIRECTIVE,Exit_Routine,name);

  return;
}