Пример #1
0
void guac_audio_stream_end(guac_audio_stream* audio) {

    double duration;

    /* Flush stream and finish encoding */
    guac_audio_stream_flush(audio);
    audio->encoder->end_handler(audio);

    /* Calculate duration of PCM data */
    duration = ((double) (audio->pcm_bytes_written * 1000 * 8))
                / audio->rate / audio->channels / audio->bps;

    /* Send audio */
    guac_protocol_send_audio(audio->client->socket, audio->stream,
            audio->stream->index, audio->encoder->mimetype, duration);

    guac_protocol_send_blob(audio->client->socket, audio->stream,
            audio->encoded_data, audio->encoded_data_used);

    guac_protocol_send_end(audio->client->socket, audio->stream);

    /* Clear data */
    audio->encoded_data_used = 0;

}
/**
 * Guacamole client plugin entry point. This function will be called by guacd
 * when the protocol associated with this plugin is selected.
 *
 * @param client
 *     A newly-allocated guac_client structure representing the client which
 *     connected to guacd.
 *
 * @param argc
 *     The number of arguments within the argv array.
 *
 * @param argv
 *     All arguments passed during the Guacamole protocol handshake. These
 *     arguments correspond identically in both order and number to the
 *     arguments listed in GUAC_CLIENT_ARGS.
 */
int guac_client_init(guac_client* client, int argc, char** argv) {

    /* Validate argument count */
    if (argc != STREAMTEST_ARGS_COUNT) {
        guac_client_log(client, GUAC_LOG_ERROR, "Wrong number of arguments.");
        return 1;
    }

    /* Allocate stream for media */
    streamtest_playback_mode mode;
    guac_stream* stream = guac_client_alloc_stream(client);

    /* Determine playback mode from mimetype */
    if (strncmp(argv[IDX_MIMETYPE], "audio/", 6) == 0) {
        mode = STREAMTEST_AUDIO;
        guac_client_log(client, GUAC_LOG_DEBUG,
                "Recognized type \"%s\" as audio",
                argv[IDX_MIMETYPE]);
    }
    else if (strncmp(argv[IDX_MIMETYPE], "video/", 6) == 0) {
        mode = STREAMTEST_VIDEO;
        guac_client_log(client, GUAC_LOG_DEBUG,
                "Recognized type \"%s\" as video",
                argv[IDX_MIMETYPE]);
    }

    /* Abort if type cannot be recognized */
    else {
        guac_client_log(client, GUAC_LOG_ERROR,
                "Invalid media type \"%s\" (not audio nor video)",
                argv[IDX_MIMETYPE]);
        return 1;
    }

    /* Initialize streaming depending on playback mode */
    switch (mode) {

        /* Set up progress bar for audio streams */
        case STREAMTEST_AUDIO:

            /* Begin audio stream */
            guac_protocol_send_audio(client->socket, stream,
                    argv[IDX_MIMETYPE]);

            /* Init display */
            guac_protocol_send_size(client->socket, GUAC_DEFAULT_LAYER,
                    STREAMTEST_PROGRESS_WIDTH,
                    STREAMTEST_PROGRESS_HEIGHT);
            break;

        /* Set up generic video area for video streams */
        case STREAMTEST_VIDEO:

            /* Begin video stream */
            guac_protocol_send_video(client->socket, stream,
                    GUAC_DEFAULT_LAYER, argv[IDX_MIMETYPE]);

            /* Init display */
            guac_protocol_send_size(client->socket, GUAC_DEFAULT_LAYER,
                    client->info.optimal_width,
                    client->info.optimal_height);
            break;

        /* There are no other playback modes */
        default:
            assert(false);

    }

    /* Attempt to open specified file, abort on error */
    int fd = open(argv[IDX_FILENAME], O_RDONLY);
    if (fd == -1) {
        guac_client_log(client, GUAC_LOG_ERROR,
                "Unable to open \"%s\": %s",
                argv[IDX_FILENAME], strerror(errno));
        return 1;
    }

    int file_size = streamtest_get_file_size(fd);
    if (file_size == -1) {
        guac_client_log(client, GUAC_LOG_ERROR,
                "Unable to determine size of file \"%s\": %s",
                argv[IDX_FILENAME], strerror(errno));
        return 1;
    }

    guac_client_log(client, GUAC_LOG_DEBUG,
            "Successfully opened file \"%s\" (%i bytes)",
            argv[IDX_FILENAME], file_size);

    /* Allocate state structure */
    streamtest_state* state = malloc(sizeof(streamtest_state));

    /* Set frame duration/size */
    state->frame_duration = atoi(argv[IDX_FRAME_USECS]);
    state->frame_bytes    = atoi(argv[IDX_BYTES_PER_FRAME]);
    state->frame_buffer   = malloc(state->frame_bytes);

    guac_client_log(client, GUAC_LOG_DEBUG,
            "Frames will last %i microseconds and contain %i bytes",
            state->frame_duration, state->frame_bytes);

    /* Start with the file closed, playback not paused */
    state->mode = mode;
    state->stream = stream;
    state->fd = fd;
    state->paused = false;
    state->file_size = file_size;

    /* Set client handlers and data */
    client->handle_messages = streamtest_client_message_handler;
    client->key_handler     = streamtest_client_key_handler;
    client->free_handler    = streamtest_client_free_handler;
    client->data = state;

    /* Render initial progress bar */
    streamtest_render_progress(client);
    guac_socket_flush(client->socket);

    /* Initialization complete */
    return 0;

}