Example #1
0
File: under.c Project: vvv/under.c
/*
 * This function is an /enumerator/ in the terminology of iteratees
 * [http://okmij.org/ftp/Streams.html].
 *
 * Return value: 0 - success, -1 - error.
 */
static int
process_file(enum Codec_T ct, const char *inpath, struct Buffer *inbuf,
             const struct Repr_Format *repr)
{
    debug_print("process_file: \"%s\"", inpath);
    FILE *f = NULL;

    if (streq(inpath, "-")) {
        f = stdin;
    } else if ((f = fopen(inpath, "rb")) == NULL) {
        error(0, errno, "%s", inpath);
        return -1;
    }

    if (adjust_buffer(inbuf, f) < 0) {
        error(0, errno, "%s", inpath);
        return -1;
    }

    int retval = -1;
    size_t filepos = 0;
    struct Stream str = STREAM_INIT;
    void *z = NULL;

    for (;;) {
        const size_t orig_size = read_block(inbuf->wptr, inbuf->size,
                                            f, &str);
        str.type = ((str.size = orig_size) == 0) ? S_EOF : S_CHUNK;
        str.data = inbuf->wptr;

        if (str.type == S_EOF && str.errmsg != NULL) {
            error_at_line(0, 0, inpath, filepos, "%s", str.errmsg);
            break;
        }

        const IterV indic = run_codec(ct, &z, &str, repr);
        assert(indic == IE_DONE || indic == IE_CONT);
        filepos += orig_size - str.size;

        if (indic == IE_CONT && str.errmsg != NULL) {
            error_at_line(0, 0, inpath, filepos, "%s", str.errmsg);
            break;
        }

        assert(str.size == 0);

        if (indic == IE_DONE) {
            retval = 0;
            break;
        }
    }

    if (!streq(inpath, "-"))
        retval |= fclose(f);

    free(str.errmsg);
    free_codec(ct, z); /* XXX malloc/free for each input file is not good */
    return retval;
}
Example #2
0
/* Codec thread function */
static void NORETURN_ATTR codec_thread(void)
{
    struct queue_event ev;

    while (1)
    {
        cancel_cpu_boost();

        queue_wait(&codec_queue, &ev);

        switch (ev.id)
        {
        case Q_CODEC_LOAD:
            LOGFQUEUE("codec < Q_CODEC_LOAD");
            load_codec((const struct codec_load_info *)ev.data);
            break;

        case Q_CODEC_RUN:
            LOGFQUEUE("codec < Q_CODEC_RUN");
            run_codec();
            break;

        case Q_CODEC_PAUSE:
            LOGFQUEUE("codec < Q_CODEC_PAUSE");
            break;

        case Q_CODEC_SEEK:
            LOGFQUEUE("codec < Q_CODEC_SEEK: %lu", (unsigned long)ev.data);
            seek_codec(ev.data);
            break;

        case Q_CODEC_UNLOAD:
            LOGFQUEUE("codec < Q_CODEC_UNLOAD");
            unload_codec();
            break;

        case Q_CODEC_DO_CALLBACK:
            LOGFQUEUE("codec < Q_CODEC_DO_CALLBACK");
            do_callback((void (*)(void))ev.data);
            break;

        default:
            LOGFQUEUE("codec < default : %ld", ev.id);
        }
    }
}
Example #3
0
/* Handle Q_CODEC_SEEK */
static void seek_codec(unsigned long time)
{
    if (codec_type == AFMT_UNKNOWN)
    {
        logf("no codec to seek");
        codec_queue_ack(Q_CODEC_SEEK);
        codec_seek_complete_callback();
        return;
    }

    /* Post it up one level */
    queue_post(&codec_queue, Q_CODEC_SEEK, time);
    codec_queue_ack(Q_CODEC_SEEK);

    /* Have to run it again */
    run_codec();
}