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