1 /*
2 * Copyright (c) 2013 Lukasz Marek <lukasz.m.luki@gmail.com>
3 *
4 * This file is part of FFmpeg.
5 *
6 * FFmpeg is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * FFmpeg is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with FFmpeg; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
29
30 #define CONTROL_BUFFER_SIZE 1024
31 #define DIR_BUFFER_SIZE 4096
32
41
47
57 char *
user;
/**< Server user */
59 char *
path;
/**< Path to resource on server. */
60 int64_t
filesize;
/**< Size of file on server, -1 on error. */
61 int64_t
position;
/**< Current position, calculated. */
63 const char *
anonymous_password;
/**< Password to be used for anonymous user. An email should be used. */
67 char *
features;
/**< List of server's features represented as raw response */
73
74 #define OFFSET(x) offsetof(FTPContext, x)
75 #define D AV_OPT_FLAG_DECODING_PARAM
76 #define E AV_OPT_FLAG_ENCODING_PARAM
78 {
"timeout",
"set timeout of socket I/O operations",
OFFSET(rw_timeout),
AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX,
D|
E },
79 {
"ftp-write-seekable",
"control seekability of connection during encoding",
OFFSET(write_seekable),
AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1,
E },
80 {
"ftp-anonymous-password",
"password for anonymous login. E-mail address should be used.",
OFFSET(anonymous_password),
AV_OPT_TYPE_STRING, { 0 }, 0, 0,
D|
E },
82 };
83
89 };
90
92
94 {
98 if (len < 0) {
100 } else if (!len) {
101 return -1;
102 } else {
105 }
106 }
108 }
109
111 {
113 char *q = line;
114
115 for (;;) {
117 if (ch < 0) {
119 }
120 if (ch == '\n') {
121 /* process line */
122 if (q > line && q[-1] == '\r')
123 q--;
124 *q = '0円';
125 return 0;
126 } else {
127 if ((q - line) < line_size - 1)
129 }
130 }
131 }
132
133 /*
134 * This routine returns ftp server response code.
135 * Server may send more than one response for a certain command.
136 * First expected code is returned.
137 */
139 {
140 int err, i, dash = 0, result = 0, code_found = 0, linesize;
142 AVBPrint line_buffer;
143
144 if (line)
146
147 while (!code_found || dash) {
149 if (line)
151 return err;
152 }
153
155
156 linesize = strlen(buf);
157 err = 0;
158 if (linesize >= 3) {
159 for (i = 0; i < 3; ++i) {
160 if (buf[i] < '0' || buf[i] > '9') {
161 err = 0;
162 break;
163 }
164 err *= 10;
165 err += buf[i] - '0';
166 }
167 }
168
169 if (!code_found) {
170 if (err >= 500) {
171 code_found = 1;
172 result = err;
173 } else
174 for (i = 0; response_codes[i]; ++i) {
175 if (err == response_codes[i]) {
176 code_found = 1;
177 result = err;
178 break;
179 }
180 }
181 }
182 if (code_found) {
183 if (line)
185 if (linesize >= 4) {
186 if (!dash && buf[3] == '-')
187 dash = err;
188 else if (err == dash && buf[3] == ' ')
189 dash = 0;
190 }
191 }
192 }
193
194 if (line)
196 return result;
197 }
198
200 const int response_codes[], char **response)
201 {
202 int err;
203
205
206 if (response)
208
211
213 return err;
214 if (!err)
215 return -1;
216
217 /* return status */
218 if (response_codes) {
219 return ftp_status(s, response, response_codes);
220 }
221 return 0;
222 }
223
225 {
229 }
230
232 {
235 }
236
238 {
240 int err;
241 static const int user_codes[] = {331, 230, 0};
242 static const int pass_codes[] = {230, 0};
243
246 if (err == 331) {
250 } else
252 }
253 if (err != 230)
255
256 return 0;
257 }
258
260 {
262 int i;
263 static const char d = '|';
264 static const char *
command =
"EPSV\r\n";
265 static const int epsv_codes[] = {229, 0};
266
269
270 for (i = 0; res[i]; ++i) {
271 if (res[i] == '(') {
272 start = res + i + 1;
273 } else if (res[i] == ')') {
274 end = res + i;
275 break;
276 }
277 }
278 if (!start || !end)
280
281 *end = '0円';
282 if (strlen(start) < 5)
284 if (start[0] != d || start[1] != d || start[2] != d || end[-1] != d)
286 start += 3;
287 end[-1] = '0円';
288
291
293 return 0;
294
299 }
300
302 {
304 int i;
305 static const char *
command =
"PASV\r\n";
306 static const int pasv_codes[] = {227, 0};
307
310
311 for (i = 0; res[i]; ++i) {
312 if (res[i] == '(') {
313 start = res + i + 1;
314 } else if (res[i] == ')') {
315 end = res + i;
316 break;
317 }
318 }
319 if (!start || !end)
321
322 *end = '0円';
323 /* skip ip */
328
329 /* parse port number */
331 if (!start)
goto fail;
334 if (!start)
goto fail;
337
339 return 0;
340
345 }
346
348 {
350 int i;
351 static const char *
command =
"PWD\r\n";
352 static const int pwd_codes[] = {257, 0};
353
356
357 for (i = 0; res[i]; ++i) {
358 if (res[i] == '"') {
359 if (!start) {
360 start = res + i + 1;
361 continue;
362 }
363 end = res + i;
364 break;
365 }
366 }
367
368 if (!end)
370
371 *end = '0円';
373
375
378 return 0;
379
383 }
384
386 {
389 static const int size_codes[] = {213, 0};
390
391 snprintf(command,
sizeof(command),
"SIZE %s\r\n", s->
path);
394 } else {
398 }
399
401 return 0;
402 }
403
405 {
407 static const int retr_codes[] = {150, 125, 0};
408 int resp_code;
409
410 snprintf(command,
sizeof(command),
"RETR %s\r\n", s->
path);
412 if (resp_code != 125 && resp_code != 150)
414
416
417 return 0;
418 }
419
421 {
423 static const int stor_codes[] = {150, 125, 0};
424 int resp_code;
425
426 snprintf(command,
sizeof(command),
"STOR %s\r\n", s->
path);
428 if (resp_code != 125 && resp_code != 150)
430
432
433 return 0;
434 }
435
437 {
438 static const char *
command =
"TYPE I\r\n";
439 static const int type_codes[] = {200, 0};
440
443
444 return 0;
445 }
446
448 {
450 static const int rest_codes[] = {350, 0};
451
452 snprintf(command,
sizeof(command),
"REST %"PRId64
"\r\n", pos);
455
456 return 0;
457 }
458
460 {
461 static const int cwd_codes[] = {250, 550, 0}; /* 550 is incorrect code */
463
464 snprintf(command,
sizeof(command),
"CWD %s\r\n", s->
path);
467 return 0;
468 }
469
471 {
472 static const char *
command =
"MLSD\r\n";
473 static const int mlsd_codes[] = {150, 500, 0}; /* 500 is incorrect code */
474
478 return 0;
479 }
480
482 {
483 static const char *
command =
"NLST\r\n";
484 static const int nlst_codes[] = {226, 425, 426, 451, 450, 550, 0};
485
489 return 0;
490 }
491
493
495 {
496 int ret;
498
501
502 return ret;
503 }
504
506 {
508 return 0;
509
511 }
512
514 {
515 static const char *feat_command = "FEAT\r\n";
516 static const char *enable_utf8_command = "OPTS UTF8 ON\r\n";
517 static const int feat_codes[] = {211, 0};
518 static const int opts_codes[] = {200, 451, 0};
519
523 }
524
528 }
529
530 return 0;
531 }
532
534 {
536 int err;
539 static const int connect_codes[] = {220, 0};
540
546 } /* if option is not given, don't pass it and let tcp use its own default */
551 if (err < 0) {
553 return err;
554 }
555
556 /* check if server is ready */
560 }
561
563 av_log(h,
AV_LOG_WARNING,
"Pure-FTPd server is used as an output protocol. It is known issue this implementation may produce incorrect content and it cannot be fixed at this moment.");
564 }
566
569 return err;
570 }
571
574 return err;
575 }
576
578 }
579 return 0;
580 }
581
583 {
584 int err;
588
590 /* Enter passive mode */
592 /* Use PASV as fallback */
594 return err;
595 }
596 /* Open data connection */
600 } /* if option is not given, don't pass it and let tcp use its own default */
605 if (err < 0)
606 return err;
607
610 return err;
611 }
613 return 0;
614 }
615
617 {
618 static const char *
command =
"ABOR\r\n";
619 int err;
620 static const int abor_codes[] = {225, 226, 0};
622
623 /* According to RCF 959:
624 "ABOR command tells the server to abort the previous FTP
625 service command and any associated transfer of data."
626
627 There are FTP server implementations that don't response
628 to any commands during data transfer in passive mode (including ABOR).
629
630 This implementation closes data connection by force.
631 */
632
637 return err;
638 }
639 } else {
642 /* wu-ftpd also closes control connection after data connection closing */
646 return err;
647 }
648 }
649 }
650
651 return 0;
652 }
653
655 {
657 const char *tok_user =
NULL, *tok_pass =
NULL;
659 int err;
661
667
669 credencials, sizeof(credencials),
670 hostname, sizeof(hostname),
672 path, sizeof(path),
673 url);
674
675 tok_user =
av_strtok(credencials,
":", &end);
677 if (!tok_user) {
678 tok_user = "anonymous";
680 }
686 }
687
690
692 return err;
693
695 return err;
696
698 if (!newpath)
702
703 return 0;
704 }
705
707 {
709 int err;
710
711 ff_dlog(h,
"ftp protocol open\n");
712
715
718 } else {
723 }
724
725 return 0;
726
730 return err;
731 }
732
734 {
736 int err;
737 int64_t new_pos, fake_pos;
738
739 ff_dlog(h,
"ftp protocol seek %"PRId64
" %d\n", pos, whence);
740
741 switch(whence) {
744 case SEEK_SET:
745 new_pos = pos;
746 break;
747 case SEEK_CUR:
749 break;
750 case SEEK_END:
754 break;
755 default:
757 }
758
761
762 if (new_pos < 0) {
765 }
766
770 return err;
772 }
773 return new_pos;
774 }
775
777 {
779 int read, err, retry_done = 0;
780
781 ff_dlog(h,
"ftp protocol read %d bytes\n", size);
782 retry:
784 /* optimization */
786 return 0;
788 return err;
789 }
792 return 0;
794 return err;
795 }
798 if (read >= 0) {
801 /* server will terminate, but keep current position to avoid madness */
802 /* save position to restart from it */
807 }
809 }
810 }
811 if (read <= 0 && s->position < s->filesize && !h->
is_streamed) {
812 /* Server closed connection. Probably due to inactivity */
816 return err;
817 if ((err =
ftp_seek(h, pos, SEEK_SET)) < 0) {
819 return err;
820 }
821 if (!retry_done) {
822 retry_done = 1;
823 goto retry;
824 }
825 }
826 return read;
827 }
828
831 }
832
834 {
835 int err;
837 int written;
838
839 ff_dlog(h,
"ftp protocol write %d bytes\n", size);
840
843 return err;
844 }
847 return err;
848 }
851 if (written > 0) {
854 }
855 return written;
856 }
857
860 }
861
863 {
865
866 ff_dlog(h,
"ftp protocol close\n");
867
874
875 return 0;
876 }
877
879 {
881
882 ff_dlog(h,
"ftp protocol get_file_handle\n");
883
886
888 }
889
891 {
893
894 ff_dlog(h,
"ftp protocol shutdown\n");
895
898
900 }
901
903 {
905 int ret;
906
919 }
922 return 0;
926 return ret;
927 }
928
930 {
931 struct tm tv;
932 memset(&tv, 0, sizeof(struct tm));
934 return INT64_C(1000000) *
av_timegm(&tv);
935 }
936
938 {
940 return 0;
941 }
942
944 {
947 while(fact =
av_strtok(mlsd,
";", &mlsd)) {
948 if (fact[0] == ' ') {
950 continue;
951 }
955 return 1;
971 next->
size = strtoll(value,
NULL, 10);
972 }
973 return 0;
974 }
975
976 /**
977 * @return 0 on success, negative on error, positive on entry to discard.
978 */
980 {
982
989 default:
990 return -1;
991 }
992 }
993
995 {
998 int ret, retried;
999
1000 do {
1001 retried = 0;
1003 while (!(found = strstr(start, "\n"))) {
1004 if (retried)
1011 if (ret < 0)
1012 return ret;
1013 if (!ret) {
1015 return 0;
1016 }
1020 retried = 1;
1021 }
1023 found[0] = 0;
1024 if (found > start && found[-1] == '\r')
1025 found[-1] = 0;
1026
1028 if (!*next)
1030 (*next)->utf8 = s->
utf8;
1032 if (ret) {
1034 if (ret < 0)
1035 return ret;
1036 }
1037 } while (ret > 0);
1038 return 0;
1039 }
1040
1042 {
1047 return 0;
1048 }
1049
1051 {
1054 static const int del_codes[] = {250, 421, 450, 500, 501, 502, 530, 550, 0};
1055 static const int rmd_codes[] = {250, 421, 500, 501, 502, 530, 550, 0};
1056 int ret;
1057
1060
1061 snprintf(command,
sizeof(command),
"DELE %s\r\n", s->
path);
1063 ret = 0;
1065 }
1066
1067 snprintf(command,
sizeof(command),
"RMD %s\r\n", s->
path);
1069 ret = 0;
1070 else
1072
1075 return ret;
1076 }
1077
1079 {
1082 static const int rnfr_codes[] = {350, 421, 450, 500, 501, 502, 503, 530, 0};
1083 static const int rnto_codes[] = {250, 421, 500, 501, 502, 503, 530, 532, 553, 0};
1084 int ret;
1085
1088
1089 snprintf(command,
sizeof(command),
"RNFR %s\r\n", s->
path);
1093 }
1094
1096 path, sizeof(path),
1098 snprintf(command,
sizeof(command),
"RNTO %s\r\n", path);
1100 ret = 0;
1101 else
1103
1106 return ret;
1107 }
1108
1119 .priv_data_class = &ftp_context_class,
1126 .default_whitelist = "tcp",
1127 };
time_t av_timegm(struct tm *tm)
Convert the decomposed UTC time in tm to a time_t value.
const URLProtocol ff_ftp_protocol
void av_url_split(char *proto, int proto_size, char *authorization, int authorization_size, char *hostname, int hostname_size, int *port_ptr, char *path, int path_size, const char *url)
Split a URL string into components.
void av_bprintf(AVBPrint *buf, const char *fmt,...)
int ffurl_open_whitelist(URLContext **puc, const char *filename, int flags, const AVIOInterruptCB *int_cb, AVDictionary **options, const char *whitelist, const char *blacklist, URLContext *parent)
Create an URLContext for accessing to the resource indicated by url, and open it. ...
#define URL_PROTOCOL_FLAG_NETWORK
static int ftp_get_line(FTPContext *s, char *line, int line_size)
char * password
Server user's password.
int64_t filemode
Unix file mode, -1 if unknown.
#define AV_LOG_WARNING
Something somehow does not look correct.
static int ftp_list(FTPContext *s)
static int ftp_move(URLContext *h_src, URLContext *h_dst)
#define LIBAVUTIL_VERSION_INT
static int ftp_file_size(FTPContext *s)
int ffurl_write(URLContext *h, const unsigned char *buf, int size)
Write size bytes from buf to the resource accessed by h.
char * av_stristr(const char *s1, const char *s2)
Locate the first case-independent occurrence in the string haystack of the string needle...
int is_streamed
true if streamed (no seek possible), default = false
AVIOInterruptCB interrupt_callback
Describes single entry of the directory.
#define AVIO_FLAG_READ
read-only
const char * av_default_item_name(void *ptr)
Return the context name.
static int ftp_connect(URLContext *h, const char *url)
#define AVIO_FLAG_WRITE
write-only
static int ftp_open(URLContext *h, const char *url, int flags)
uint8_t * control_buf_end
static int ftp_status(FTPContext *s, char **line, const int response_codes[])
int write_seekable
Control seekability, 0 = disable, 1 = enable.
static int ftp_retrieve(FTPContext *s)
int av_bprint_finalize(AVBPrint *buf, char **ret_str)
Finalize a print buffer.
int ffurl_shutdown(URLContext *h, int flags)
Signal the URLContext that we are done reading or writing the stream.
int64_t modification_timestamp
Time of last modification in microseconds since unix epoch, -1 if unknown.
const char * class_name
The name of the class; usually it is the same name as the context structure type to which the AVClass...
URLContext * conn_control
Control connection.
static int ftp_read_dir(URLContext *h, AVIODirEntry **next)
static int ftp_connect_data_connection(URLContext *h)
static int ftp_set_dir(FTPContext *s)
static int ftp_shutdown(URLContext *h, int flags)
static av_cold int end(AVCodecContext *avctx)
int64_t filesize
Size of file on server, -1 on error.
char * av_small_strptime(const char *p, const char *fmt, struct tm *dt)
Simplified version of strptime.
static int ftp_delete(URLContext *h)
static int ftp_connect_control_connection(URLContext *h)
uint8_t control_buffer[CONTROL_BUFFER_SIZE]
Control connection buffer.
static int ftp_current_dir(FTPContext *s)
uint8_t * control_buf_ptr
static int ftp_passive_mode(FTPContext *s)
int server_data_port
Data connection port opened by server, -1 on error.
FTPListingMethod listing_method
Called listing method.
static void * av_x_if_null(const void *p, const void *x)
Return x default pointer in case p is NULL.
static int ftp_getc(FTPContext *s)
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
const char * anonymous_password
Password to be used for anonymous user.
const char * protocol_whitelist
static int ftp_abort(URLContext *h)
void av_bprint_init(AVBPrint *buf, unsigned size_init, unsigned size_max)
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
void av_dict_free(AVDictionary **pm)
Free all the memory allocated for an AVDictionary struct and all keys and values. ...
static int ftp_send_command(FTPContext *s, const char *command, const int response_codes[], char **response)
static void ftp_close_both_connections(FTPContext *s)
static int ftp_passive_mode_epsv(FTPContext *s)
void avio_free_directory_entry(AVIODirEntry **entry)
Free entry allocated by avio_read_dir().
int rw_timeout
Network timeout.
common internal API header
static int ftp_parse_entry_nlst(char *line, AVIODirEntry *next)
static int ftp_read(URLContext *h, unsigned char *buf, int size)
static int ftp_close(URLContext *h)
URLContext * conn_data
Data connection, NULL when not connected.
int av_strcasecmp(const char *a, const char *b)
Locale-independent case-insensitive compare.
GLsizei GLboolean const GLfloat * value
static int ftp_auth(FTPContext *s)
int64_t position
Current position, calculated.
static int ftp_restart(FTPContext *s, int64_t pos)
char * features
List of server's features represented as raw response.
static int ftp_has_feature(FTPContext *s, const char *feature_name)
char * path
Path to resource on server.
int ffurl_get_file_handle(URLContext *h)
Return the file descriptor associated with this URL.
int64_t size
File size in bytes, -1 if unknown.
int ffurl_closep(URLContext **hh)
Close the resource accessed by the URLContext h, and free the memory used by it.
int ff_url_join(char *str, int size, const char *proto, const char *authorization, const char *hostname, int port, const char *fmt,...)
static int64_t ftp_seek(URLContext *h, int64_t pos, int whence)
#define AV_LOG_INFO
Standard information.
#define AV_BPRINT_SIZE_AUTOMATIC
char * av_strdup(const char *s)
Duplicate a string.
const char * protocol_blacklist
static int ftp_close_dir(URLContext *h)
int type
Type of the entry.
static int ftp_get_file_handle(URLContext *h)
static int command(AVFilterContext *ctx, const char *cmd, const char *arg, char *res, int res_len, int flags)
static const AVOption options[]
#define AVIO_FLAG_READ_WRITE
read-write pseudo flag
FTPState state
State of data connection.
Describe the class of an AVClass context structure.
int64_t group_id
Group ID of owner, -1 if unknown.
static void ftp_close_data_connection(FTPContext *s)
static int ftp_features(FTPContext *s)
static int ftp_parse_entry_mlsd(char *mlsd, AVIODirEntry *next)
#define CONTROL_BUFFER_SIZE
char * av_strtok(char *s, const char *delim, char **saveptr)
Split the string into several tokens which can be accessed by successive calls to av_strtok()...
static int ftp_write(URLContext *h, const unsigned char *buf, int size)
char * av_append_path_component(const char *path, const char *component)
Append path component to the existing path.
int av_dict_set_int(AVDictionary **pm, const char *key, int64_t value, int flags)
Convenience wrapper for av_dict_set that converts the value to a string and stores it...
AVIODirEntry * ff_alloc_dir_entry(void)
Allocate directory entry with default values.
char * filename
specified URL
#define AVSEEK_SIZE
ORing this as the "whence" parameter to a seek function causes it to return the filesize without seek...
char * hostname
Server address.
static int ftp_store(FTPContext *s)
static int ftp_type(FTPContext *s)
static int ftp_open_dir(URLContext *h)
int server_control_port
Control connection port, default is 21.
int64_t user_id
User ID of owner, -1 if unknown.
static int ftp_list_mlsd(FTPContext *s)
static const AVClass ftp_context_class
unbuffered private I/O API
static int64_t ftp_parse_date(const char *date)
static int ftp_parse_entry(URLContext *h, char *line, AVIODirEntry *next)
int ffurl_read(URLContext *h, unsigned char *buf, int size)
Read up to size bytes from the resource accessed by h, and store the read bytes in buf...
static av_cold void cleanup(FlashSV2Context *s)
uint8_t pi<< 24) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_U8,(uint64_t)((*(constuint8_t *) pi-0x80U))<< 56) CONV_FUNC(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_U8,(*(constuint8_t *) pi-0x80)*(1.0f/(1<< 7))) CONV_FUNC(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_U8,(*(constuint8_t *) pi-0x80)*(1.0/(1<< 7))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S16,(*(constint16_t *) pi >>8)+0x80) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_S16,(uint64_t)(*(constint16_t *) pi)<< 48) CONV_FUNC(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S16,*(constint16_t *) pi *(1.0f/(1<< 15))) CONV_FUNC(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S16,*(constint16_t *) pi *(1.0/(1<< 15))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S32,(*(constint32_t *) pi >>24)+0x80) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_S32,(uint64_t)(*(constint32_t *) pi)<< 32) CONV_FUNC(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S32,*(constint32_t *) pi *(1.0f/(1U<< 31))) CONV_FUNC(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S32,*(constint32_t *) pi *(1.0/(1U<< 31))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S64,(*(constint64_t *) pi >>56)+0x80) CONV_FUNC(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S64,*(constint64_t *) pi *(1.0f/(INT64_C(1)<< 63))) CONV_FUNC(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S64,*(constint64_t *) pi *(1.0/(INT64_C(1)<< 63))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_FLT, av_clip_uint8(lrintf(*(constfloat *) pi *(1<< 7))+0x80)) CONV_FUNC(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_FLT, av_clip_int16(lrintf(*(constfloat *) pi *(1<< 15)))) CONV_FUNC(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_FLT, av_clipl_int32(llrintf(*(constfloat *) pi *(1U<< 31)))) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_FLT, llrintf(*(constfloat *) pi *(INT64_C(1)<< 63))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_DBL, av_clip_uint8(lrint(*(constdouble *) pi *(1<< 7))+0x80)) CONV_FUNC(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_DBL, av_clip_int16(lrint(*(constdouble *) pi *(1<< 15)))) CONV_FUNC(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_DBL, av_clipl_int32(llrint(*(constdouble *) pi *(1U<< 31)))) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_DBL, llrint(*(constdouble *) pi *(INT64_C(1)<< 63)))#defineFMT_PAIR_FUNC(out, in) staticconv_func_type *constfmt_pair_to_conv_functions[AV_SAMPLE_FMT_NB *AV_SAMPLE_FMT_NB]={FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_S64), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S64), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_S64), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S64), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_S64), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_S64),};staticvoidcpy1(uint8_t **dst, constuint8_t **src, intlen){memcpy(*dst,*src, len);}staticvoidcpy2(uint8_t **dst, constuint8_t **src, intlen){memcpy(*dst,*src, 2 *len);}staticvoidcpy4(uint8_t **dst, constuint8_t **src, intlen){memcpy(*dst,*src, 4 *len);}staticvoidcpy8(uint8_t **dst, constuint8_t **src, intlen){memcpy(*dst,*src, 8 *len);}AudioConvert *swri_audio_convert_alloc(enumAVSampleFormatout_fmt, enumAVSampleFormatin_fmt, intchannels, constint *ch_map, intflags){AudioConvert *ctx;conv_func_type *f=fmt_pair_to_conv_functions[av_get_packed_sample_fmt(out_fmt)+AV_SAMPLE_FMT_NB *av_get_packed_sample_fmt(in_fmt)];if(!f) returnNULL;ctx=av_mallocz(sizeof(*ctx));if(!ctx) returnNULL;if(channels==1){in_fmt=av_get_planar_sample_fmt(in_fmt);out_fmt=av_get_planar_sample_fmt(out_fmt);}ctx->channels=channels;ctx->conv_f=f;ctx->ch_map=ch_map;if(in_fmt==AV_SAMPLE_FMT_U8||in_fmt==AV_SAMPLE_FMT_U8P) memset(ctx->silence, 0x80, sizeof(ctx->silence));if(out_fmt==in_fmt &&!ch_map){switch(av_get_bytes_per_sample(in_fmt)){case1:ctx->simd_f=cpy1;break;case2:ctx->simd_f=cpy2;break;case4:ctx->simd_f=cpy4;break;case8:ctx->simd_f=cpy8;break;}}if(HAVE_X86ASM &&1) swri_audio_convert_init_x86(ctx, out_fmt, in_fmt, channels);if(ARCH_ARM) swri_audio_convert_init_arm(ctx, out_fmt, in_fmt, channels);if(ARCH_AARCH64) swri_audio_convert_init_aarch64(ctx, out_fmt, in_fmt, channels);returnctx;}voidswri_audio_convert_free(AudioConvert **ctx){av_freep(ctx);}intswri_audio_convert(AudioConvert *ctx, AudioData *out, AudioData *in, intlen){intch;intoff=0;constintos=(out->planar?1:out->ch_count)*out->bps;unsignedmisaligned=0;av_assert0(ctx->channels==out->ch_count);if(ctx->in_simd_align_mask){intplanes=in->planar?in->ch_count:1;unsignedm=0;for(ch=0;ch< planes;ch++) m|=(intptr_t) in->ch[ch];misaligned|=m &ctx->in_simd_align_mask;}if(ctx->out_simd_align_mask){intplanes=out->planar?out->ch_count:1;unsignedm=0;for(ch=0;ch< planes;ch++) m|=(intptr_t) out->ch[ch];misaligned|=m &ctx->out_simd_align_mask;}if(ctx->simd_f &&!ctx->ch_map &&!misaligned){off=len &~15;av_assert1(off >=0);av_assert1(off<=len);av_assert2(ctx->channels==SWR_CH_MAX||!in->ch[ctx->channels]);if(off >0){if(out->planar==in->planar){intplanes=out->planar?out->ch_count:1;for(ch=0;ch< planes;ch++){ctx->simd_f(out-> ch ch
static int ftp_list_nlst(FTPContext *s)