Beispiel #1
0
int main(int argc, char **argv)
{
    int flags = DCADEC_FLAG_STRICT;
    bool parse_only = false;
    bool no_progress = false;
    bool quiet = false;
    bool no_strip = false;

    int opt;
    while ((opt = getopt(argc, argv, "26bcfhlnPqSsx")) != -1) {
        switch (opt) {
        case '2':
            flags |= DCADEC_FLAG_KEEP_DMIX_2CH;
            break;
        case '6':
            flags |= DCADEC_FLAG_KEEP_DMIX_6CH;
            break;
        case 'b':
            flags |= DCADEC_FLAG_CORE_BIT_EXACT;
            break;
        case 'c':
            flags |= DCADEC_FLAG_CORE_ONLY;
            break;
        case 'f':
            flags |= DCADEC_FLAG_CORE_LFE_FIR;
            break;
        case 'h':
            print_help(argv[0]);
            return 0;
        case 'l':
            flags &= ~DCADEC_FLAG_STRICT;
            break;
        case 'n':
            parse_only = true;
            break;
        case 'P':
            no_progress = true;
            break;
        case 'q':
            quiet = true;
            break;
        case 'S':
            no_strip = true;
            break;
        case 's':
            flags |= DCADEC_FLAG_CORE_SOURCE_PCM_RES;
            break;
        case 'x':
            flags |= DCADEC_FLAG_CORE_SYNTH_X96;
            break;
        default:
            print_help(argv[0]);
            return 1;
        }
    }

    no_progress |= quiet;

    if (optind >= argc) {
        print_help(argv[0]);
        return 1;
    }

    char *fn = argv[optind];
    struct dcadec_stream *stream = dcadec_stream_open(strcmp(fn, "-") ? fn : NULL);
    if (!stream) {
        fprintf(stderr, "Couldn't open input file\n");
        return 1;
    }

    uint8_t *packet;
    size_t size;
    int ret;

    if ((ret = dcadec_stream_read(stream, &packet, &size)) < 0) {
        fprintf(stderr, "Error reading packet: %s\n", dcadec_strerror(ret));
        dcadec_stream_close(stream);
        return 1;
    }

    if (ret == 0) {
        fprintf(stderr, "This doesn't look like a valid DTS bit stream\n");
        dcadec_stream_close(stream);
        return 1;
    }

    struct dcadec_context *context = dcadec_context_create(flags);
    if (!context) {
        fprintf(stderr, "Couldn't create decoder context\n");
        dcadec_stream_close(stream);
        return 1;
    }

    if ((ret = dcadec_context_parse(context, packet, size)) < 0) {
        fprintf(stderr, "Error parsing packet: %s\n", dcadec_strerror(ret));
        dcadec_context_destroy(context);
        dcadec_stream_close(stream);
        return 1;
    }

    if (!quiet)
        print_info(context);

    struct dcadec_waveout *waveout = NULL;
    if (!parse_only) {
        if (optind + 1 >= argc) {
            dcadec_context_destroy(context);
            dcadec_stream_close(stream);
            return 0;
        }

        fn = argv[optind + 1];
        waveout = dcadec_waveout_open(strcmp(fn, "-") ? fn : NULL);
        if (!waveout) {
            fprintf(stderr, "Couldn't open output file\n");
            dcadec_context_destroy(context);
            dcadec_stream_close(stream);
            return 1;
        }

    }

    int last_progress = -1;

#ifdef _WIN32
    SetConsoleCtrlHandler(&console_ctrl_handler, TRUE);
#else
    signal(SIGINT, &signal_handler);
#endif

    uint32_t ndelayframes = 0;
    uint64_t npcmsamples = UINT64_MAX;

    if (!parse_only && !no_strip) {
        struct dcadec_stream_info *info = dcadec_stream_get_info(stream);
        if (info) {
            if (info->nframesamples)
                ndelayframes = info->ndelaysamples / info->nframesamples;
            if (info->npcmsamples)
                npcmsamples = info->npcmsamples;
            dcadec_stream_free_info(info);
        }
    }

    if (!quiet) {
        if (waveout) {
            if (flags & DCADEC_FLAG_CORE_ONLY)
                fprintf(stderr, "Decoding (core only)...\n");
            else
                fprintf(stderr, "Decoding...\n");
        } else {
            if (flags & DCADEC_FLAG_CORE_ONLY)
                fprintf(stderr, "Parsing (core only)...\n");
            else
                fprintf(stderr, "Parsing...\n");
        }
    }

    while (!interrupted) {
        if (waveout) {
            int **samples, nsamples, channel_mask, sample_rate, bits_per_sample;
            if ((ret = dcadec_context_filter(context, &samples, &nsamples,
                                             &channel_mask, &sample_rate,
                                             &bits_per_sample, NULL)) < 0) {
                fprintf(stderr, "Error filtering frame: %s\n", dcadec_strerror(ret));
                if (flags & DCADEC_FLAG_STRICT)
                    break;
                else
                    goto next_packet;
            }

            if (ndelayframes) {
                ndelayframes--;
                goto next_packet;
            }

            if ((uint64_t)nsamples > npcmsamples)
                nsamples = npcmsamples;

            if ((ret = dcadec_waveout_write(waveout, samples, nsamples,
                                            channel_mask, sample_rate,
                                            bits_per_sample)) < 0) {
                fprintf(stderr, "Error writing WAV file: %s\n", dcadec_strerror(ret));
                if ((flags & DCADEC_FLAG_STRICT) || ret == -DCADEC_EIO)
                    break;
            }

            npcmsamples -= nsamples;
        }

next_packet:
        if ((ret = dcadec_stream_read(stream, &packet, &size)) < 0) {
            fprintf(stderr, "Error reading packet: %s\n", dcadec_strerror(ret));
            break;
        }

        if (!no_progress) {
            int progress = dcadec_stream_progress(stream);
            if (progress != last_progress) {
                fprintf(stderr, "Progress: %d%%\r", progress);
                last_progress = progress;
            }
        }

        if (ret == 0)
            break;

        if ((ret = dcadec_context_parse(context, packet, size)) < 0) {
            fprintf(stderr, "Error parsing packet: %s\n", dcadec_strerror(ret));
            if (flags & DCADEC_FLAG_STRICT)
                break;
            else
                goto next_packet;
        }
    }

    if (!quiet) {
        if (last_progress != -1)
            fprintf(stderr, "\n");
        if (interrupted)
            fprintf(stderr, "Interrupted.\n");
        else if (ret == 0)
            fprintf(stderr, "Completed.\n");
    }

    dcadec_waveout_close(waveout);
    dcadec_context_destroy(context);
    dcadec_stream_close(stream);
    return !!ret;
}
Beispiel #2
0
int main(int argc, char **argv)
{
    if (argc < 3) {
        fprintf(stderr, "Usage: %s <input.dts> <output.dts> [first] [last]\n", argv[0]);
        return 1;
    }

    unsigned long first_packet = 0;
    unsigned long last_packet = ULONG_MAX;

    if (argc > 3)
        first_packet = strtoul(argv[3], NULL, 0);
    if (argc > 4)
        last_packet = strtoul(argv[4], NULL, 0);
    if (last_packet < first_packet) {
        fprintf(stderr, "Invalid packet range\n");
        return 1;
    }

    struct dcadec_stream *stream = dcadec_stream_open(argv[1], 0);
    if (!stream) {
        fprintf(stderr, "Couldn't open input file\n");
        return 1;
    }

    FILE *fp = fopen(argv[2], "wb");
    if (!fp) {
        fprintf(stderr, "Couldn't open output file\n");
        dcadec_stream_close(stream);
        return 1;
    }

    unsigned long packet_in = 0;
    unsigned long packet_out = 0;

    int ret;

    while (true) {
        uint8_t *packet;
        size_t size;

        ret = dcadec_stream_read(stream, &packet, &size);
        if (ret < 0) {
            fprintf(stderr, "Error %d reading packet\n", ret);
            break;
        }
        if (ret == 0)
            break;

        if (packet_in >= first_packet) {
            if (fwrite(packet, size, 1, fp) != 1) {
                fprintf(stderr, "Error %d writing packet\n", errno);
                ret = -1;
                break;
            }
            packet_out++;
        }

        if (++packet_in > last_packet)
            break;
    }

    if (packet_out) {
        fprintf(stderr, "Wrote %lu packets\n", packet_out);
    } else {
        fprintf(stderr, "Didn't write a single packet!\n");
        ret = -1;
    }

    fclose(fp);
    dcadec_stream_close(stream);
    return !!ret;
}