static int print_link_prop(AVBPrint *buf, AVFilterLink *link) { char *format; char layout[64]; if (!buf) buf = &(AVBPrint){ 0 }; /* dummy buffer */ switch (link->type) { case AVMEDIA_TYPE_VIDEO: format = av_x_if_null(av_get_pix_fmt_name(link->format), "?"); av_bprintf(buf, "[%dx%d %d:%d %s]", link->w, link->h, link->sample_aspect_ratio.num, link->sample_aspect_ratio.den, format); break; case AVMEDIA_TYPE_AUDIO: av_get_channel_layout_string(layout, sizeof(layout), -1, link->channel_layout); format = av_x_if_null(av_get_sample_fmt_name(link->format), "?"); av_bprintf(buf, "[%dHz %s:%s:%s]", (int)link->sample_rate, format, layout, link->planar ? "planar" : "packed"); break; default: av_bprintf(buf, "?"); break; } return buf->len; }
int avfilter_link(AVFilterContext *src, unsigned srcpad, AVFilterContext *dst, unsigned dstpad) { AVFilterLink *link; if (src->nb_outputs <= srcpad || dst->nb_inputs <= dstpad || src->outputs[srcpad] || dst->inputs[dstpad]) return AVERROR(EINVAL); if (src->output_pads[srcpad].type != dst->input_pads[dstpad].type) { av_log(src, AV_LOG_ERROR, "Media type mismatch between the '%s' filter output pad %d (%s) and the '%s' filter input pad %d (%s)\n", src->name, srcpad, (char *)av_x_if_null(av_get_media_type_string(src->output_pads[srcpad].type), "?"), dst->name, dstpad, (char *)av_x_if_null(av_get_media_type_string(dst-> input_pads[dstpad].type), "?")); return AVERROR(EINVAL); } link = av_mallocz(sizeof(*link)); if (!link) return AVERROR(ENOMEM); src->outputs[srcpad] = dst->inputs[dstpad] = link; link->src = src; link->dst = dst; link->srcpad = &src->output_pads[srcpad]; link->dstpad = &dst->input_pads[dstpad]; link->type = src->output_pads[srcpad].type; av_assert0(AV_PIX_FMT_NONE == -1 && AV_SAMPLE_FMT_NONE == -1); link->format = -1; return 0; }
static int end_frame(AVFilterLink *inlink) { AVFilterContext *ctx = inlink->dst; BufferSinkContext *buf = inlink->dst->priv; av_assert1(inlink->cur_buf); if (av_fifo_space(buf->fifo) < sizeof(AVFilterBufferRef *)) { /* realloc fifo size */ if (av_fifo_realloc2(buf->fifo, av_fifo_size(buf->fifo) * 2) < 0) { av_log(ctx, AV_LOG_ERROR, "Cannot buffer more frames. Consume some available frames " "before adding new ones.\n"); return AVERROR(ENOMEM); } } /* cache frame */ av_fifo_generic_write(buf->fifo, &inlink->cur_buf, sizeof(AVFilterBufferRef *), NULL); inlink->cur_buf = NULL; if (buf->warning_limit && av_fifo_size(buf->fifo) / sizeof(AVFilterBufferRef *) >= buf->warning_limit) { av_log(ctx, AV_LOG_WARNING, "%d buffers queued in %s, something may be wrong.\n", buf->warning_limit, (char *)av_x_if_null(ctx->name, ctx->filter->name)); buf->warning_limit *= 10; } return 0; }
static av_cold int data_open(URLContext *h, const char *uri, int flags) { DataContext *dc = h->priv_data; const char *data, *opt, *next; char *ddata; int ret, base64 = 0; size_t in_size; /* data:content/type[;base64],payload */ av_strstart(uri, "data:", &uri); data = strchr(uri, ','); if (!data) { av_log(h, AV_LOG_ERROR, "No ',' delimiter in URI\n"); return AVERROR(EINVAL); } opt = uri; while (opt < data) { next = av_x_if_null(memchr(opt, ';', data - opt), data); if (opt == uri) { if (!memchr(opt, '/', next - opt)) { /* basic validity check */ av_log(h, AV_LOG_ERROR, "Invalid content-type '%.*s'\n", (int)(next - opt), opt); return AVERROR(EINVAL); } av_log(h, AV_LOG_VERBOSE, "Content-type: %.*s\n", (int)(next - opt), opt); } else { if (!av_strncasecmp(opt, "base64", next - opt)) { base64 = 1; } else { av_log(h, AV_LOG_VERBOSE, "Ignoring option '%.*s'\n", (int)(next - opt), opt); } } opt = next + 1; } data++; in_size = strlen(data); if (base64) { size_t out_size = 3 * (in_size / 4) + 1; if (out_size > INT_MAX || !(ddata = av_malloc(out_size))) return AVERROR(ENOMEM); if ((ret = av_base64_decode(ddata, data, out_size)) < 0) { av_free(ddata); av_log(h, AV_LOG_ERROR, "Invalid base64 in URI\n"); return ret; } dc->data = dc->tofree = ddata; dc->size = ret; } else { dc->data = data; dc->size = in_size; } return 0; }
static int filter_frame(AVFilterLink *link, AVFrame *frame) { AVFilterContext *ctx = link->dst; BufferSinkContext *buf = link->dst->priv; int ret; if ((ret = add_buffer_ref(ctx, frame)) < 0) return ret; if (buf->warning_limit && av_fifo_size(buf->fifo) / sizeof(AVFilterBufferRef *) >= buf->warning_limit) { av_log(ctx, AV_LOG_WARNING, "%d buffers queued in %s, something may be wrong.\n", buf->warning_limit, (char *)av_x_if_null(ctx->name, ctx->filter->name)); buf->warning_limit *= 10; } return 0; }
static av_cold int init_video(AVFilterContext *ctx) { BufferSourceContext *c = ctx->priv; if (c->pix_fmt == AV_PIX_FMT_NONE || !c->w || !c->h || av_q2d(c->time_base) <= 0) { av_log(ctx, AV_LOG_ERROR, "Invalid parameters provided.\n"); return AVERROR(EINVAL); } if (!(c->fifo = av_fifo_alloc(sizeof(AVFrame*)))) return AVERROR(ENOMEM); av_log(ctx, AV_LOG_VERBOSE, "w:%d h:%d pixfmt:%s tb:%d/%d fr:%d/%d sar:%d/%d sws_param:%s\n", c->w, c->h, av_get_pix_fmt_name(c->pix_fmt), c->time_base.num, c->time_base.den, c->frame_rate.num, c->frame_rate.den, c->pixel_aspect.num, c->pixel_aspect.den, (char *)av_x_if_null(c->sws_param, "")); c->warning_limit = 100; return 0; }
static int avi_write_header(AVFormatContext *s) { AVIContext *avi = s->priv_data; AVIOContext *pb = s->pb; int bitrate, n, i, nb_frames, au_byterate, au_ssize, au_scale; AVCodecContext *stream, *video_enc; int64_t list1, list2, strh, strf; AVDictionaryEntry *t = NULL; if (s->nb_streams > AVI_MAX_STREAM_COUNT) { av_log(s, AV_LOG_ERROR, "AVI does not support >%d streams\n", AVI_MAX_STREAM_COUNT); return AVERROR(EINVAL); } for(n=0;n<s->nb_streams;n++) { s->streams[n]->priv_data= av_mallocz(sizeof(AVIStream)); if(!s->streams[n]->priv_data) return AVERROR(ENOMEM); } /* header list */ avi->riff_id = 0; list1 = avi_start_new_riff(s, pb, "AVI ", "hdrl"); /* avi header */ ffio_wfourcc(pb, "avih"); avio_wl32(pb, 14 * 4); bitrate = 0; video_enc = NULL; for(n=0;n<s->nb_streams;n++) { stream = s->streams[n]->codec; bitrate += stream->bit_rate; if (stream->codec_type == AVMEDIA_TYPE_VIDEO) video_enc = stream; } nb_frames = 0; if(video_enc){ avio_wl32(pb, (uint32_t)(INT64_C(1000000) * video_enc->time_base.num / video_enc->time_base.den)); } else { avio_wl32(pb, 0); } avio_wl32(pb, bitrate / 8); /* XXX: not quite exact */ avio_wl32(pb, 0); /* padding */ if (!pb->seekable) avio_wl32(pb, AVIF_TRUSTCKTYPE | AVIF_ISINTERLEAVED); /* flags */ else avio_wl32(pb, AVIF_TRUSTCKTYPE | AVIF_HASINDEX | AVIF_ISINTERLEAVED); /* flags */ avi->frames_hdr_all = avio_tell(pb); /* remember this offset to fill later */ avio_wl32(pb, nb_frames); /* nb frames, filled later */ avio_wl32(pb, 0); /* initial frame */ avio_wl32(pb, s->nb_streams); /* nb streams */ avio_wl32(pb, 1024 * 1024); /* suggested buffer size */ if(video_enc){ avio_wl32(pb, video_enc->width); avio_wl32(pb, video_enc->height); } else { avio_wl32(pb, 0); avio_wl32(pb, 0); } avio_wl32(pb, 0); /* reserved */ avio_wl32(pb, 0); /* reserved */ avio_wl32(pb, 0); /* reserved */ avio_wl32(pb, 0); /* reserved */ /* stream list */ for(i=0;i<n;i++) { AVIStream *avist= s->streams[i]->priv_data; list2 = ff_start_tag(pb, "LIST"); ffio_wfourcc(pb, "strl"); stream = s->streams[i]->codec; /* stream generic header */ strh = ff_start_tag(pb, "strh"); switch(stream->codec_type) { case AVMEDIA_TYPE_SUBTITLE: // XSUB subtitles behave like video tracks, other subtitles // are not (yet) supported. if (stream->codec_id != AV_CODEC_ID_XSUB) { av_log(s, AV_LOG_ERROR, "Subtitle streams other than DivX XSUB are not supported by the AVI muxer.\n"); return AVERROR_PATCHWELCOME; } case AVMEDIA_TYPE_VIDEO: ffio_wfourcc(pb, "vids"); break; case AVMEDIA_TYPE_AUDIO: ffio_wfourcc(pb, "auds"); break; // case AVMEDIA_TYPE_TEXT : ffio_wfourcc(pb, "txts"); break; case AVMEDIA_TYPE_DATA : ffio_wfourcc(pb, "dats"); break; } if(stream->codec_type == AVMEDIA_TYPE_VIDEO || stream->codec_id == AV_CODEC_ID_XSUB) avio_wl32(pb, stream->codec_tag); else avio_wl32(pb, 1); avio_wl32(pb, 0); /* flags */ avio_wl16(pb, 0); /* priority */ avio_wl16(pb, 0); /* language */ avio_wl32(pb, 0); /* initial frame */ ff_parse_specific_params(stream, &au_byterate, &au_ssize, &au_scale); if ( stream->codec_type == AVMEDIA_TYPE_VIDEO && stream->codec_id != AV_CODEC_ID_XSUB && au_byterate > 1000LL*au_scale) { au_byterate = 600; au_scale = 1; } avpriv_set_pts_info(s->streams[i], 64, au_scale, au_byterate); if(stream->codec_id == AV_CODEC_ID_XSUB) au_scale = au_byterate = 0; avio_wl32(pb, au_scale); /* scale */ avio_wl32(pb, au_byterate); /* rate */ avio_wl32(pb, 0); /* start */ avist->frames_hdr_strm = avio_tell(pb); /* remember this offset to fill later */ if (!pb->seekable) avio_wl32(pb, AVI_MAX_RIFF_SIZE); /* FIXME: this may be broken, but who cares */ else avio_wl32(pb, 0); /* length, XXX: filled later */ /* suggested buffer size */ //FIXME set at the end to largest chunk if(stream->codec_type == AVMEDIA_TYPE_VIDEO) avio_wl32(pb, 1024 * 1024); else if(stream->codec_type == AVMEDIA_TYPE_AUDIO) avio_wl32(pb, 12 * 1024); else avio_wl32(pb, 0); avio_wl32(pb, -1); /* quality */ avio_wl32(pb, au_ssize); /* sample size */ avio_wl32(pb, 0); avio_wl16(pb, stream->width); avio_wl16(pb, stream->height); ff_end_tag(pb, strh); if(stream->codec_type != AVMEDIA_TYPE_DATA){ int ret; strf = ff_start_tag(pb, "strf"); switch(stream->codec_type) { case AVMEDIA_TYPE_SUBTITLE: // XSUB subtitles behave like video tracks, other subtitles // are not (yet) supported. if (stream->codec_id != AV_CODEC_ID_XSUB) break; case AVMEDIA_TYPE_VIDEO: ff_put_bmp_header(pb, stream, ff_codec_bmp_tags, 0, 0); break; case AVMEDIA_TYPE_AUDIO: if ((ret = ff_put_wav_header(pb, stream)) < 0) { return ret; } break; default: av_log(s, AV_LOG_ERROR, "Invalid or not supported codec type '%s' found in the input\n", (char *)av_x_if_null(av_get_media_type_string(stream->codec_type), "?")); return AVERROR(EINVAL); } ff_end_tag(pb, strf); if ((t = av_dict_get(s->streams[i]->metadata, "title", NULL, 0))) { ff_riff_write_info_tag(s->pb, "strn", t->value); t = NULL; } if(stream->codec_id == AV_CODEC_ID_XSUB && (t = av_dict_get(s->streams[i]->metadata, "language", NULL, 0))) { const char* langstr = av_convert_lang_to(t->value, AV_LANG_ISO639_1); t = NULL; if (langstr) { char* str = av_asprintf("Subtitle - %s-xx;02", langstr); ff_riff_write_info_tag(s->pb, "strn", str); av_free(str); } } } if (pb->seekable) { unsigned char tag[5]; int j; /* Starting to lay out AVI OpenDML master index. * We want to make it JUNK entry for now, since we'd * like to get away without making AVI an OpenDML one * for compatibility reasons. */ avist->indexes.entry = avist->indexes.ents_allocated = 0; avist->indexes.indx_start = ff_start_tag(pb, "JUNK"); avio_wl16(pb, 4); /* wLongsPerEntry */ avio_w8(pb, 0); /* bIndexSubType (0 == frame index) */ avio_w8(pb, 0); /* bIndexType (0 == AVI_INDEX_OF_INDEXES) */ avio_wl32(pb, 0); /* nEntriesInUse (will fill out later on) */ ffio_wfourcc(pb, avi_stream2fourcc(tag, i, stream->codec_type)); /* dwChunkId */ avio_wl64(pb, 0); /* dwReserved[3] avio_wl32(pb, 0); Must be 0. */ for (j=0; j < AVI_MASTER_INDEX_SIZE * 2; j++) avio_wl64(pb, 0); ff_end_tag(pb, avist->indexes.indx_start); } if( stream->codec_type == AVMEDIA_TYPE_VIDEO && s->streams[i]->sample_aspect_ratio.num>0 && s->streams[i]->sample_aspect_ratio.den>0){ int vprp= ff_start_tag(pb, "vprp"); AVRational dar = av_mul_q(s->streams[i]->sample_aspect_ratio, (AVRational){stream->width, stream->height}); int num, den; av_reduce(&num, &den, dar.num, dar.den, 0xFFFF); avio_wl32(pb, 0); //video format = unknown avio_wl32(pb, 0); //video standard= unknown avio_wl32(pb, lrintf(1.0/av_q2d(stream->time_base))); avio_wl32(pb, stream->width ); avio_wl32(pb, stream->height); avio_wl16(pb, den); avio_wl16(pb, num); avio_wl32(pb, stream->width ); avio_wl32(pb, stream->height); avio_wl32(pb, 1); //progressive FIXME avio_wl32(pb, stream->height); avio_wl32(pb, stream->width ); avio_wl32(pb, stream->height); avio_wl32(pb, stream->width ); avio_wl32(pb, 0); avio_wl32(pb, 0); avio_wl32(pb, 0); avio_wl32(pb, 0); ff_end_tag(pb, vprp); } ff_end_tag(pb, list2); } if (pb->seekable) { /* AVI could become an OpenDML one, if it grows beyond 2Gb range */ avi->odml_list = ff_start_tag(pb, "JUNK"); ffio_wfourcc(pb, "odml"); ffio_wfourcc(pb, "dmlh"); avio_wl32(pb, 248); for (i = 0; i < 248; i+= 4) avio_wl32(pb, 0); ff_end_tag(pb, avi->odml_list); } ff_end_tag(pb, list1); ff_riff_write_info(s); /* some padding for easier tag editing */ list2 = ff_start_tag(pb, "JUNK"); for (i = 0; i < 1016; i += 4) avio_wl32(pb, 0); ff_end_tag(pb, list2); avi->movi_list = ff_start_tag(pb, "LIST"); ffio_wfourcc(pb, "movi"); avio_flush(pb); return 0; }
int VideoDecoder::video_thread(void *arg) { VideoState *is = (VideoState *) arg; AVStreamsParser* ps = is->getAVStreamsParser(); AVFrame *frame = av_frame_alloc(); double pts; double duration; int ret; AVRational tb = ps->video_st->time_base; AVRational frame_rate = av_guess_frame_rate(ps->ic, ps->video_st, NULL); #if CONFIG_AVFILTER AVFilterGraph *graph = avfilter_graph_alloc(); AVFilterContext *filt_out = NULL, *filt_in = NULL; int last_w = 0; int last_h = 0; enum AVPixelFormat last_format = (AVPixelFormat) (-2); int last_serial = -1; int last_vfilter_idx = 0; if (!graph) { av_frame_free(&frame); return AVERROR(ENOMEM); } #endif if (!frame) { #if CONFIG_AVFILTER avfilter_graph_free(&graph); #endif return AVERROR(ENOMEM); } for (;;) { ret = is->viddec().get_video_frame(is, frame); if (ret < 0) goto the_end; if (!ret) continue; #if CONFIG_AVFILTER if ( last_w != frame->width || last_h != frame->height || last_format != frame->format || last_serial != is->viddec().pkt_serial || last_vfilter_idx != is->vfilter_idx) { av_log(NULL, AV_LOG_DEBUG, "Video frame changed from size:%dx%d format:%s serial:%d to size:%dx%d format:%s serial:%d\n", last_w, last_h, (const char *)av_x_if_null(av_get_pix_fmt_name(last_format), "none"), last_serial, frame->width, frame->height, (const char *)av_x_if_null(av_get_pix_fmt_name((AVPixelFormat)frame->format), "none"), is->viddec().pkt_serial); avfilter_graph_free(&graph); graph = avfilter_graph_alloc(); if ((ret = configure_video_filters(graph, is,gOptions.vfilters_list ? gOptions.vfilters_list[is->vfilter_idx] : NULL, frame)) < 0) { SDL_Event event; event.type = FF_QUIT_EVENT; event.user.data1 = is; SDL_PushEvent(&event); goto the_end; } filt_in = is->in_video_filter; filt_out = is->out_video_filter; last_w = frame->width; last_h = frame->height; last_format = (AVPixelFormat) frame->format; last_serial = is->viddec().pkt_serial; last_vfilter_idx = is->vfilter_idx; frame_rate = filt_out->inputs[0]->frame_rate; } ret = av_buffersrc_add_frame(filt_in, frame); if (ret < 0) goto the_end; while (ret >= 0) { is->frame_last_returned_time = av_gettime_relative() / 1000000.0; ret = av_buffersink_get_frame_flags(filt_out, frame, 0); if (ret < 0) { if (ret == AVERROR_EOF) is->viddec().finished = is->viddec().pkt_serial; ret = 0; break; } is->frame_last_filter_delay = av_gettime_relative() / 1000000.0 - is->frame_last_returned_time; if (fabs(is->frame_last_filter_delay) > AV_NOSYNC_THRESHOLD / 10.0) is->frame_last_filter_delay = 0; tb = filt_out->inputs[0]->time_base; #endif duration = (frame_rate.num && frame_rate.den ? av_q2d((AVRational){frame_rate.den, frame_rate.num}) : 0); pts = (frame->pts == AV_NOPTS_VALUE) ? NAN : frame->pts * av_q2d(tb); ret = queue_picture(is, frame, pts, duration, av_frame_get_pkt_pos(frame), is->viddec().pkt_serial); av_frame_unref(frame); #if CONFIG_AVFILTER } #endif if (ret < 0) goto the_end; } the_end: #if CONFIG_AVFILTER avfilter_graph_free(&graph); #endif av_frame_free(&frame); return 0; }
static av_cold int init(AVFilterContext *ctx) { LADSPAContext *s = ctx->priv; LADSPA_Descriptor_Function descriptor_fn; const LADSPA_Descriptor *desc; LADSPA_PortDescriptor pd; AVFilterPad pad = { NULL }; char *p, *arg, *saveptr = NULL; unsigned long nb_ports; int i; if (!s->dl_name) { av_log(ctx, AV_LOG_ERROR, "No plugin name provided\n"); return AVERROR(EINVAL); } if (s->dl_name[0] == '/' || s->dl_name[0] == '.') { // argument is a path s->dl_handle = dlopen(s->dl_name, RTLD_LOCAL|RTLD_NOW); } else { // argument is a shared object name char *paths = av_strdup(getenv("LADSPA_PATH")); const char *separator = ":"; if (paths) { p = paths; while ((arg = av_strtok(p, separator, &saveptr)) && !s->dl_handle) { s->dl_handle = try_load(arg, s->dl_name); p = NULL; } } av_free(paths); if (!s->dl_handle && (paths = av_asprintf("%s/.ladspa/lib", getenv("HOME")))) { s->dl_handle = try_load(paths, s->dl_name); av_free(paths); } if (!s->dl_handle) s->dl_handle = try_load("/usr/local/lib/ladspa", s->dl_name); if (!s->dl_handle) s->dl_handle = try_load("/usr/lib/ladspa", s->dl_name); } if (!s->dl_handle) { av_log(ctx, AV_LOG_ERROR, "Failed to load '%s'\n", s->dl_name); return AVERROR(EINVAL); } descriptor_fn = dlsym(s->dl_handle, "ladspa_descriptor"); if (!descriptor_fn) { av_log(ctx, AV_LOG_ERROR, "Could not find ladspa_descriptor: %s\n", dlerror()); return AVERROR(EINVAL); } // Find the requested plugin, or list plugins if (!s->plugin) { av_log(ctx, AV_LOG_INFO, "The '%s' library contains the following plugins:\n", s->dl_name); av_log(ctx, AV_LOG_INFO, "I = Input Channels\n"); av_log(ctx, AV_LOG_INFO, "O = Output Channels\n"); av_log(ctx, AV_LOG_INFO, "I:O %-25s %s\n", "Plugin", "Description"); av_log(ctx, AV_LOG_INFO, "\n"); for (i = 0; desc = descriptor_fn(i); i++) { unsigned long inputs = 0, outputs = 0; count_ports(desc, &inputs, &outputs); av_log(ctx, AV_LOG_INFO, "%lu:%lu %-25s %s\n", inputs, outputs, desc->Label, av_x_if_null(desc->Name, "?")); av_log(ctx, AV_LOG_VERBOSE, "Maker: %s\n", av_x_if_null(desc->Maker, "?")); av_log(ctx, AV_LOG_VERBOSE, "Copyright: %s\n", av_x_if_null(desc->Copyright, "?")); } return AVERROR_EXIT; } else { for (i = 0;; i++) { desc = descriptor_fn(i); if (!desc) { av_log(ctx, AV_LOG_ERROR, "Could not find plugin: %s\n", s->plugin); return AVERROR(EINVAL); } if (desc->Label && !strcmp(desc->Label, s->plugin)) break; } } s->desc = desc; nb_ports = desc->PortCount; s->ipmap = av_calloc(nb_ports, sizeof(*s->ipmap)); s->opmap = av_calloc(nb_ports, sizeof(*s->opmap)); s->icmap = av_calloc(nb_ports, sizeof(*s->icmap)); s->ocmap = av_calloc(nb_ports, sizeof(*s->ocmap)); s->ictlv = av_calloc(nb_ports, sizeof(*s->ictlv)); s->octlv = av_calloc(nb_ports, sizeof(*s->octlv)); s->ctl_needs_value = av_calloc(nb_ports, sizeof(*s->ctl_needs_value)); if (!s->ipmap || !s->opmap || !s->icmap || !s->ocmap || !s->ictlv || !s->octlv || !s->ctl_needs_value) return AVERROR(ENOMEM); for (i = 0; i < nb_ports; i++) { pd = desc->PortDescriptors[i]; if (LADSPA_IS_PORT_AUDIO(pd)) { if (LADSPA_IS_PORT_INPUT(pd)) { s->ipmap[s->nb_inputs] = i; s->nb_inputs++; } else if (LADSPA_IS_PORT_OUTPUT(pd)) { s->opmap[s->nb_outputs] = i; s->nb_outputs++; } } else if (LADSPA_IS_PORT_CONTROL(pd)) { if (LADSPA_IS_PORT_INPUT(pd)) { s->icmap[s->nb_inputcontrols] = i; if (LADSPA_IS_HINT_HAS_DEFAULT(desc->PortRangeHints[i].HintDescriptor)) set_default_ctl_value(s, s->nb_inputcontrols, s->icmap, s->ictlv); else s->ctl_needs_value[s->nb_inputcontrols] = 1; s->nb_inputcontrols++; } else if (LADSPA_IS_PORT_OUTPUT(pd)) { s->ocmap[s->nb_outputcontrols] = i; s->nb_outputcontrols++; } } } // List Control Ports if "help" is specified if (s->options && !strcmp(s->options, "help")) { if (!s->nb_inputcontrols) { av_log(ctx, AV_LOG_INFO, "The '%s' plugin does not have any input controls.\n", desc->Label); } else { av_log(ctx, AV_LOG_INFO, "The '%s' plugin has the following input controls:\n", desc->Label); for (i = 0; i < s->nb_inputcontrols; i++) print_ctl_info(ctx, AV_LOG_INFO, s, i, s->icmap, s->ictlv, 0); } return AVERROR_EXIT; } // Parse control parameters p = s->options; while (s->options) { LADSPA_Data val; int ret; if (!(arg = av_strtok(p, "|", &saveptr))) break; p = NULL; if (sscanf(arg, "c%d=%f", &i, &val) != 2) { av_log(ctx, AV_LOG_ERROR, "Invalid syntax.\n"); return AVERROR(EINVAL); } if ((ret = set_control(ctx, i, val)) < 0) return ret; s->ctl_needs_value[i] = 0; } // Check if any controls are not set for (i = 0; i < s->nb_inputcontrols; i++) { if (s->ctl_needs_value[i]) { av_log(ctx, AV_LOG_ERROR, "Control c%d must be set.\n", i); print_ctl_info(ctx, AV_LOG_ERROR, s, i, s->icmap, s->ictlv, 0); return AVERROR(EINVAL); } } pad.type = AVMEDIA_TYPE_AUDIO; if (s->nb_inputs) { pad.name = av_asprintf("in0:%s%lu", desc->Label, s->nb_inputs); if (!pad.name) return AVERROR(ENOMEM); pad.filter_frame = filter_frame; pad.config_props = config_input; if (ff_insert_inpad(ctx, ctx->nb_inputs, &pad) < 0) { av_freep(&pad.name); return AVERROR(ENOMEM); } } av_log(ctx, AV_LOG_DEBUG, "ports: %lu\n", nb_ports); av_log(ctx, AV_LOG_DEBUG, "inputs: %lu outputs: %lu\n", s->nb_inputs, s->nb_outputs); av_log(ctx, AV_LOG_DEBUG, "input controls: %lu output controls: %lu\n", s->nb_inputcontrols, s->nb_outputcontrols); return 0; }
static int init_filters(const char *filters_descr) { char args[512]; int ret = 0; AVFilter *abuffersrc = avfilter_get_by_name("abuffer"); AVFilter *abuffersink = avfilter_get_by_name("abuffersink"); AVFilterInOut *outputs = avfilter_inout_alloc(); AVFilterInOut *inputs = avfilter_inout_alloc(); static const enum AVSampleFormat out_sample_fmts[] = { AV_SAMPLE_FMT_S16, -1 }; static const int64_t out_channel_layouts[] = { AV_CH_LAYOUT_MONO, -1 }; static const int out_sample_rates[] = { 8000, -1 }; const AVFilterLink *outlink; AVRational time_base = fmt_ctx->streams[audio_stream_index]->time_base; filter_graph = avfilter_graph_alloc(); if (!outputs || !inputs || !filter_graph) { ret = AVERROR(ENOMEM); goto end; } /* buffer audio source: the decoded frames from the decoder will be inserted here. */ if (!dec_ctx->channel_layout) dec_ctx->channel_layout = av_get_default_channel_layout(dec_ctx->channels); snprintf(args, sizeof(args), "time_base=%d/%d:sample_rate=%d:sample_fmt=%s:channel_layout=0x%"PRIx64, time_base.num, time_base.den, dec_ctx->sample_rate, av_get_sample_fmt_name(dec_ctx->sample_fmt), dec_ctx->channel_layout); ret = avfilter_graph_create_filter(&buffersrc_ctx, abuffersrc, "in", args, NULL, filter_graph); if (ret < 0) { av_log(NULL, AV_LOG_ERROR, "Cannot create audio buffer source\n"); goto end; } /* buffer audio sink: to terminate the filter chain. */ ret = avfilter_graph_create_filter(&buffersink_ctx, abuffersink, "out", NULL, NULL, filter_graph); if (ret < 0) { av_log(NULL, AV_LOG_ERROR, "Cannot create audio buffer sink\n"); goto end; } ret = av_opt_set_int_list(buffersink_ctx, "sample_fmts", out_sample_fmts, -1, AV_OPT_SEARCH_CHILDREN); if (ret < 0) { av_log(NULL, AV_LOG_ERROR, "Cannot set output sample format\n"); goto end; } ret = av_opt_set_int_list(buffersink_ctx, "channel_layouts", out_channel_layouts, -1, AV_OPT_SEARCH_CHILDREN); if (ret < 0) { av_log(NULL, AV_LOG_ERROR, "Cannot set output channel layout\n"); goto end; } ret = av_opt_set_int_list(buffersink_ctx, "sample_rates", out_sample_rates, -1, AV_OPT_SEARCH_CHILDREN); if (ret < 0) { av_log(NULL, AV_LOG_ERROR, "Cannot set output sample rate\n"); goto end; } /* Endpoints for the filter graph. */ outputs->name = av_strdup("in"); outputs->filter_ctx = buffersrc_ctx; outputs->pad_idx = 0; outputs->next = NULL; inputs->name = av_strdup("out"); inputs->filter_ctx = buffersink_ctx; inputs->pad_idx = 0; inputs->next = NULL; if ((ret = avfilter_graph_parse_ptr(filter_graph, filters_descr, &inputs, &outputs, NULL)) < 0) goto end; if ((ret = avfilter_graph_config(filter_graph, NULL)) < 0) goto end; /* Print summary of the sink buffer * Note: args buffer is reused to store channel layout string */ outlink = buffersink_ctx->inputs[0]; av_get_channel_layout_string(args, sizeof(args), -1, outlink->channel_layout); av_log(NULL, AV_LOG_INFO, "Output: srate:%dHz fmt:%s chlayout:%s\n", (int)outlink->sample_rate, (char *)av_x_if_null(av_get_sample_fmt_name(outlink->format), "?"), args); end: avfilter_inout_free(&inputs); avfilter_inout_free(&outputs); return ret; }
static int avi_write_header(AVFormatContext *s) { AVIContext *avi = s->priv_data; AVIOContext *pb = s->pb; int bitrate, n, i, nb_frames, au_byterate, au_ssize, au_scale; AVCodecContext *video_enc; AVStream *video_st = NULL; int64_t list1, list2, strh, strf; AVDictionaryEntry *t = NULL; int padding; if (s->nb_streams > AVI_MAX_STREAM_COUNT) { av_log(s, AV_LOG_ERROR, "AVI does not support >%d streams\n", AVI_MAX_STREAM_COUNT); return AVERROR(EINVAL); } for (n = 0; n < s->nb_streams; n++) { s->streams[n]->priv_data = av_mallocz(sizeof(AVIStream)); if (!s->streams[n]->priv_data) return AVERROR(ENOMEM); } /* header list */ avi->riff_id = 0; list1 = avi_start_new_riff(s, pb, "AVI ", "hdrl"); /* avi header */ ffio_wfourcc(pb, "avih"); avio_wl32(pb, 14 * 4); bitrate = 0; video_enc = NULL; for (n = 0; n < s->nb_streams; n++) { AVCodecContext *codec = s->streams[n]->codec; bitrate += codec->bit_rate; if (codec->codec_type == AVMEDIA_TYPE_VIDEO) { video_enc = codec; video_st = s->streams[n]; } } nb_frames = 0; // TODO: should be avg_frame_rate if (video_st) avio_wl32(pb, (uint32_t) (INT64_C(1000000) * video_st->time_base.num / video_st->time_base.den)); else avio_wl32(pb, 0); avio_wl32(pb, bitrate / 8); /* XXX: not quite exact */ avio_wl32(pb, 0); /* padding */ if (!pb->seekable) avio_wl32(pb, AVIF_TRUSTCKTYPE | AVIF_ISINTERLEAVED); /* flags */ else avio_wl32(pb, AVIF_TRUSTCKTYPE | AVIF_HASINDEX | AVIF_ISINTERLEAVED); /* flags */ avi->frames_hdr_all = avio_tell(pb); /* remember this offset to fill later */ avio_wl32(pb, nb_frames); /* nb frames, filled later */ avio_wl32(pb, 0); /* initial frame */ avio_wl32(pb, s->nb_streams); /* nb streams */ avio_wl32(pb, 1024 * 1024); /* suggested buffer size */ if (video_enc) { avio_wl32(pb, video_enc->width); avio_wl32(pb, video_enc->height); } else { avio_wl32(pb, 0); avio_wl32(pb, 0); } avio_wl32(pb, 0); /* reserved */ avio_wl32(pb, 0); /* reserved */ avio_wl32(pb, 0); /* reserved */ avio_wl32(pb, 0); /* reserved */ /* stream list */ for (i = 0; i < n; i++) { AVStream *st = s->streams[i]; AVCodecContext *enc = st->codec; AVIStream *avist = st->priv_data; list2 = ff_start_tag(pb, "LIST"); ffio_wfourcc(pb, "strl"); /* stream generic header */ strh = ff_start_tag(pb, "strh"); switch (enc->codec_type) { case AVMEDIA_TYPE_SUBTITLE: // XSUB subtitles behave like video tracks, other subtitles // are not (yet) supported. if (enc->codec_id != AV_CODEC_ID_XSUB) { av_log(s, AV_LOG_ERROR, "Subtitle streams other than DivX XSUB are not supported by the AVI muxer.\n"); return AVERROR_PATCHWELCOME; } case AVMEDIA_TYPE_VIDEO: ffio_wfourcc(pb, "vids"); break; case AVMEDIA_TYPE_AUDIO: ffio_wfourcc(pb, "auds"); break; // case AVMEDIA_TYPE_TEXT: // ffio_wfourcc(pb, "txts"); // break; case AVMEDIA_TYPE_DATA: ffio_wfourcc(pb, "dats"); break; } if (enc->codec_type == AVMEDIA_TYPE_VIDEO || enc->codec_id == AV_CODEC_ID_XSUB) avio_wl32(pb, enc->codec_tag); else avio_wl32(pb, 1); avio_wl32(pb, 0); /* flags */ avio_wl16(pb, 0); /* priority */ avio_wl16(pb, 0); /* language */ avio_wl32(pb, 0); /* initial frame */ ff_parse_specific_params(st, &au_byterate, &au_ssize, &au_scale); if ( enc->codec_type == AVMEDIA_TYPE_VIDEO && enc->codec_id != AV_CODEC_ID_XSUB && au_byterate > 1000LL*au_scale) { au_byterate = 600; au_scale = 1; } avpriv_set_pts_info(st, 64, au_scale, au_byterate); if (enc->codec_id == AV_CODEC_ID_XSUB) au_scale = au_byterate = 0; avio_wl32(pb, au_scale); /* scale */ avio_wl32(pb, au_byterate); /* rate */ avio_wl32(pb, 0); /* start */ /* remember this offset to fill later */ avist->frames_hdr_strm = avio_tell(pb); if (!pb->seekable) /* FIXME: this may be broken, but who cares */ avio_wl32(pb, AVI_MAX_RIFF_SIZE); else avio_wl32(pb, 0); /* length, XXX: filled later */ /* suggested buffer size, is set to largest chunk size in avi_write_trailer */ if (enc->codec_type == AVMEDIA_TYPE_VIDEO) avio_wl32(pb, 1024 * 1024); else if (enc->codec_type == AVMEDIA_TYPE_AUDIO) avio_wl32(pb, 12 * 1024); else avio_wl32(pb, 0); avio_wl32(pb, -1); /* quality */ avio_wl32(pb, au_ssize); /* sample size */ avio_wl32(pb, 0); avio_wl16(pb, enc->width); avio_wl16(pb, enc->height); ff_end_tag(pb, strh); if (enc->codec_type != AVMEDIA_TYPE_DATA) { int ret; enum AVPixelFormat pix_fmt; strf = ff_start_tag(pb, "strf"); switch (enc->codec_type) { case AVMEDIA_TYPE_SUBTITLE: /* XSUB subtitles behave like video tracks, other subtitles * are not (yet) supported. */ if (enc->codec_id != AV_CODEC_ID_XSUB) break; case AVMEDIA_TYPE_VIDEO: /* WMP expects RGB 5:5:5 rawvideo in avi to have bpp set to 16. */ if ( !enc->codec_tag && enc->codec_id == AV_CODEC_ID_RAWVIDEO && enc->pix_fmt == AV_PIX_FMT_RGB555LE && enc->bits_per_coded_sample == 15) enc->bits_per_coded_sample = 16; ff_put_bmp_header(pb, enc, ff_codec_bmp_tags, 0, 0); pix_fmt = avpriv_find_pix_fmt(avpriv_pix_fmt_bps_avi, enc->bits_per_coded_sample); if ( !enc->codec_tag && enc->codec_id == AV_CODEC_ID_RAWVIDEO && enc->pix_fmt != pix_fmt && enc->pix_fmt != AV_PIX_FMT_NONE) av_log(s, AV_LOG_ERROR, "%s rawvideo cannot be written to avi, output file will be unreadable\n", av_get_pix_fmt_name(enc->pix_fmt)); break; case AVMEDIA_TYPE_AUDIO: if ((ret = ff_put_wav_header(pb, enc, 0)) < 0) return ret; break; default: av_log(s, AV_LOG_ERROR, "Invalid or not supported codec type '%s' found in the input\n", (char *)av_x_if_null(av_get_media_type_string(enc->codec_type), "?")); return AVERROR(EINVAL); } ff_end_tag(pb, strf); if ((t = av_dict_get(st->metadata, "title", NULL, 0))) { ff_riff_write_info_tag(s->pb, "strn", t->value); t = NULL; } if (enc->codec_id == AV_CODEC_ID_XSUB && (t = av_dict_get(s->streams[i]->metadata, "language", NULL, 0))) { const char* langstr = av_convert_lang_to(t->value, AV_LANG_ISO639_1); t = NULL; if (langstr) { char* str = av_asprintf("Subtitle - %s-xx;02", langstr); if (!str) return AVERROR(ENOMEM); ff_riff_write_info_tag(s->pb, "strn", str); av_free(str); } } } if (pb->seekable) { write_odml_master(s, i); } if (enc->codec_type == AVMEDIA_TYPE_VIDEO && st->sample_aspect_ratio.num > 0 && st->sample_aspect_ratio.den > 0) { int vprp = ff_start_tag(pb, "vprp"); AVRational dar = av_mul_q(st->sample_aspect_ratio, (AVRational) { enc->width, enc->height }); int num, den; av_reduce(&num, &den, dar.num, dar.den, 0xFFFF); avio_wl32(pb, 0); // video format = unknown avio_wl32(pb, 0); // video standard = unknown // TODO: should be avg_frame_rate avio_wl32(pb, (2LL*st->time_base.den + st->time_base.num - 1) / (2LL * st->time_base.num)); avio_wl32(pb, enc->width); avio_wl32(pb, enc->height); avio_wl16(pb, den); avio_wl16(pb, num); avio_wl32(pb, enc->width); avio_wl32(pb, enc->height); avio_wl32(pb, 1); // progressive FIXME avio_wl32(pb, enc->height); avio_wl32(pb, enc->width); avio_wl32(pb, enc->height); avio_wl32(pb, enc->width); avio_wl32(pb, 0); avio_wl32(pb, 0); avio_wl32(pb, 0); avio_wl32(pb, 0); ff_end_tag(pb, vprp); } ff_end_tag(pb, list2); } if (pb->seekable) { /* AVI could become an OpenDML one, if it grows beyond 2Gb range */ avi->odml_list = ff_start_tag(pb, "JUNK"); ffio_wfourcc(pb, "odml"); ffio_wfourcc(pb, "dmlh"); avio_wl32(pb, 248); for (i = 0; i < 248; i += 4) avio_wl32(pb, 0); ff_end_tag(pb, avi->odml_list); } ff_end_tag(pb, list1); ff_riff_write_info(s); padding = s->metadata_header_padding; if (padding < 0) padding = 1016; /* some padding for easier tag editing */ if (padding) { list2 = ff_start_tag(pb, "JUNK"); for (i = padding; i > 0; i -= 4) avio_wl32(pb, 0); ff_end_tag(pb, list2); } avi->movi_list = ff_start_tag(pb, "LIST"); ffio_wfourcc(pb, "movi"); avio_flush(pb); return 0; }
static int init_filters(const char *filters_descr) { char args[512]; int ret; AVFilter *abuffersrc = avfilter_get_by_name("abuffer"); AVFilter *abuffersink = avfilter_get_by_name("abuffersink"); AVFilterInOut *outputs = avfilter_inout_alloc(); AVFilterInOut *inputs = avfilter_inout_alloc(); const enum AVSampleFormat sample_fmts[] = { AV_SAMPLE_FMT_S16, -1 }; AVABufferSinkParams *abuffersink_params; const AVFilterLink *outlink; AVRational time_base = fmt_ctx->streams[audio_stream_index]->time_base; filter_graph = avfilter_graph_alloc(); /* buffer audio source: the decoded frames from the decoder will be inserted here. */ if (!dec_ctx->channel_layout) dec_ctx->channel_layout = av_get_default_channel_layout(dec_ctx->channels); snprintf(args, sizeof(args), "time_base=%d/%d:sample_rate=%d:sample_fmt=%s:channel_layout=0x%"PRIx64, time_base.num, time_base.den, dec_ctx->sample_rate, av_get_sample_fmt_name(dec_ctx->sample_fmt), dec_ctx->channel_layout); ret = avfilter_graph_create_filter(&buffersrc_ctx, abuffersrc, "in", args, NULL, filter_graph); if (ret < 0) { av_log(NULL, AV_LOG_ERROR, "Cannot create audio buffer source\n"); return ret; } /* buffer audio sink: to terminate the filter chain. */ abuffersink_params = av_abuffersink_params_alloc(); abuffersink_params->sample_fmts = sample_fmts; ret = avfilter_graph_create_filter(&buffersink_ctx, abuffersink, "out", NULL, abuffersink_params, filter_graph); av_free(abuffersink_params); if (ret < 0) { av_log(NULL, AV_LOG_ERROR, "Cannot create audio buffer sink\n"); return ret; } /* Endpoints for the filter graph. */ outputs->name = av_strdup("in"); outputs->filter_ctx = buffersrc_ctx; outputs->pad_idx = 0; outputs->next = NULL; inputs->name = av_strdup("out"); inputs->filter_ctx = buffersink_ctx; inputs->pad_idx = 0; inputs->next = NULL; if ((ret = avfilter_graph_parse(filter_graph, filters_descr, &inputs, &outputs, NULL)) < 0) return ret; if ((ret = avfilter_graph_config(filter_graph, NULL)) < 0) return ret; /* Print summary of the sink buffer * Note: args buffer is reused to store channel layout string */ outlink = buffersink_ctx->inputs[0]; av_get_channel_layout_string(args, sizeof(args), -1, outlink->channel_layout); av_log(NULL, AV_LOG_INFO, "Output: srate:%dHz fmt:%s chlayout:%s\n", (int)outlink->sample_rate, (char *)av_x_if_null(av_get_sample_fmt_name(outlink->format), "?"), args); return 0; }
static int init_filters(AVStream *audio_stream, int audio_stream_index) { AVCodecContext *dec_ctx = audio_stream->codec; char args[512]; int ret = 0; AVFilter *abuffersrc = avfilter_get_by_name("abuffer"); AVFilter *abuffersink = avfilter_get_by_name("abuffersink"); AVFilterInOut *outputs = avfilter_inout_alloc(); AVFilterInOut *inputs = avfilter_inout_alloc(); static const enum AVSampleFormat out_sample_fmts[] = { AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE }; static const int64_t out_channel_layouts[] = { AV_CH_LAYOUT_STEREO, -1 }; static const int out_sample_rates[] = { dec_ctx->sample_rate, -1 }; const AVFilterLink *outlink; AVRational time_base = fmt_ctx->streams[audio_stream_index]->time_base; filter_graph = avfilter_graph_alloc(); if (!outputs || !inputs || !filter_graph) { ret = AVERROR(ENOMEM); goto end; } /* buffer audio source: the decoded frames from the decoder will be inserted here. */ if (!dec_ctx->channel_layout) dec_ctx->channel_layout = av_get_default_channel_layout(dec_ctx->channels); _snprintf_s(args, sizeof(args), "time_base=%d/%d:sample_rate=%d:sample_fmt=%s:channel_layout=0x%I64d", time_base.num, time_base.den, dec_ctx->sample_rate, av_get_sample_fmt_name(dec_ctx->sample_fmt), dec_ctx->channel_layout); ret = avfilter_graph_create_filter(&buffersrc_ctx, abuffersrc, "in", args, NULL, filter_graph); if (ret < 0) { av_log(NULL, AV_LOG_ERROR, "Cannot create audio buffer source\n"); goto end; } /* buffer audio sink: to terminate the filter chain. */ ret = avfilter_graph_create_filter(&buffersink_ctx, abuffersink, "out", NULL, NULL, filter_graph); if (ret < 0) { av_log(NULL, AV_LOG_ERROR, "Cannot create audio buffer sink\n"); goto end; } ret = av_opt_set_int_list(buffersink_ctx, "sample_fmts", out_sample_fmts, -1, AV_OPT_SEARCH_CHILDREN); if (ret < 0) { av_log(NULL, AV_LOG_ERROR, "Cannot set output sample format\n"); goto end; } ret = av_opt_set_int_list(buffersink_ctx, "channel_layouts", out_channel_layouts, -1, AV_OPT_SEARCH_CHILDREN); if (ret < 0) { av_log(NULL, AV_LOG_ERROR, "Cannot set output channel layout\n"); goto end; } ret = av_opt_set_int_list(buffersink_ctx, "sample_rates", out_sample_rates, -1, AV_OPT_SEARCH_CHILDREN); if (ret < 0) { av_log(NULL, AV_LOG_ERROR, "Cannot set output sample rate\n"); goto end; } last_flt_ctx = buffersink_ctx; int index = 1; while(filter_descr[index]) { const char* name = NULL; const char* arg = NULL; char tmp[64] = {0}; char* pos = NULL; strncpy_s(tmp, 64, filter_descr[index], 64); pos = strchr(tmp, '='); if (pos != NULL) { *pos = '\0'; name = tmp; arg = pos + 1; } else { name = filter_descr[index]; arg = NULL; } insert_filter(name, arg, &last_flt_ctx); index++; } /* Endpoints for the filter graph. */ outputs->name = av_strdup("in"); outputs->filter_ctx = buffersrc_ctx; outputs->pad_idx = 0; outputs->next = NULL; inputs->name = av_strdup("out"); inputs->filter_ctx = last_flt_ctx; inputs->pad_idx = 0; inputs->next = NULL; if ((ret = avfilter_graph_parse_ptr(filter_graph, filter_descr[0], &inputs, &outputs, NULL)) < 0) goto end; if ((ret = avfilter_graph_config(filter_graph, NULL)) < 0) goto end; /* Print summary of the sink buffer * Note: args buffer is reused to store channel layout string */ outlink = buffersink_ctx->inputs[0]; av_get_channel_layout_string(args, sizeof(args), -1, outlink->channel_layout); av_log(NULL, AV_LOG_INFO, "Output: srate:%dHz fmt:%s chlayout:%s\n", (int)outlink->sample_rate, (char *)av_x_if_null(av_get_sample_fmt_name((AVSampleFormat)outlink->format), "?"), args); end: avfilter_inout_free(&inputs); avfilter_inout_free(&outputs); return ret; }