1cabdff1aSopenharmony_ci/*
2cabdff1aSopenharmony_ci * Copyright (c) 2012 Martin Storsjo
3cabdff1aSopenharmony_ci *
4cabdff1aSopenharmony_ci * This file is part of FFmpeg.
5cabdff1aSopenharmony_ci *
6cabdff1aSopenharmony_ci * FFmpeg is free software; you can redistribute it and/or
7cabdff1aSopenharmony_ci * modify it under the terms of the GNU Lesser General Public
8cabdff1aSopenharmony_ci * License as published by the Free Software Foundation; either
9cabdff1aSopenharmony_ci * version 2.1 of the License, or (at your option) any later version.
10cabdff1aSopenharmony_ci *
11cabdff1aSopenharmony_ci * FFmpeg is distributed in the hope that it will be useful,
12cabdff1aSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of
13cabdff1aSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14cabdff1aSopenharmony_ci * Lesser General Public License for more details.
15cabdff1aSopenharmony_ci *
16cabdff1aSopenharmony_ci * You should have received a copy of the GNU Lesser General Public
17cabdff1aSopenharmony_ci * License along with FFmpeg; if not, write to the Free Software
18cabdff1aSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19cabdff1aSopenharmony_ci */
20cabdff1aSopenharmony_ci
21cabdff1aSopenharmony_ci#include <stdio.h>
22cabdff1aSopenharmony_ci#include <stdlib.h>
23cabdff1aSopenharmony_ci
24cabdff1aSopenharmony_ci#include "libavutil/time.h"
25cabdff1aSopenharmony_ci#include "libavformat/avformat.h"
26cabdff1aSopenharmony_ci
27cabdff1aSopenharmony_cistatic int usage(const char *argv0, int ret)
28cabdff1aSopenharmony_ci{
29cabdff1aSopenharmony_ci    fprintf(stderr, "%s [-b bytespersec] [-d duration] [-oi <options>] [-oo <options>] [-v] input_url output_url\n", argv0);
30cabdff1aSopenharmony_ci    fprintf(stderr, "<options>: AVOptions expressed as key=value, :-separated\n");
31cabdff1aSopenharmony_ci    return ret;
32cabdff1aSopenharmony_ci}
33cabdff1aSopenharmony_ci
34cabdff1aSopenharmony_ciint main(int argc, char **argv)
35cabdff1aSopenharmony_ci{
36cabdff1aSopenharmony_ci    int bps = 0, duration = 0, verbose = 0, ret, i;
37cabdff1aSopenharmony_ci    const char *input_url = NULL, *output_url = NULL;
38cabdff1aSopenharmony_ci    int64_t stream_pos = 0;
39cabdff1aSopenharmony_ci    int64_t start_time;
40cabdff1aSopenharmony_ci    char errbuf[50];
41cabdff1aSopenharmony_ci    AVIOContext *input, *output;
42cabdff1aSopenharmony_ci    AVDictionary *in_opts = NULL;
43cabdff1aSopenharmony_ci    AVDictionary *out_opts = NULL;
44cabdff1aSopenharmony_ci
45cabdff1aSopenharmony_ci    avformat_network_init();
46cabdff1aSopenharmony_ci
47cabdff1aSopenharmony_ci    for (i = 1; i < argc; i++) {
48cabdff1aSopenharmony_ci        if (!strcmp(argv[i], "-b") && i + 1 < argc) {
49cabdff1aSopenharmony_ci            bps = atoi(argv[i + 1]);
50cabdff1aSopenharmony_ci            i++;
51cabdff1aSopenharmony_ci        } else if (!strcmp(argv[i], "-d") && i + 1 < argc) {
52cabdff1aSopenharmony_ci            duration = atoi(argv[i + 1]);
53cabdff1aSopenharmony_ci            i++;
54cabdff1aSopenharmony_ci        } else if (!strcmp(argv[i], "-oi") && i + 1 < argc) {
55cabdff1aSopenharmony_ci            if (av_dict_parse_string(&in_opts, argv[i + 1], "=", ":", 0) < 0) {
56cabdff1aSopenharmony_ci                fprintf(stderr, "Cannot parse option string %s\n",
57cabdff1aSopenharmony_ci                        argv[i + 1]);
58cabdff1aSopenharmony_ci                return usage(argv[0], 1);
59cabdff1aSopenharmony_ci            }
60cabdff1aSopenharmony_ci            i++;
61cabdff1aSopenharmony_ci        } else if (!strcmp(argv[i], "-oo") && i + 1 < argc) {
62cabdff1aSopenharmony_ci            if (av_dict_parse_string(&out_opts, argv[i + 1], "=", ":", 0) < 0) {
63cabdff1aSopenharmony_ci                fprintf(stderr, "Cannot parse option string %s\n",
64cabdff1aSopenharmony_ci                        argv[i + 1]);
65cabdff1aSopenharmony_ci                return usage(argv[0], 1);
66cabdff1aSopenharmony_ci            }
67cabdff1aSopenharmony_ci            i++;
68cabdff1aSopenharmony_ci        } else if (!strcmp(argv[i], "-v")) {
69cabdff1aSopenharmony_ci            verbose = 1;
70cabdff1aSopenharmony_ci        } else if (!input_url) {
71cabdff1aSopenharmony_ci            input_url = argv[i];
72cabdff1aSopenharmony_ci        } else if (!output_url) {
73cabdff1aSopenharmony_ci            output_url = argv[i];
74cabdff1aSopenharmony_ci        } else {
75cabdff1aSopenharmony_ci            return usage(argv[0], 1);
76cabdff1aSopenharmony_ci        }
77cabdff1aSopenharmony_ci    }
78cabdff1aSopenharmony_ci    if (!output_url)
79cabdff1aSopenharmony_ci        return usage(argv[0], 1);
80cabdff1aSopenharmony_ci
81cabdff1aSopenharmony_ci    ret = avio_open2(&input, input_url, AVIO_FLAG_READ, NULL, &in_opts);
82cabdff1aSopenharmony_ci    if (ret) {
83cabdff1aSopenharmony_ci        av_strerror(ret, errbuf, sizeof(errbuf));
84cabdff1aSopenharmony_ci        fprintf(stderr, "Unable to open %s: %s\n", input_url, errbuf);
85cabdff1aSopenharmony_ci        return 1;
86cabdff1aSopenharmony_ci    }
87cabdff1aSopenharmony_ci    if (verbose) {
88cabdff1aSopenharmony_ci        int64_t size = avio_seek(input, 0, AVSEEK_SIZE);
89cabdff1aSopenharmony_ci        if (size >= 0) {
90cabdff1aSopenharmony_ci            fprintf(stderr, "aviocat: input size: %"PRId64"\n", size);
91cabdff1aSopenharmony_ci        } else {
92cabdff1aSopenharmony_ci            fprintf(stderr, "aviocat: input size: unknown\n");
93cabdff1aSopenharmony_ci        }
94cabdff1aSopenharmony_ci    }
95cabdff1aSopenharmony_ci    if (duration && !bps) {
96cabdff1aSopenharmony_ci        int64_t size = avio_size(input);
97cabdff1aSopenharmony_ci        if (size < 0) {
98cabdff1aSopenharmony_ci            av_strerror(ret, errbuf, sizeof(errbuf));
99cabdff1aSopenharmony_ci            fprintf(stderr, "Unable to get size of %s: %s\n", input_url, errbuf);
100cabdff1aSopenharmony_ci            goto fail;
101cabdff1aSopenharmony_ci        }
102cabdff1aSopenharmony_ci        bps = size / duration;
103cabdff1aSopenharmony_ci    }
104cabdff1aSopenharmony_ci    ret = avio_open2(&output, output_url, AVIO_FLAG_WRITE, NULL, &out_opts);
105cabdff1aSopenharmony_ci    if (ret) {
106cabdff1aSopenharmony_ci        av_strerror(ret, errbuf, sizeof(errbuf));
107cabdff1aSopenharmony_ci        fprintf(stderr, "Unable to open %s: %s\n", output_url, errbuf);
108cabdff1aSopenharmony_ci        goto fail;
109cabdff1aSopenharmony_ci    }
110cabdff1aSopenharmony_ci
111cabdff1aSopenharmony_ci    start_time = av_gettime_relative();
112cabdff1aSopenharmony_ci    while (1) {
113cabdff1aSopenharmony_ci        uint8_t buf[1024];
114cabdff1aSopenharmony_ci        int n;
115cabdff1aSopenharmony_ci        n = avio_read(input, buf, sizeof(buf));
116cabdff1aSopenharmony_ci        if (n <= 0)
117cabdff1aSopenharmony_ci            break;
118cabdff1aSopenharmony_ci        avio_write(output, buf, n);
119cabdff1aSopenharmony_ci        if (output->error) {
120cabdff1aSopenharmony_ci            av_strerror(output->error, errbuf, sizeof(errbuf));
121cabdff1aSopenharmony_ci            fprintf(stderr, "Unable to write %s: %s\n", output_url, errbuf);
122cabdff1aSopenharmony_ci            break;
123cabdff1aSopenharmony_ci        }
124cabdff1aSopenharmony_ci        stream_pos += n;
125cabdff1aSopenharmony_ci        if (bps) {
126cabdff1aSopenharmony_ci            avio_flush(output);
127cabdff1aSopenharmony_ci            while ((av_gettime_relative() - start_time) * bps / AV_TIME_BASE < stream_pos)
128cabdff1aSopenharmony_ci                av_usleep(50 * 1000);
129cabdff1aSopenharmony_ci        }
130cabdff1aSopenharmony_ci    }
131cabdff1aSopenharmony_ci
132cabdff1aSopenharmony_ci    avio_flush(output);
133cabdff1aSopenharmony_ci    avio_close(output);
134cabdff1aSopenharmony_ci
135cabdff1aSopenharmony_cifail:
136cabdff1aSopenharmony_ci    av_dict_free(&in_opts);
137cabdff1aSopenharmony_ci    av_dict_free(&out_opts);
138cabdff1aSopenharmony_ci    avio_close(input);
139cabdff1aSopenharmony_ci    avformat_network_deinit();
140cabdff1aSopenharmony_ci    return ret ? 1 : 0;
141cabdff1aSopenharmony_ci}
142