24 #include "config_components.h"
51 # define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO)
53 # define S_ISFIFO(m) 0
60 # define S_ISLNK(m) (((m) & S_IFLNK) == S_IFLNK)
69 # define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK)
71 # define S_ISSOCK(m) 0
78 # define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
87 # define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK)
150 if (
ret == 0 &&
c->follow)
175 const char *filename =
h->filename;
179 #if HAVE_ACCESS && defined(R_OK)
180 if (access(filename, F_OK) < 0)
183 if (access(filename, R_OK) >= 0)
186 if (access(filename, W_OK) >= 0)
190 ret = stat(filename, &st);
201 #if CONFIG_FD_PROTOCOL || CONFIG_PIPE_PROTOCOL
206 #ifdef F_DUPFD_CLOEXEC
207 newfd = fcntl(oldfd, F_DUPFD_CLOEXEC, 0);
215 if (fcntl(newfd, F_SETFD, FD_CLOEXEC) == -1)
239 if (
c->follow && (whence == SEEK_END || whence ==
AVSEEK_SIZE))
244 ret = fstat(
c->fd, &st);
248 ret = lseek(
c->fd,
pos, whence);
253 #if CONFIG_FILE_PROTOCOL
259 const char *filename =
h->filename;
262 ret = rmdir(filename);
263 if (
ret < 0 && (errno == ENOTDIR
268 ret = unlink(filename);
280 const char *filename_src = h_src->
filename;
281 const char *filename_dst = h_dst->
filename;
285 if (rename(filename_src, filename_dst) < 0)
301 access = O_CREAT | O_RDWR;
305 access = O_CREAT | O_WRONLY;
319 h->is_streamed = !fstat(fd, &st) &&
S_ISFIFO(st.st_mode);
322 h->max_packet_size =
c->pkt_size;
327 h->max_packet_size = 262144;
332 h->min_packet_size =
h->max_packet_size;
334 if (
c->seekable >= 0)
335 h->is_streamed = !
c->seekable;
345 c->dir = opendir(
h->filename);
360 char *fullpath =
NULL;
367 dir = readdir(
c->dir);
372 }
while (!strcmp(dir->d_name,
".") || !strcmp(dir->d_name,
".."));
377 if (!lstat(fullpath, &st)) {
378 if (S_ISDIR(st.st_mode))
382 else if (S_ISCHR(st.st_mode))
395 (*next)->group_id = st.st_gid;
396 (*next)->user_id = st.st_uid;
397 (*next)->size = st.st_size;
398 (*next)->filemode = st.st_mode & 0777;
399 (*next)->modification_timestamp = INT64_C(1000000) * st.st_mtime;
400 (*next)->access_timestamp = INT64_C(1000000) * st.st_atime;
401 (*next)->status_change_timestamp = INT64_C(1000000) * st.st_ctime;
426 .url_open = file_open,
433 .url_delete = file_delete,
434 .url_move = file_move,
437 .url_open_dir = file_open_dir,
438 .url_read_dir = file_read_dir,
439 .url_close_dir = file_close_dir,
440 .default_whitelist =
"file,crypto,data"
445 #if CONFIG_PIPE_PROTOCOL
463 fd = strtol(filename, &
final, 10);
470 c->fd = fd_dup(
h,
c->fd);
479 .url_open = pipe_open,
487 .default_whitelist =
"crypto,data"
492 #if CONFIG_FD_PROTOCOL
499 if (strcmp(filename,
"fd:") != 0) {
501 " please set it via -fd {num}\n");
512 if (fstat(
c->fd, &st) < 0)
515 c->fd = fd_dup(
h,
c->fd);
533 .default_whitelist =
"crypto,data"
538 #if CONFIG_ANDROID_CONTENT_PROTOCOL
543 typedef struct JFields {
547 jclass context_class;
548 jmethodID get_content_resolver_id;
550 jclass content_resolver_class;
551 jmethodID open_file_descriptor_id;
553 jclass parcel_file_descriptor_class;
554 jmethodID detach_fd_id;
557 #define OFFSET(x) offsetof(JFields, x)
558 static const struct FFJniField jfields_mapping[] = {
563 {
"android/content/Context",
"getContentResolver",
"()Landroid/content/ContentResolver;",
FF_JNI_METHOD,
OFFSET(get_content_resolver_id), 1 },
566 {
"android/content/ContentResolver",
"openFileDescriptor",
"(Landroid/net/Uri;Ljava/lang/String;)Landroid/os/ParcelFileDescriptor;",
FF_JNI_METHOD,
OFFSET(open_file_descriptor_id), 1 },
569 {
"android/os/ParcelFileDescriptor",
"detachFd",
"()I",
FF_JNI_METHOD,
OFFSET(detach_fd_id), 1 },
575 static int android_content_open(
URLContext *
h,
const char *filename,
int flags)
580 const char *mode_str =
"r";
583 JFields jfields = { 0 };
584 jobject application_context =
NULL;
588 jobject content_resolver =
NULL;
589 jobject parcel_file_descriptor =
NULL;
603 if (!application_context) {
626 uri = (*env)->CallStaticObjectMethod(env, jfields.uri_class, jfields.parse_id, url);
631 content_resolver = (*env)->CallObjectMethod(env, application_context, jfields.get_content_resolver_id);
636 parcel_file_descriptor = (*env)->CallObjectMethod(env, content_resolver, jfields.open_file_descriptor_id, uri,
mode);
640 if (!parcel_file_descriptor) {
646 fd = (*env)->CallIntMethod(env, parcel_file_descriptor, jfields.detach_fd_id);
651 if (fstat(fd, &st) < 0) {
660 (*env)->DeleteLocalRef(env, url);
661 (*env)->DeleteLocalRef(env,
mode);
662 (*env)->DeleteLocalRef(env, uri);
663 (*env)->DeleteLocalRef(env, content_resolver);
664 (*env)->DeleteLocalRef(env, parcel_file_descriptor);
670 static const AVOption android_content_options[] = {
675 static const AVClass android_content_class = {
678 .option = android_content_options,
684 .url_open = android_content_open,
692 .priv_data_class = &android_content_class,