On 4/28/2018 2:05 PM, wm4 wrote: > This can "demux" .vpy files. > > Some minor code copied from other LGPL parts of FFmpeg. > > I did not found a good way to test a few of the more obscure features, > like VFR nodes, compat pixel formats, or nodes with dynamic size/format > changes. These can be easily implemented on demand. > --- > configure | 5 + > libavformat/Makefile | 1 + > libavformat/allformats.c | 1 + > libavformat/vapoursynth.c | 421 > ++++++++++++++++++++++++++++++++++++++++++++++ > 4 files changed, 428 insertions(+) > create mode 100644 libavformat/vapoursynth.c
[...] > +static int read_packet_vs(AVFormatContext *s, AVPacket *pkt) > +{ > + VSContext *vs = s->priv_data; > + AVStream *st = s->streams[0]; > + AVFrame *frame = NULL; > + char vserr[80]; > + const VSFrameRef *vsframe = NULL; > + const VSVideoInfo *info = vs->vsapi->getVideoInfo(vs->outnode); > + int err = 0; > + const uint8_t *src_data[4]; > + int src_linesizes[4]; > + const VSMap *props; > + int i; > + > + if (vs->current_frame >= info->numFrames) > + return AVERROR_EOF; > + > + vsframe = vs->vsapi->getFrame(vs->current_frame, vs->outnode, vserr, > sizeof(vserr)); > + if (!vsframe) { > + av_log(s, AV_LOG_ERROR, "Error getting frame: %s\n", vserr); > + err = AVERROR_EXTERNAL; > + goto end; > + } > + > + props = vs->vsapi->getFramePropsRO(vsframe); > + > + frame = av_frame_alloc(); > + if (!frame) { > + err = AVERROR(ENOMEM); > + goto end; > + } > + > + frame->format = st->codecpar->format; > + frame->width = st->codecpar->width; > + frame->height = st->codecpar->height; > + frame->colorspace = st->codecpar->color_space; > + > + // Values according to ISO/IEC 14496-10. > + frame->colorspace = get_vs_prop_int(s, props, "_Matrix", > frame->colorspace); > + frame->color_primaries = get_vs_prop_int(s, props, "_Primaries", > frame->color_primaries); > + frame->color_trc = get_vs_prop_int(s, props, "_Transfer", > frame->color_trc); > + > + if (get_vs_prop_int(s, props, "_ColorRange", 1) == 0) > + frame->color_range = AVCOL_RANGE_JPEG; > + > + frame->sample_aspect_ratio.num = get_vs_prop_int(s, props, "_SARNum", 0); > + frame->sample_aspect_ratio.den = get_vs_prop_int(s, props, "_SARDen", 1); > + > + av_assert0(vs->vsapi->getFrameWidth(vsframe, 0) == frame->width); > + av_assert0(vs->vsapi->getFrameHeight(vsframe, 0) == frame->height); > + > + err = av_frame_get_buffer(frame, 0); > + if (err < 0) > + goto end; > + > + for (i = 0; i < info->format->numPlanes; i++) { > + int p = vs->c_order[i]; > + src_data[i] = vs->vsapi->getReadPtr(vsframe, p); > + src_linesizes[i] = vs->vsapi->getStride(vsframe, p); > + } > + > + av_image_copy(frame->data, frame->linesize, src_data, src_linesizes, > + frame->format, frame->width, frame->height); > + > + pkt->buf = av_buffer_create((uint8_t*)frame, sizeof(*frame), > + free_frame, NULL, 0); > + if (!pkt->buf) { > + err = AVERROR(ENOMEM); > + goto end; > + } > + > + frame = NULL; // pkt owns it now > + > + pkt->data = pkt->buf->data; > + pkt->size = pkt->buf->size; > + pkt->flags |= AV_PKT_FLAG_TRUSTED; > + > + if (vs->is_cfr) > + pkt->pts = vs->current_frame; > + > + vs->current_frame++; > + > +end: > + if (err < 0) > + av_packet_unref(pkt); Unneeded. Nothing after pkt->buf is initialized can fail right now. And if av_buffer_create() fails, pkt will be untouched. > + av_frame_free(&frame); > + vs->vsapi->freeFrame(vsframe); > + return err; Shouldn't you set err to pkt->size right above the end label? > +} > + > +static int read_seek_vs(AVFormatContext *s, int stream_idx, int64_t ts, int > flags) > +{ > + VSContext *vs = s->priv_data; > + > + if (!vs->is_cfr) > + return AVERROR(ENOSYS); > + > + vs->current_frame = FFMIN(FFMAX(0, ts), s->streams[0]->duration); > + return 0; > +} > + > +static av_cold int probe_vs(AVProbeData *p) > +{ > + // Explicitly do not support this. VS scripts are written in Python, and > + // can run arbitrary code on the user's system. > + return 0; > +} > + > +static const AVClass class_vs = { > + .class_name = "VapourSynth demuxer", > + .item_name = av_default_item_name, > + .option = options, > + .version = LIBAVUTIL_VERSION_INT, > +}; > + > +AVInputFormat ff_vapoursynth_demuxer = { > + .name = "vapoursynth", > + .long_name = NULL_IF_CONFIG_SMALL("VapourSynth demuxer"), > + .priv_data_size = sizeof(VSContext), > + .read_probe = probe_vs, > + .read_header = read_header_vs, > + .read_packet = read_packet_vs, > + .read_close = read_close_vs, > + .read_seek = read_seek_vs, > + .priv_class = &class_vs, > +}; > _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel