static int ffserver_parse_config_redirect(FFServerConfig *config, const char *cmd, const char **p, FFServerStream **predirect) { FFServerStream *redirect; av_assert0(predirect); redirect = *predirect; if (!av_strcasecmp(cmd, "<Redirect")) { char *q; redirect = av_mallocz(sizeof(FFServerStream)); if (!redirect) return AVERROR(ENOMEM); ffserver_get_arg(redirect->filename, sizeof(redirect->filename), p); q = strrchr(redirect->filename, '>'); if (*q) *q = '\0'; redirect->stream_type = STREAM_TYPE_REDIRECT; *predirect = redirect; return 0; } av_assert0(redirect); if (!av_strcasecmp(cmd, "URL")) { ffserver_get_arg(redirect->feed_filename, sizeof(redirect->feed_filename), p); } else if (!av_strcasecmp(cmd, "</Redirect>")) { if (!redirect->feed_filename[0]) ERROR("No URL found for <Redirect>\n"); *predirect = NULL; } else { ERROR("Invalid entry '%s' inside <Redirect></Redirect>\n", cmd); } return 0; }
int av_parse_color(uint8_t *rgba_color, const char *color_string, int slen, void *log_ctx) { char *tail, color_string2[128]; const ColorEntry *entry; int len, hex_offset = 0; if (color_string[0] == '#') { hex_offset = 1; } else if (!strncmp(color_string, "0x", 2)) hex_offset = 2; if (slen < 0) slen = strlen(color_string); av_strlcpy(color_string2, color_string + hex_offset, FFMIN(slen-hex_offset+1, sizeof(color_string2))); if ((tail = strchr(color_string2, ALPHA_SEP))) *tail++ = 0; len = strlen(color_string2); rgba_color[3] = 255; if (!av_strcasecmp(color_string2, "random") || !av_strcasecmp(color_string2, "bikeshed")) { int rgba = av_get_random_seed(); rgba_color[0] = rgba >> 24; rgba_color[1] = rgba >> 16; rgba_color[2] = rgba >> 8; rgba_color[3] = rgba; } else if (hex_offset ||
void ff_metadata_conv(AVDictionary **pm, const AVMetadataConv *d_conv, const AVMetadataConv *s_conv) { /* TODO: use binary search to look up the two conversion tables if the tables are getting big enough that it would matter speed wise */ const AVMetadataConv *sc, *dc; AVDictionaryEntry *mtag = NULL; AVDictionary *dst = NULL; const char *key; if (d_conv == s_conv) return; while ((mtag = av_dict_get(*pm, "", mtag, AV_DICT_IGNORE_SUFFIX))) { key = mtag->key; if (s_conv) for (sc=s_conv; sc->native; sc++) if (!av_strcasecmp(key, sc->native)) { key = sc->generic; break; } if (d_conv) for (dc=d_conv; dc->native; dc++) if (!av_strcasecmp(key, dc->generic)) { key = dc->native; break; } av_dict_set(&dst, key, mtag->value, 0); } av_dict_free(pm); *pm = dst; }
static int handle_line(HTTPContext *c, char *line, int line_size, RequestData *rd) { char *p1, tmp[32], info[32]; const char *p = line; int len; get_word(tmp, sizeof(tmp), &p); if(!strcmp(tmp, "GET") || !strcmp(tmp, "POST")){ if (tmp[0]== 'G') c->post = 0; else if (tmp[0] == 'P') c->post = 1; else return -1; get_word(c->url, sizeof(c->url), &p); if(c->url[0] == '/'){ len = strlen(c->url)-1; memmove(c->url, c->url+1, len); c->url[len] = 0; } if(!c->url[0]){ av_strlcpy(c->url, "index.html", sizeof(c->url)); } get_word(tmp, sizeof(tmp), &p); if (strcmp(tmp, "HTTP/1.0") && strcmp(tmp, "HTTP/1.1")) return -1; p1 = strchr(c->url, '?'); if (p1) { av_strlcpy(info, p1, sizeof(info)); *p1 = '\0'; } else info[0] = '\0'; } else if(!strcmp(tmp, "Host:")){ get_word(rd->domain, sizeof(rd->domain), &p); } else if(!strcmp(tmp, "Cookie:")){ get_word(rd->cookie, sizeof(rd->cookie), &p); } else if(!strcmp(tmp, "Connection:")){ get_word(info, sizeof(info), &p); if(!av_strcasecmp(info, "keep-alive")){ c->keep_alive = 1; } } else if(!av_strcasecmp(tmp, "Content-Length:")){ get_word(info, sizeof(info), &p); c->content_length = atoi(info); } return 0; }
static int parse_multipart_header(AVIOContext *pb, void *log_ctx) { char line[128]; int found_content_type = 0; int ret, size = -1; ret = get_line(pb, line, sizeof(line)); if (ret < 0) return ret; if (strncmp(line, "--", 2)) return AVERROR_INVALIDDATA; while (!pb->eof_reached) { char *tag, *value; ret = get_line(pb, line, sizeof(line)); if (ret < 0) { if (ret == AVERROR_EOF) break; return ret; } if (line[0] == '\0') break; ret = split_tag_value(&tag, &value, line); if (ret < 0) return ret; if (!av_strcasecmp(tag, "Content-type")) { if (av_strcasecmp(value, "image/jpeg")) { if (log_ctx) { av_log(log_ctx, AV_LOG_ERROR, "Unexpected %s : %s\n", tag, value); } return AVERROR_INVALIDDATA; } else found_content_type = 1; } else if (!av_strcasecmp(tag, "Content-Length")) { size = parse_content_length(value); if (size < 0) return size; } } if (!found_content_type || size < 0) { return AVERROR_INVALIDDATA; } return size; }
static int check_content_type(char *line) { char *tag, *value; int ret = split_tag_value(&tag, &value, line); if (ret < 0) return ret; if (av_strcasecmp(tag, "Content-type") || av_strcasecmp(value, "image/jpeg")) return AVERROR_INVALIDDATA; return 0; }
static inline int parse_slave_failure_policy_option(const char *opt, TeeSlave *tee_slave) { if (!opt) { tee_slave->on_fail = DEFAULT_SLAVE_FAILURE_POLICY; return 0; } else if (!av_strcasecmp("abort", opt)) { tee_slave->on_fail = ON_SLAVE_FAILURE_ABORT; return 0; } else if (!av_strcasecmp("ignore", opt)) { tee_slave->on_fail = ON_SLAVE_FAILURE_IGNORE; return 0; } /* Set failure behaviour to abort, so invalid option error will not be ignored */ tee_slave->on_fail = ON_SLAVE_FAILURE_ABORT; return AVERROR(EINVAL); }
static int write_header(AVFormatContext *s) { VideoMuxData *img = s->priv_data; AVStream *st = s->streams[0]; const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(st->codec->pix_fmt); const char *proto = avio_find_protocol_name(s->filename); av_strlcpy(img->path, s->filename, sizeof(img->path)); /* find format */ if (s->oformat->flags & AVFMT_NOFILE) img->is_pipe = 0; else img->is_pipe = 1; if (st->codec->codec_id == AV_CODEC_ID_GIF) { img->muxer = "gif"; } else if (st->codec->codec_id == AV_CODEC_ID_RAWVIDEO) { const char *str = strrchr(img->path, '.'); img->split_planes = str && !av_strcasecmp(str + 1, "y") && s->nb_streams == 1 && desc &&(desc->flags & AV_PIX_FMT_FLAG_PLANAR) && desc->nb_components >= 3; } img->use_rename = img->use_rename < 0 ? proto && !strcmp(proto, "file") : img->use_rename; return 0; }
static int id3v1_create_tag(AVFormatContext *s, uint8_t *buf) { AVDictionaryEntry *tag; int i, count = 0; memset(buf, 0, ID3v1_TAG_SIZE); /* fail safe */ buf[0] = 'T'; buf[1] = 'A'; buf[2] = 'G'; count += id3v1_set_string(s, "TIT2", buf + 3, 30); //title count += id3v1_set_string(s, "TPE1", buf + 33, 30); //author|artist count += id3v1_set_string(s, "TALB", buf + 63, 30); //album count += id3v1_set_string(s, "TDRL", buf + 93, 4); //date count += id3v1_set_string(s, "comment", buf + 97, 30); if ((tag = av_dict_get(s->metadata, "TRCK", NULL, 0))) { //track buf[125] = 0; buf[126] = atoi(tag->value); count++; } buf[127] = 0xFF; /* default to unknown genre */ if ((tag = av_dict_get(s->metadata, "TCON", NULL, 0))) { //genre for(i = 0; i <= ID3v1_GENRE_MAX; i++) { if (!av_strcasecmp(tag->value, ff_id3v1_genre_str[i])) { buf[127] = i; count++; break; } } } return count; }
static int parse_fmtp(AVFormatContext *s, AVStream *stream, PayloadContext *data, const char *attr, const char *value) { AVCodecParameters *par = stream->codecpar; int res, i; if (!strcmp(attr, "config")) { res = parse_fmtp_config(par, value); if (res < 0) return res; } if (par->codec_id == AV_CODEC_ID_AAC) { /* Looking for a known attribute */ for (i = 0; attr_names[i].str; ++i) { if (!av_strcasecmp(attr, attr_names[i].str)) { if (attr_names[i].type == ATTR_NAME_TYPE_INT) { *(int *)((char *)data+ attr_names[i].offset) = atoi(value); } else if (attr_names[i].type == ATTR_NAME_TYPE_STR) *(char **)((char *)data+ attr_names[i].offset) = av_strdup(value); } } } return 0; }
void ff_http_auth_handle_header(HTTPAuthState *state, const char *key, const char *value) { if (!strcmp(key, "WWW-Authenticate") || !strcmp(key, "Proxy-Authenticate")) { const char *p; if (av_stristart(value, "Basic ", &p) && state->auth_type <= HTTP_AUTH_BASIC) { state->auth_type = HTTP_AUTH_BASIC; state->realm[0] = 0; state->stale = 0; ff_parse_key_value(p, (ff_parse_key_val_cb) handle_basic_params, state); } else if (av_stristart(value, "Digest ", &p) && state->auth_type <= HTTP_AUTH_DIGEST) { state->auth_type = HTTP_AUTH_DIGEST; memset(&state->digest_params, 0, sizeof(DigestParams)); state->realm[0] = 0; state->stale = 0; ff_parse_key_value(p, (ff_parse_key_val_cb) handle_digest_params, state); choose_qop(state->digest_params.qop, sizeof(state->digest_params.qop)); if (!av_strcasecmp(state->digest_params.stale, "true")) state->stale = 1; } } else if (!strcmp(key, "Authentication-Info")) { ff_parse_key_value(value, (ff_parse_key_val_cb) handle_digest_update, state); } }
int av_match_ext(const char *filename, const char *extensions) { const char *ext, *p; char ext1[32], *q; if (!filename) return 0; ext = strrchr(filename, '.'); if (ext) { ext++; p = extensions; for (;;) { q = ext1; while (*p != '\0' && *p != ',' && q - ext1 < sizeof(ext1) - 1) *q++ = *p++; *q = '\0'; if (!av_strcasecmp(ext1, ext)) return 1; if (*p == '\0') break; p++; } } return 0; }
AVOutputFormat *av_guess_format(const char *short_name, const char *filename, const char *mime_type) { AVOutputFormat *fmt = NULL, *fmt_found; int score_max, score; /* specific test for image sequences */ #if CONFIG_IMAGE2_MUXER if (!short_name && filename && av_filename_number_test(filename) && ff_guess_image2_codec(filename) != AV_CODEC_ID_NONE) { return av_guess_format("image2", NULL, NULL); } #endif /* Find the proper file type. */ fmt_found = NULL; score_max = 0; while ((fmt = av_oformat_next(fmt))) { score = 0; if (fmt->name && short_name && !av_strcasecmp(fmt->name, short_name)) score += 100; if (fmt->mime_type && mime_type && !strcmp(fmt->mime_type, mime_type)) score += 10; if (filename && fmt->extensions && av_match_ext(filename, fmt->extensions)) { score += 5; } if (score > score_max) { score_max = score; fmt_found = fmt; } } return fmt_found; }
static int get_color_mode_index(const char *name) { int i; for (i = 0; i < FF_ARRAY_ELEMS(color_modes); i++) if (!av_strcasecmp(color_modes[i], name)) return i; return -1; }
int af_str2fmt_short(const char* str) { int i; if(!str) return -1; for (i = 0; af_fmtstr_table[i].name; i++) if (!av_strcasecmp(str, af_fmtstr_table[i].name)) return af_fmtstr_table[i].format; return -1; }
enum AVCodecID ff_rtp_codec_id(const char *buf, enum AVMediaType codec_type) { int i; for (i = 0; rtp_payload_types[i].pt >= 0; i++) if (!av_strcasecmp(buf, rtp_payload_types[i].enc_name) && (codec_type == rtp_payload_types[i].codec_type)) return rtp_payload_types[i].codec_id; return AV_CODEC_ID_NONE; }
RTPDynamicProtocolHandler *ff_rtp_handler_find_by_name(const char *name, enum AVMediaType codec_type) { RTPDynamicProtocolHandler *handler; for (handler = rtp_first_dynamic_payload_handler; handler; handler = handler->next) if (!av_strcasecmp(name, handler->enc_name) && codec_type == handler->codec_type) return handler; return NULL; }
static enum CodecID av_str2id(const IdStrMap *tags, const char *str) { str= strrchr(str, '.'); if(!str) return CODEC_ID_NONE; str++; while (tags->id) { if (!av_strcasecmp(str, tags->str)) return tags->id; tags++; } return CODEC_ID_NONE; }
static int attachment_is_font(AVStream * st) { const AVDictionaryEntry *tag = NULL; int n; tag = av_dict_get(st->metadata, "mimetype", NULL, AV_DICT_MATCH_CASE); if (tag) { for (n = 0; font_mimetypes[n]; n++) { if (av_strcasecmp(font_mimetypes[n], tag->value) == 0) return 1; } } return 0; }
/** * To debug ffmpeg", type this command on the console before starting playback: * setprop debug.nam.ffmpeg 1 * To disable the debug, type: * setprop debug.nam.ffmpge 0 */ status_t initFFmpeg() { status_t ret = OK; bool debug_enabled = false; char value[PROPERTY_VALUE_MAX]; pthread_mutex_lock(&init_mutex); if (property_get("debug.nam.ffmpeg", value, NULL) && (!strcmp(value, "1") || !av_strcasecmp(value, "true"))) { LOGI("set ffmpeg debug level to AV_LOG_DEBUG"); debug_enabled = true; } if (debug_enabled) av_log_set_level(AV_LOG_DEBUG); else av_log_set_level(AV_LOG_INFO); if(ref_count == 0) { nam_av_log_set_flags(AV_LOG_SKIP_REPEATED); av_log_set_callback(nam_av_log_callback); /* register all codecs, demux and protocols */ avcodec_register_all(); #if CONFIG_AVDEVICE avdevice_register_all(); #endif av_register_all(); avformat_network_init(); /* register android source */ ffmpeg_register_android_source(); init_opts(); if (av_lockmgr_register(lockmgr)) { LOGE("could not initialize lock manager!"); ret = NO_INIT; } } // update counter ref_count++; pthread_mutex_unlock(&init_mutex); return ret; }
static int match_format(const char *name, const char *names) { const char *p; int len, namelen; if (!name || !names) return 0; namelen = strlen(name); while ((p = strchr(names, ','))) { len = FFMAX(p - names, namelen); if (!av_strncasecmp(name, names, len)) return 1; names = p + 1; } return !av_strcasecmp(name, names); }
static int parse_fmtp(AVFormatContext *s, AVStream *stream, PayloadContext *data, const char *attr, const char *value) { AVCodecParameters *par = stream->codecpar; int res, i; if (!strcmp(attr, "config")) { res = parse_fmtp_config(par, value); if (res < 0) return res; } if (par->codec_id == AV_CODEC_ID_AAC) { /* Looking for a known attribute */ for (i = 0; attr_names[i].str; ++i) { if (!av_strcasecmp(attr, attr_names[i].str)) { if (attr_names[i].type == ATTR_NAME_TYPE_INT) { int val = atoi(value); if (val > 32) { av_log(s, AV_LOG_ERROR, "The %s field size is invalid (%d)\n", attr, val); return AVERROR_INVALIDDATA; } *(int *)((char *)data+ attr_names[i].offset) = val; } else if (attr_names[i].type == ATTR_NAME_TYPE_STR) { char *val = av_strdup(value); if (!val) return AVERROR(ENOMEM); *(char **)((char *)data+ attr_names[i].offset) = val; } } } } return 0; }
static int color_table_compare(const void *lhs, const void *rhs) { return av_strcasecmp(lhs, ((const ColorEntry *)rhs)->name); }
static int ffserver_parse_config_global(FFServerConfig *config, const char *cmd, const char **p) { int val; char arg[1024]; if (!av_strcasecmp(cmd, "Port") || !av_strcasecmp(cmd, "HTTPPort")) { if (!av_strcasecmp(cmd, "Port")) WARNING("Port option is deprecated. Use HTTPPort instead.\n"); ffserver_get_arg(arg, sizeof(arg), p); ffserver_set_int_param(&val, arg, 0, 1, 65535, config, "Invalid port: %s\n", arg); if (val < 1024) WARNING("Trying to use IETF assigned system port: '%d'\n", val); config->http_addr.sin_port = htons(val); } else if (!av_strcasecmp(cmd, "HTTPBindAddress") || !av_strcasecmp(cmd, "BindAddress")) { if (!av_strcasecmp(cmd, "BindAddress")) WARNING("BindAddress option is deprecated. Use HTTPBindAddress " "instead.\n"); ffserver_get_arg(arg, sizeof(arg), p); if (resolve_host(&config->http_addr.sin_addr, arg)) ERROR("Invalid host/IP address: '%s'\n", arg); } else if (!av_strcasecmp(cmd, "NoDaemon")) { WARNING("NoDaemon option has no effect. You should remove it.\n"); } else if (!av_strcasecmp(cmd, "RTSPPort")) { ffserver_get_arg(arg, sizeof(arg), p); ffserver_set_int_param(&val, arg, 0, 1, 65535, config, "Invalid port: %s\n", arg); config->rtsp_addr.sin_port = htons(val); } else if (!av_strcasecmp(cmd, "RTSPBindAddress")) { ffserver_get_arg(arg, sizeof(arg), p); if (resolve_host(&config->rtsp_addr.sin_addr, arg)) ERROR("Invalid host/IP address: %s\n", arg); } else if (!av_strcasecmp(cmd, "MaxHTTPConnections")) { ffserver_get_arg(arg, sizeof(arg), p); ffserver_set_int_param(&val, arg, 0, 1, 65535, config, "Invalid MaxHTTPConnections: %s\n", arg); config->nb_max_http_connections = val; if (config->nb_max_connections > config->nb_max_http_connections) { ERROR("Inconsistent configuration: MaxClients(%d) > " "MaxHTTPConnections(%d)\n", config->nb_max_connections, config->nb_max_http_connections); } } else if (!av_strcasecmp(cmd, "MaxClients")) { ffserver_get_arg(arg, sizeof(arg), p); ffserver_set_int_param(&val, arg, 0, 1, 65535, config, "Invalid MaxClients: '%s'\n", arg); config->nb_max_connections = val; if (config->nb_max_connections > config->nb_max_http_connections) { ERROR("Inconsistent configuration: MaxClients(%d) > " "MaxHTTPConnections(%d)\n", config->nb_max_connections, config->nb_max_http_connections); } } else if (!av_strcasecmp(cmd, "MaxBandwidth")) { int64_t llval; char *tailp; ffserver_get_arg(arg, sizeof(arg), p); errno = 0; llval = strtoll(arg, &tailp, 10); if (llval < 10 || llval > 10000000 || tailp[0] || errno) ERROR("Invalid MaxBandwidth: '%s'\n", arg); else config->max_bandwidth = llval; } else if (!av_strcasecmp(cmd, "CustomLog")) { if (!config->debug) { ffserver_get_arg(config->logfilename, sizeof(config->logfilename), p); } } else if (!av_strcasecmp(cmd, "LoadModule")) { ERROR("Loadable modules are no longer supported\n"); } else if (!av_strcasecmp(cmd, "NoDefaults")) { config->use_defaults = 0; } else if (!av_strcasecmp(cmd, "UseDefaults")) { config->use_defaults = 1; } else ERROR("Incorrect keyword: '%s'\n", cmd); return 0; }
static int ffserver_parse_config_feed(FFServerConfig *config, const char *cmd, const char **p, FFServerStream **pfeed) { FFServerStream *feed; char arg[1024]; av_assert0(pfeed); feed = *pfeed; if (!av_strcasecmp(cmd, "<Feed")) { char *q; FFServerStream *s; feed = av_mallocz(sizeof(FFServerStream)); if (!feed) return AVERROR(ENOMEM); ffserver_get_arg(feed->filename, sizeof(feed->filename), p); q = strrchr(feed->filename, '>'); if (*q) *q = '\0'; for (s = config->first_feed; s; s = s->next) { if (!strcmp(feed->filename, s->filename)) ERROR("Feed '%s' already registered\n", s->filename); } feed->fmt = av_guess_format("ffm", NULL, NULL); /* default feed file */ snprintf(feed->feed_filename, sizeof(feed->feed_filename), "/tmp/%s.ffm", feed->filename); feed->feed_max_size = 5 * 1024 * 1024; feed->is_feed = 1; feed->feed = feed; /* self feeding :-) */ *pfeed = feed; return 0; } av_assert0(feed); if (!av_strcasecmp(cmd, "Launch")) { int i; feed->child_argv = av_mallocz_array(MAX_CHILD_ARGS, sizeof(char *)); if (!feed->child_argv) return AVERROR(ENOMEM); for (i = 0; i < MAX_CHILD_ARGS - 2; i++) { ffserver_get_arg(arg, sizeof(arg), p); if (!arg[0]) break; feed->child_argv[i] = av_strdup(arg); if (!feed->child_argv[i]) return AVERROR(ENOMEM); } feed->child_argv[i] = av_asprintf("http://%s:%d/%s", (config->http_addr.sin_addr.s_addr == INADDR_ANY) ? "127.0.0.1" : inet_ntoa(config->http_addr.sin_addr), ntohs(config->http_addr.sin_port), feed->filename); if (!feed->child_argv[i]) return AVERROR(ENOMEM); } else if (!av_strcasecmp(cmd, "ACL")) { ffserver_parse_acl_row(NULL, feed, NULL, *p, config->filename, config->line_num); } else if (!av_strcasecmp(cmd, "File") || !av_strcasecmp(cmd, "ReadOnlyFile")) { ffserver_get_arg(feed->feed_filename, sizeof(feed->feed_filename), p); feed->readonly = !av_strcasecmp(cmd, "ReadOnlyFile"); } else if (!av_strcasecmp(cmd, "Truncate")) { ffserver_get_arg(arg, sizeof(arg), p); /* assume Truncate is true in case no argument is specified */ if (!arg[0]) { feed->truncate = 1; } else { WARNING("Truncate N syntax in configuration file is deprecated. " "Use Truncate alone with no arguments.\n"); feed->truncate = strtod(arg, NULL); } } else if (!av_strcasecmp(cmd, "FileMaxSize")) { char *p1; double fsize; ffserver_get_arg(arg, sizeof(arg), p); p1 = arg; fsize = strtod(p1, &p1); switch(av_toupper(*p1)) { case 'K': fsize *= 1024; break; case 'M': fsize *= 1024 * 1024; break; case 'G': fsize *= 1024 * 1024 * 1024; break; default: ERROR("Invalid file size: '%s'\n", arg); break; } feed->feed_max_size = (int64_t)fsize; if (feed->feed_max_size < FFM_PACKET_SIZE*4) { ERROR("Feed max file size is too small. Must be at least %d.\n", FFM_PACKET_SIZE*4); } } else if (!av_strcasecmp(cmd, "</Feed>")) { *pfeed = NULL; } else { ERROR("Invalid entry '%s' inside <Feed></Feed>\n", cmd); } return 0; }
static int nist_read_header(AVFormatContext *s) { char buffer[32], coding[32] = "pcm", format[32] = "01"; int bps = 0, be = 0; int32_t header_size = -1; AVStream *st; st = avformat_new_stream(s, NULL); if (!st) return AVERROR(ENOMEM); st->codec->codec_type = AVMEDIA_TYPE_AUDIO; ff_get_line(s->pb, buffer, sizeof(buffer)); ff_get_line(s->pb, buffer, sizeof(buffer)); sscanf(buffer, "%"SCNd32, &header_size); if (header_size <= 0) return AVERROR_INVALIDDATA; while (!avio_feof(s->pb)) { ff_get_line(s->pb, buffer, sizeof(buffer)); if (avio_tell(s->pb) >= header_size) return AVERROR_INVALIDDATA; if (!memcmp(buffer, "end_head", 8)) { if (!st->codec->bits_per_coded_sample) st->codec->bits_per_coded_sample = bps << 3; if (!av_strcasecmp(coding, "pcm")) { st->codec->codec_id = ff_get_pcm_codec_id(st->codec->bits_per_coded_sample, 0, be, 0xFFFF); } else if (!av_strcasecmp(coding, "alaw")) { st->codec->codec_id = AV_CODEC_ID_PCM_ALAW; } else if (!av_strcasecmp(coding, "ulaw") || !av_strcasecmp(coding, "mu-law")) { st->codec->codec_id = AV_CODEC_ID_PCM_MULAW; } else { avpriv_request_sample(s, "coding %s", coding); } avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate); st->codec->block_align = st->codec->bits_per_coded_sample * st->codec->channels / 8; if (avio_tell(s->pb) > header_size) return AVERROR_INVALIDDATA; avio_skip(s->pb, header_size - avio_tell(s->pb)); return 0; } else if (!memcmp(buffer, "channel_count", 13)) { sscanf(buffer, "%*s %*s %"SCNd32, &st->codec->channels); } else if (!memcmp(buffer, "sample_byte_format", 18)) { sscanf(buffer, "%*s %*s %31s", format); if (!av_strcasecmp(format, "01")) { be = 0; } else if (!av_strcasecmp(format, "10")) { be = 1; } else if (av_strcasecmp(format, "1")) { avpriv_request_sample(s, "sample byte format %s", format); return AVERROR_PATCHWELCOME; } } else if (!memcmp(buffer, "sample_coding", 13)) { sscanf(buffer, "%*s %*s %31s", coding); } else if (!memcmp(buffer, "sample_count", 12)) { sscanf(buffer, "%*s %*s %"SCNd64, &st->duration); } else if (!memcmp(buffer, "sample_n_bytes", 14)) { sscanf(buffer, "%*s %*s %"SCNd32, &bps); } else if (!memcmp(buffer, "sample_rate", 11)) { sscanf(buffer, "%*s %*s %"SCNd32, &st->codec->sample_rate); } else if (!memcmp(buffer, "sample_sig_bits", 15)) { sscanf(buffer, "%*s %*s %"SCNd32, &st->codec->bits_per_coded_sample); } else { char key[32], value[32]; if (sscanf(buffer, "%31s %*s %31s", key, value) == 3) { av_dict_set(&s->metadata, key, value, AV_DICT_APPEND); } else { av_log(s, AV_LOG_ERROR, "Failed to parse '%s' as metadata\n", buffer); } } } return AVERROR_EOF; }
int av_probe_input_buffer2(AVIOContext *pb, AVInputFormat **fmt, const char *filename, void *logctx, unsigned int offset, unsigned int max_probe_size) { AVProbeData pd = { filename ? filename : "" }; uint8_t *buf = NULL; int ret = 0, probe_size, buf_offset = 0; int score = 0; int ret2; if (!max_probe_size) max_probe_size = PROBE_BUF_MAX; else if (max_probe_size < PROBE_BUF_MIN) { av_log(logctx, AV_LOG_ERROR, "Specified probe size value %u cannot be < %u\n", max_probe_size, PROBE_BUF_MIN); return AVERROR(EINVAL); } if (offset >= max_probe_size) return AVERROR(EINVAL); if (pb->av_class) { uint8_t *mime_type_opt = NULL; char *semi; av_opt_get(pb, "mime_type", AV_OPT_SEARCH_CHILDREN, &mime_type_opt); pd.mime_type = (const char *)mime_type_opt; semi = pd.mime_type ? strchr(pd.mime_type, ';') : NULL; if (semi) { *semi = '\0'; } } #if 0 if (!*fmt && pb->av_class && av_opt_get(pb, "mime_type", AV_OPT_SEARCH_CHILDREN, &mime_type) >= 0 && mime_type) { if (!av_strcasecmp(mime_type, "audio/aacp")) { *fmt = av_find_input_format("aac"); } av_freep(&mime_type); } #endif for (probe_size = PROBE_BUF_MIN; probe_size <= max_probe_size && !*fmt; probe_size = FFMIN(probe_size << 1, FFMAX(max_probe_size, probe_size + 1))) { score = probe_size < max_probe_size ? AVPROBE_SCORE_RETRY : 0; /* Read probe data. */ if ((ret = av_reallocp(&buf, probe_size + AVPROBE_PADDING_SIZE)) < 0) goto fail; if ((ret = avio_read(pb, buf + buf_offset, probe_size - buf_offset)) < 0) { /* Fail if error was not end of file, otherwise, lower score. */ if (ret != AVERROR_EOF) goto fail; score = 0; ret = 0; /* error was end of file, nothing read */ } buf_offset += ret; if (buf_offset < offset) continue; pd.buf_size = buf_offset - offset; pd.buf = &buf[offset]; memset(pd.buf + pd.buf_size, 0, AVPROBE_PADDING_SIZE); /* Guess file format. */ *fmt = av_probe_input_format2(&pd, 1, &score); if (*fmt) { /* This can only be true in the last iteration. */ if (score <= AVPROBE_SCORE_RETRY) { av_log(logctx, AV_LOG_WARNING, "Format %s detected only with low score of %d, " "misdetection possible!\n", (*fmt)->name, score); } else av_log(logctx, AV_LOG_DEBUG, "Format %s probed with size=%d and score=%d\n", (*fmt)->name, probe_size, score); #if 0 FILE *f = fopen("probestat.tmp", "ab"); fprintf(f, "probe_size:%d format:%s score:%d filename:%s\n", probe_size, (*fmt)->name, score, filename); fclose(f); #endif } } if (!*fmt) ret = AVERROR_INVALIDDATA; fail: /* Rewind. Reuse probe buffer to avoid seeking. */ ret2 = ffio_rewind_with_probe_data(pb, &buf, buf_offset); if (ret >= 0) ret = ret2; av_freep(&pd.mime_type); return ret < 0 ? ret : score; }
static int parse_multipart_header(AVIOContext *pb, int* size, const char* expected_boundary, void *log_ctx) { char line[128]; int found_content_type = 0; int ret; *size = -1; // get the CRLF as empty string ret = get_line(pb, line, sizeof(line)); if (ret < 0) return ret; /* some implementation do not provide the required * initial CRLF (see rfc1341 7.2.1) */ while (!line[0]) { ret = get_line(pb, line, sizeof(line)); if (ret < 0) return ret; } if (!av_strstart(line, expected_boundary, NULL)) { if (log_ctx) av_log(log_ctx, AV_LOG_ERROR, "Expected boundary '%s' not found, instead found a line of %zu bytes\n", expected_boundary, strlen(line)); return AVERROR_INVALIDDATA; } while (!pb->eof_reached) { char *tag, *value; ret = get_line(pb, line, sizeof(line)); if (ret < 0) { if (ret == AVERROR_EOF) break; return ret; } if (line[0] == '\0') break; ret = split_tag_value(&tag, &value, line); if (ret < 0) return ret; if (value==NULL || tag==NULL) break; if (!av_strcasecmp(tag, "Content-type")) { if (av_strcasecmp(value, "image/jpeg")) { if (log_ctx) av_log(log_ctx, AV_LOG_ERROR, "Unexpected %s : %s\n", tag, value); return AVERROR_INVALIDDATA; } else found_content_type = 1; } else if (!av_strcasecmp(tag, "Content-Length")) { *size = parse_content_length(value); if ( *size < 0 ) if (log_ctx) av_log(log_ctx, AV_LOG_WARNING, "Invalid Content-Length value : %s\n", value); } } return found_content_type ? 0 : AVERROR_INVALIDDATA; }
int ff_img_read_header(AVFormatContext *s1) { VideoDemuxData *s = s1->priv_data; int first_index = 1, last_index = 1; AVStream *st; enum AVPixelFormat pix_fmt = AV_PIX_FMT_NONE; s1->ctx_flags |= AVFMTCTX_NOHEADER; st = avformat_new_stream(s1, NULL); if (!st) { return AVERROR(ENOMEM); } if (s->pixel_format && (pix_fmt = av_get_pix_fmt(s->pixel_format)) == AV_PIX_FMT_NONE) { av_log(s1, AV_LOG_ERROR, "No such pixel format: %s.\n", s->pixel_format); return AVERROR(EINVAL); } av_strlcpy(s->path, s1->url, sizeof(s->path)); s->img_number = 0; s->img_count = 0; /* find format */ if (s1->iformat->flags & AVFMT_NOFILE) s->is_pipe = 0; else { s->is_pipe = 1; st->need_parsing = AVSTREAM_PARSE_FULL; } if (s->ts_from_file == 2) { #if !HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC av_log(s1, AV_LOG_ERROR, "POSIX.1-2008 not supported, nanosecond file timestamps unavailable\n"); return AVERROR(ENOSYS); #endif avpriv_set_pts_info(st, 64, 1, 1000000000); } else if (s->ts_from_file) avpriv_set_pts_info(st, 64, 1, 1); else avpriv_set_pts_info(st, 64, s->framerate.den, s->framerate.num); if (s->width && s->height) { st->codecpar->width = s->width; st->codecpar->height = s->height; } if (!s->is_pipe) { if (s->pattern_type == PT_DEFAULT) { if (s1->pb) { s->pattern_type = PT_NONE; } else s->pattern_type = PT_GLOB_SEQUENCE; } if (s->pattern_type == PT_GLOB_SEQUENCE) { s->use_glob = is_glob(s->path); if (s->use_glob) { #if HAVE_GLOB char *p = s->path, *q, *dup; int gerr; #endif av_log(s1, AV_LOG_WARNING, "Pattern type 'glob_sequence' is deprecated: " "use pattern_type 'glob' instead\n"); #if HAVE_GLOB dup = q = av_strdup(p); while (*q) { /* Do we have room for the next char and a \ insertion? */ if ((p - s->path) >= (sizeof(s->path) - 2)) break; if (*q == '%' && strspn(q + 1, "%*?[]{}")) ++q; else if (strspn(q, "\\*?[]{}")) *p++ = '\\'; *p++ = *q++; } *p = 0; av_free(dup); gerr = glob(s->path, GLOB_NOCHECK|GLOB_BRACE|GLOB_NOMAGIC, NULL, &s->globstate); if (gerr != 0) { return AVERROR(ENOENT); } first_index = 0; last_index = s->globstate.gl_pathc - 1; #endif } } if ((s->pattern_type == PT_GLOB_SEQUENCE && !s->use_glob) || s->pattern_type == PT_SEQUENCE) { if (find_image_range(s1->pb, &first_index, &last_index, s->path, s->start_number, s->start_number_range) < 0) { av_log(s1, AV_LOG_ERROR, "Could find no file with path '%s' and index in the range %d-%d\n", s->path, s->start_number, s->start_number + s->start_number_range - 1); return AVERROR(ENOENT); } } else if (s->pattern_type == PT_GLOB) { #if HAVE_GLOB int gerr; gerr = glob(s->path, GLOB_NOCHECK|GLOB_BRACE|GLOB_NOMAGIC, NULL, &s->globstate); if (gerr != 0) { return AVERROR(ENOENT); } first_index = 0; last_index = s->globstate.gl_pathc - 1; s->use_glob = 1; #else av_log(s1, AV_LOG_ERROR, "Pattern type 'glob' was selected but globbing " "is not supported by this libavformat build\n"); return AVERROR(ENOSYS); #endif } else if (s->pattern_type != PT_GLOB_SEQUENCE && s->pattern_type != PT_NONE) { av_log(s1, AV_LOG_ERROR, "Unknown value '%d' for pattern_type option\n", s->pattern_type); return AVERROR(EINVAL); } s->img_first = first_index; s->img_last = last_index; s->img_number = first_index; /* compute duration */ if (!s->ts_from_file) { st->start_time = 0; st->duration = last_index - first_index + 1; } } if (s1->video_codec_id) { st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO; st->codecpar->codec_id = s1->video_codec_id; } else if (s1->audio_codec_id) { st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO; st->codecpar->codec_id = s1->audio_codec_id; } else if (s1->iformat->raw_codec_id) { st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO; st->codecpar->codec_id = s1->iformat->raw_codec_id; } else { const char *str = strrchr(s->path, '.'); s->split_planes = str && !av_strcasecmp(str + 1, "y"); st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO; if (s1->pb) { int probe_buffer_size = 2048; uint8_t *probe_buffer = av_realloc(NULL, probe_buffer_size + AVPROBE_PADDING_SIZE); const AVInputFormat *fmt = NULL; void *fmt_iter = NULL; AVProbeData pd = { 0 }; if (!probe_buffer) return AVERROR(ENOMEM); probe_buffer_size = avio_read(s1->pb, probe_buffer, probe_buffer_size); if (probe_buffer_size < 0) { av_free(probe_buffer); return probe_buffer_size; } memset(probe_buffer + probe_buffer_size, 0, AVPROBE_PADDING_SIZE); pd.buf = probe_buffer; pd.buf_size = probe_buffer_size; pd.filename = s1->url; while ((fmt = av_demuxer_iterate(&fmt_iter))) { if (fmt->read_header != ff_img_read_header || !fmt->read_probe || (fmt->flags & AVFMT_NOFILE) || !fmt->raw_codec_id) continue; if (fmt->read_probe(&pd) > 0) { st->codecpar->codec_id = fmt->raw_codec_id; break; } } if (s1->flags & AVFMT_FLAG_CUSTOM_IO) { avio_seek(s1->pb, 0, SEEK_SET); } else ffio_rewind_with_probe_data(s1->pb, &probe_buffer, probe_buffer_size); } if (st->codecpar->codec_id == AV_CODEC_ID_NONE) st->codecpar->codec_id = ff_guess_image2_codec(s->path); if (st->codecpar->codec_id == AV_CODEC_ID_LJPEG) st->codecpar->codec_id = AV_CODEC_ID_MJPEG; if (st->codecpar->codec_id == AV_CODEC_ID_ALIAS_PIX) // we cannot distingiush this from BRENDER_PIX st->codecpar->codec_id = AV_CODEC_ID_NONE; } if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && pix_fmt != AV_PIX_FMT_NONE) st->codecpar->format = pix_fmt; return 0; }
static int ffserver_parse_config_stream(FFServerConfig *config, const char *cmd, const char **p, FFServerStream **pstream) { char arg[1024], arg2[1024]; FFServerStream *stream; int val; av_assert0(pstream); stream = *pstream; if (!av_strcasecmp(cmd, "<Stream")) { char *q; FFServerStream *s; stream = av_mallocz(sizeof(FFServerStream)); if (!stream) return AVERROR(ENOMEM); config->dummy_actx = avcodec_alloc_context3(NULL); config->dummy_vctx = avcodec_alloc_context3(NULL); if (!config->dummy_vctx || !config->dummy_actx) { av_free(stream); avcodec_free_context(&config->dummy_vctx); avcodec_free_context(&config->dummy_actx); return AVERROR(ENOMEM); } config->dummy_actx->codec_type = AVMEDIA_TYPE_AUDIO; config->dummy_vctx->codec_type = AVMEDIA_TYPE_VIDEO; ffserver_get_arg(stream->filename, sizeof(stream->filename), p); q = strrchr(stream->filename, '>'); if (q) *q = '\0'; for (s = config->first_stream; s; s = s->next) { if (!strcmp(stream->filename, s->filename)) ERROR("Stream '%s' already registered\n", s->filename); } stream->fmt = ffserver_guess_format(NULL, stream->filename, NULL); if (stream->fmt) { config->guessed_audio_codec_id = stream->fmt->audio_codec; config->guessed_video_codec_id = stream->fmt->video_codec; } else { config->guessed_audio_codec_id = AV_CODEC_ID_NONE; config->guessed_video_codec_id = AV_CODEC_ID_NONE; } config->stream_use_defaults = config->use_defaults; *pstream = stream; return 0; } av_assert0(stream); if (!av_strcasecmp(cmd, "Feed")) { FFServerStream *sfeed; ffserver_get_arg(arg, sizeof(arg), p); sfeed = config->first_feed; while (sfeed) { if (!strcmp(sfeed->filename, arg)) break; sfeed = sfeed->next_feed; } if (!sfeed) ERROR("Feed with name '%s' for stream '%s' is not defined\n", arg, stream->filename); else stream->feed = sfeed; } else if (!av_strcasecmp(cmd, "Format")) { ffserver_get_arg(arg, sizeof(arg), p); if (!strcmp(arg, "status")) { stream->stream_type = STREAM_TYPE_STATUS; stream->fmt = NULL; } else { stream->stream_type = STREAM_TYPE_LIVE; /* JPEG cannot be used here, so use single frame MJPEG */ if (!strcmp(arg, "jpeg")) { strcpy(arg, "singlejpeg"); stream->single_frame=1; } stream->fmt = ffserver_guess_format(arg, NULL, NULL); if (!stream->fmt) ERROR("Unknown Format: '%s'\n", arg); } if (stream->fmt) { config->guessed_audio_codec_id = stream->fmt->audio_codec; config->guessed_video_codec_id = stream->fmt->video_codec; } } else if (!av_strcasecmp(cmd, "InputFormat")) { ffserver_get_arg(arg, sizeof(arg), p); stream->ifmt = av_find_input_format(arg); if (!stream->ifmt) ERROR("Unknown input format: '%s'\n", arg); } else if (!av_strcasecmp(cmd, "FaviconURL")) { if (stream->stream_type == STREAM_TYPE_STATUS) ffserver_get_arg(stream->feed_filename, sizeof(stream->feed_filename), p); else ERROR("FaviconURL only permitted for status streams\n"); } else if (!av_strcasecmp(cmd, "Author") || !av_strcasecmp(cmd, "Comment") || !av_strcasecmp(cmd, "Copyright") || !av_strcasecmp(cmd, "Title")) { char key[32]; int i; ffserver_get_arg(arg, sizeof(arg), p); for (i = 0; i < strlen(cmd); i++) key[i] = av_tolower(cmd[i]); key[i] = 0; WARNING("Deprecated '%s' option in configuration file. Use " "'Metadata %s VALUE' instead.\n", cmd, key); if (av_dict_set(&stream->metadata, key, arg, 0) < 0) goto nomem; } else if (!av_strcasecmp(cmd, "Metadata")) { ffserver_get_arg(arg, sizeof(arg), p); ffserver_get_arg(arg2, sizeof(arg2), p); if (av_dict_set(&stream->metadata, arg, arg2, 0) < 0) goto nomem; } else if (!av_strcasecmp(cmd, "Preroll")) { ffserver_get_arg(arg, sizeof(arg), p); stream->prebuffer = atof(arg) * 1000; } else if (!av_strcasecmp(cmd, "StartSendOnKey")) { stream->send_on_key = 1; } else if (!av_strcasecmp(cmd, "AudioCodec")) { ffserver_get_arg(arg, sizeof(arg), p); ffserver_set_codec(config->dummy_actx, arg, config); } else if (!av_strcasecmp(cmd, "VideoCodec")) { ffserver_get_arg(arg, sizeof(arg), p); ffserver_set_codec(config->dummy_vctx, arg, config); } else if (!av_strcasecmp(cmd, "MaxTime")) { ffserver_get_arg(arg, sizeof(arg), p); stream->max_time = atof(arg) * 1000; } else if (!av_strcasecmp(cmd, "AudioBitRate")) { float f; ffserver_get_arg(arg, sizeof(arg), p); ffserver_set_float_param(&f, arg, 1000, -FLT_MAX, FLT_MAX, config, "Invalid %s: '%s'\n", cmd, arg); if (ffserver_save_avoption_int("b", (int64_t)lrintf(f), AV_OPT_FLAG_AUDIO_PARAM, config) < 0) goto nomem; } else if (!av_strcasecmp(cmd, "AudioChannels")) { ffserver_get_arg(arg, sizeof(arg), p); if (ffserver_save_avoption("ac", arg, AV_OPT_FLAG_AUDIO_PARAM, config) < 0) goto nomem; } else if (!av_strcasecmp(cmd, "AudioSampleRate")) { ffserver_get_arg(arg, sizeof(arg), p); if (ffserver_save_avoption("ar", arg, AV_OPT_FLAG_AUDIO_PARAM, config) < 0) goto nomem; } else if (!av_strcasecmp(cmd, "VideoBitRateRange")) { int minrate, maxrate; char *dash; ffserver_get_arg(arg, sizeof(arg), p); dash = strchr(arg, '-'); if (dash) { *dash = '\0'; dash++; if (ffserver_set_int_param(&minrate, arg, 1000, 0, INT_MAX, config, "Invalid %s: '%s'", cmd, arg) >= 0 && ffserver_set_int_param(&maxrate, dash, 1000, 0, INT_MAX, config, "Invalid %s: '%s'", cmd, arg) >= 0) { if (ffserver_save_avoption_int("minrate", minrate, AV_OPT_FLAG_VIDEO_PARAM, config) < 0 || ffserver_save_avoption_int("maxrate", maxrate, AV_OPT_FLAG_VIDEO_PARAM, config) < 0) goto nomem; } } else ERROR("Incorrect format for VideoBitRateRange. It should be " "<min>-<max>: '%s'.\n", arg); } else if (!av_strcasecmp(cmd, "Debug")) { ffserver_get_arg(arg, sizeof(arg), p); if (ffserver_save_avoption("debug", arg, AV_OPT_FLAG_AUDIO_PARAM, config) < 0 || ffserver_save_avoption("debug", arg, AV_OPT_FLAG_VIDEO_PARAM, config) < 0) goto nomem; } else if (!av_strcasecmp(cmd, "Strict")) { ffserver_get_arg(arg, sizeof(arg), p); if (ffserver_save_avoption("strict", arg, AV_OPT_FLAG_AUDIO_PARAM, config) < 0 || ffserver_save_avoption("strict", arg, AV_OPT_FLAG_VIDEO_PARAM, config) < 0) goto nomem; } else if (!av_strcasecmp(cmd, "VideoBufferSize")) { ffserver_get_arg(arg, sizeof(arg), p); ffserver_set_int_param(&val, arg, 8*1024, 0, INT_MAX, config, "Invalid %s: '%s'", cmd, arg); if (ffserver_save_avoption_int("bufsize", val, AV_OPT_FLAG_VIDEO_PARAM, config) < 0) goto nomem; } else if (!av_strcasecmp(cmd, "VideoBitRateTolerance")) { ffserver_get_arg(arg, sizeof(arg), p); ffserver_set_int_param(&val, arg, 1000, INT_MIN, INT_MAX, config, "Invalid %s: '%s'", cmd, arg); if (ffserver_save_avoption_int("bt", val, AV_OPT_FLAG_VIDEO_PARAM, config) < 0) goto nomem; } else if (!av_strcasecmp(cmd, "VideoBitRate")) { ffserver_get_arg(arg, sizeof(arg), p); ffserver_set_int_param(&val, arg, 1000, INT_MIN, INT_MAX, config, "Invalid %s: '%s'", cmd, arg); if (ffserver_save_avoption_int("b", val, AV_OPT_FLAG_VIDEO_PARAM, config) < 0) goto nomem; } else if (!av_strcasecmp(cmd, "VideoSize")) { int ret, w, h; ffserver_get_arg(arg, sizeof(arg), p); ret = av_parse_video_size(&w, &h, arg); if (ret < 0) ERROR("Invalid video size '%s'\n", arg); else { if (w % 2 || h % 2) WARNING("Image size is not a multiple of 2\n"); if (ffserver_save_avoption("video_size", arg, AV_OPT_FLAG_VIDEO_PARAM, config) < 0) goto nomem; } } else if (!av_strcasecmp(cmd, "VideoFrameRate")) { ffserver_get_arg(&arg[2], sizeof(arg) - 2, p); arg[0] = '1'; arg[1] = '/'; if (ffserver_save_avoption("time_base", arg, AV_OPT_FLAG_VIDEO_PARAM, config) < 0) goto nomem; } else if (!av_strcasecmp(cmd, "PixelFormat")) { enum AVPixelFormat pix_fmt; ffserver_get_arg(arg, sizeof(arg), p); pix_fmt = av_get_pix_fmt(arg); if (pix_fmt == AV_PIX_FMT_NONE) ERROR("Unknown pixel format: '%s'\n", arg); else if (ffserver_save_avoption("pixel_format", arg, AV_OPT_FLAG_VIDEO_PARAM, config) < 0) goto nomem; } else if (!av_strcasecmp(cmd, "VideoGopSize")) { ffserver_get_arg(arg, sizeof(arg), p); if (ffserver_save_avoption("g", arg, AV_OPT_FLAG_VIDEO_PARAM, config) < 0) goto nomem; } else if (!av_strcasecmp(cmd, "VideoIntraOnly")) { if (ffserver_save_avoption("g", "1", AV_OPT_FLAG_VIDEO_PARAM, config) < 0) goto nomem; } else if (!av_strcasecmp(cmd, "VideoHighQuality")) { if (ffserver_save_avoption("mbd", "+bits", AV_OPT_FLAG_VIDEO_PARAM, config) < 0) goto nomem; } else if (!av_strcasecmp(cmd, "Video4MotionVector")) { if (ffserver_save_avoption("mbd", "+bits", AV_OPT_FLAG_VIDEO_PARAM, config) < 0 || //FIXME remove ffserver_save_avoption("flags", "+mv4", AV_OPT_FLAG_VIDEO_PARAM, config) < 0) goto nomem; } else if (!av_strcasecmp(cmd, "AVOptionVideo") || !av_strcasecmp(cmd, "AVOptionAudio")) { int ret; ffserver_get_arg(arg, sizeof(arg), p); ffserver_get_arg(arg2, sizeof(arg2), p); if (!av_strcasecmp(cmd, "AVOptionVideo")) ret = ffserver_save_avoption(arg, arg2, AV_OPT_FLAG_VIDEO_PARAM, config); else ret = ffserver_save_avoption(arg, arg2, AV_OPT_FLAG_AUDIO_PARAM, config); if (ret < 0) goto nomem; } else if (!av_strcasecmp(cmd, "AVPresetVideo") || !av_strcasecmp(cmd, "AVPresetAudio")) { ffserver_get_arg(arg, sizeof(arg), p); if (!av_strcasecmp(cmd, "AVPresetVideo")) ffserver_opt_preset(arg, AV_OPT_FLAG_VIDEO_PARAM, config); else ffserver_opt_preset(arg, AV_OPT_FLAG_AUDIO_PARAM, config); } else if (!av_strcasecmp(cmd, "VideoTag")) { ffserver_get_arg(arg, sizeof(arg), p); if (strlen(arg) == 4 && ffserver_save_avoption_int("codec_tag", MKTAG(arg[0], arg[1], arg[2], arg[3]), AV_OPT_FLAG_VIDEO_PARAM, config) < 0) goto nomem; } else if (!av_strcasecmp(cmd, "BitExact")) { if (ffserver_save_avoption("flags", "+bitexact", AV_OPT_FLAG_VIDEO_PARAM, config) < 0) goto nomem; } else if (!av_strcasecmp(cmd, "DctFastint")) { if (ffserver_save_avoption("dct", "fastint", AV_OPT_FLAG_VIDEO_PARAM, config) < 0) goto nomem; } else if (!av_strcasecmp(cmd, "IdctSimple")) { if (ffserver_save_avoption("idct", "simple", AV_OPT_FLAG_VIDEO_PARAM, config) < 0) goto nomem; } else if (!av_strcasecmp(cmd, "Qscale")) { ffserver_get_arg(arg, sizeof(arg), p); ffserver_set_int_param(&val, arg, 0, INT_MIN, INT_MAX, config, "Invalid Qscale: '%s'\n", arg); if (ffserver_save_avoption("flags", "+qscale", AV_OPT_FLAG_VIDEO_PARAM, config) < 0 || ffserver_save_avoption_int("global_quality", FF_QP2LAMBDA * val, AV_OPT_FLAG_VIDEO_PARAM, config) < 0) goto nomem; } else if (!av_strcasecmp(cmd, "VideoQDiff")) { ffserver_get_arg(arg, sizeof(arg), p); if (ffserver_save_avoption("qdiff", arg, AV_OPT_FLAG_VIDEO_PARAM, config) < 0) goto nomem; } else if (!av_strcasecmp(cmd, "VideoQMax")) { ffserver_get_arg(arg, sizeof(arg), p); if (ffserver_save_avoption("qmax", arg, AV_OPT_FLAG_VIDEO_PARAM, config) < 0) goto nomem; } else if (!av_strcasecmp(cmd, "VideoQMin")) { ffserver_get_arg(arg, sizeof(arg), p); if (ffserver_save_avoption("qmin", arg, AV_OPT_FLAG_VIDEO_PARAM, config) < 0) goto nomem; } else if (!av_strcasecmp(cmd, "LumiMask")) { ffserver_get_arg(arg, sizeof(arg), p); if (ffserver_save_avoption("lumi_mask", arg, AV_OPT_FLAG_VIDEO_PARAM, config) < 0) goto nomem; } else if (!av_strcasecmp(cmd, "DarkMask")) { ffserver_get_arg(arg, sizeof(arg), p); if (ffserver_save_avoption("dark_mask", arg, AV_OPT_FLAG_VIDEO_PARAM, config) < 0) goto nomem; } else if (!av_strcasecmp(cmd, "NoVideo")) { config->no_video = 1; } else if (!av_strcasecmp(cmd, "NoAudio")) { config->no_audio = 1; } else if (!av_strcasecmp(cmd, "ACL")) { ffserver_parse_acl_row(stream, NULL, NULL, *p, config->filename, config->line_num); } else if (!av_strcasecmp(cmd, "DynamicACL")) { ffserver_get_arg(stream->dynamic_acl, sizeof(stream->dynamic_acl), p); } else if (!av_strcasecmp(cmd, "RTSPOption")) { ffserver_get_arg(arg, sizeof(arg), p); av_freep(&stream->rtsp_option); stream->rtsp_option = av_strdup(arg); } else if (!av_strcasecmp(cmd, "MulticastAddress")) { ffserver_get_arg(arg, sizeof(arg), p); if (resolve_host(&stream->multicast_ip, arg)) ERROR("Invalid host/IP address: '%s'\n", arg); stream->is_multicast = 1; stream->loop = 1; /* default is looping */ } else if (!av_strcasecmp(cmd, "MulticastPort")) { ffserver_get_arg(arg, sizeof(arg), p); ffserver_set_int_param(&val, arg, 0, 1, 65535, config, "Invalid MulticastPort: '%s'\n", arg); stream->multicast_port = val; } else if (!av_strcasecmp(cmd, "MulticastTTL")) { ffserver_get_arg(arg, sizeof(arg), p); ffserver_set_int_param(&val, arg, 0, INT_MIN, INT_MAX, config, "Invalid MulticastTTL: '%s'\n", arg); stream->multicast_ttl = val; } else if (!av_strcasecmp(cmd, "NoLoop")) { stream->loop = 0; } else if (!av_strcasecmp(cmd, "</Stream>")) { config->stream_use_defaults &= 1; if (stream->feed && stream->fmt && strcmp(stream->fmt->name, "ffm")) { if (config->dummy_actx->codec_id == AV_CODEC_ID_NONE) config->dummy_actx->codec_id = config->guessed_audio_codec_id; if (!config->no_audio && config->dummy_actx->codec_id != AV_CODEC_ID_NONE) { AVCodecContext *audio_enc = avcodec_alloc_context3(avcodec_find_encoder(config->dummy_actx->codec_id)); add_codec(stream, audio_enc, config); } if (config->dummy_vctx->codec_id == AV_CODEC_ID_NONE) config->dummy_vctx->codec_id = config->guessed_video_codec_id; if (!config->no_video && config->dummy_vctx->codec_id != AV_CODEC_ID_NONE) { AVCodecContext *video_enc = avcodec_alloc_context3(avcodec_find_encoder(config->dummy_vctx->codec_id)); add_codec(stream, video_enc, config); } } av_dict_free(&config->video_opts); av_dict_free(&config->audio_opts); avcodec_free_context(&config->dummy_vctx); avcodec_free_context(&config->dummy_actx); *pstream = NULL; } else if (!av_strcasecmp(cmd, "File") || !av_strcasecmp(cmd, "ReadOnlyFile")) { ffserver_get_arg(stream->feed_filename, sizeof(stream->feed_filename), p); } else if (!av_strcasecmp(cmd, "UseDefaults")) { if (config->stream_use_defaults > 1) WARNING("Multiple UseDefaults/NoDefaults entries.\n"); config->stream_use_defaults = 3; } else if (!av_strcasecmp(cmd, "NoDefaults")) { if (config->stream_use_defaults > 1) WARNING("Multiple UseDefaults/NoDefaults entries.\n"); config->stream_use_defaults = 2; } else { ERROR("Invalid entry '%s' inside <Stream></Stream>\n", cmd); } return 0; nomem: av_log(NULL, AV_LOG_ERROR, "Out of memory. Aborting.\n"); av_dict_free(&config->video_opts); av_dict_free(&config->audio_opts); avcodec_free_context(&config->dummy_vctx); avcodec_free_context(&config->dummy_actx); return AVERROR(ENOMEM); }