int url_open(URLContext **puc, const char *filename, int flags) { URLContext *uc; URLProtocol *up; const char *p; char proto_str[128], *q; int err; p = filename; q = proto_str; while (*p != '\0' && *p != ':') { /* protocols can only contain alphabetic chars */ if (!isalpha(*p)) goto file_proto; if ((q - proto_str) < sizeof(proto_str) - 1) *q++ = *p; p++; } /* if the protocol has length 1, we consider it is a dos drive */ if (*p == '\0' || (q - proto_str) <= 1) { file_proto: strcpy(proto_str, "file"); } else { *q = '\0'; } up = first_protocol; while (up != NULL) { if (!strcmp(proto_str, up->name)) goto found; up = up->next; } err = AVERROR(ENOENT); goto fail; found: uc = av_malloc(sizeof(URLContext) + strlen(filename) + 1); if (!uc) { err = AVERROR(ENOMEM); goto fail; } #if LIBAVFORMAT_VERSION_INT >= (52<<16) uc->filename = (char *) &uc[1]; #endif strcpy(uc->filename, filename); uc->prot = up; uc->flags = flags; uc->is_streamed = 0; /* default = not streamed */ uc->max_packet_size = 0; /* default: stream file */ err = up->url_open(uc, filename, flags); if (err < 0) { av_free(uc); *puc = NULL; return err; } *puc = uc; return 0; fail: *puc = NULL; return err; }
int url_open(URLContext **puc, const char *filename, int flags) { URLContext *uc; URLProtocol *up; const char *p; char proto_str[128], *q; int err; p = filename; q = proto_str; while (*p != '\0' && *p != ':') { if (!isalpha(*p)) // protocols can only contain alphabetic chars 协议头中包含特殊字符就是文件类型 goto file_proto; if ((q - proto_str) < sizeof(proto_str) - 1) *q++ = *p; //协议名放入proto_str p++; } // if the protocol has length 1, we consider it is a dos drive if (*p == '\0' || (q - proto_str) <= 1) { file_proto: strcpy(proto_str, "file"); } else { *q = '\0'; } up = first_protocol; while (up != NULL) { if (!strcmp(proto_str, up->name)) goto found; //找到后跳转 up = up->next; } err = - ENOENT; goto fail; found: uc = av_malloc(sizeof(URLContext) + strlen(filename)); if (!uc) { err = - ENOMEM; goto fail; } strcpy(uc->filename, filename); //strcpy拷贝的时候是包含最后一个'\0'的 uc->prot = up; //具体的源文件协议 uc->flags = flags; uc->max_packet_size = 0; // default: stream file err = up->url_open(uc, filename, flags); if (err < 0) { av_free(uc); *puc = NULL; return err; } *puc = uc; return 0; fail: *puc = NULL; return err; }