[FFmpeg-devel] [WIP] movie video source

Stefano Sabatini stefano.sabatini-lala
Wed Dec 29 12:48:36 CET 2010


On date Tuesday 2010-12-28 14:42:33 +0100, Stefano Sabatini encoded:
> On date Sunday 2010-11-21 17:49:57 +0100, Michael Niedermayer encoded:
> > On Sun, Oct 31, 2010 at 08:56:34PM +0100, Stefano Sabatini wrote:
> > [...]
> > > +    // Try to find the movie format (container)
> > > +    if (*movie->format_name)
> > > +        iformat = av_find_input_format(movie->format_name);
> > > +    else
> > 
> > {} nitpick
> > 
> > 
> > > +        iformat = NULL;
> > > +
> > > +    movie->format_ctx = NULL;
> > > +    if ((ret = av_open_input_file(&movie->format_ctx, movie->file_name, iformat, 0, NULL)) < 0) {
> > > +        av_log(ctx, AV_LOG_ERROR,
> > > +               "Failed to av_open_input_file '%s'\n", movie->file_name);
> > > +        return ret;
> > > +    }
> > > +    if ((ret = av_find_stream_info(movie->format_ctx)) < 0) {
> > > +        av_log(ctx, AV_LOG_ERROR, "Failed to find stream info\n");
> > > +        return ret;
> > > +    }
> > > +
> > > +    // if seeking requested, we execute it
> > > +    if (movie->seek_point > 0) {
> > > +        timestamp = movie->seek_point;
> > > +        // add the stream start time, should it exist
> > > +        if (movie->format_ctx->start_time != AV_NOPTS_VALUE)
> > > +            timestamp += movie->format_ctx->start_time;
> > > +        if (av_seek_frame(movie->format_ctx, -1, timestamp, AVSEEK_FLAG_BACKWARD) < 0) {
> > > +            av_log(ctx, AV_LOG_ERROR, "%s: could not seek to position %"PRId64"\n",
> > > +                   movie->file_name, timestamp);
> > > +        }
> > > +    }
> > > +
> > 
> > > +    /* find the first available video stream */
> > > +    if (movie->video_stream < 0) {
> > > +        for (i = 0; i < movie->format_ctx->nb_streams; i++)
> > > +            if (movie->format_ctx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
> > > +                movie->video_stream = i;
> > > +                break;
> > > +            }
> > > +        if (movie->video_stream < 0) {
> > > +            av_log(ctx, AV_LOG_ERROR, "No video stream found\n");
> > > +            return AVERROR(EINVAL);
> > > +        }
> > 
> > should use the same st_best_packet_count system as ffplay to select the default
> > stream. Or this effectively introduces a bug that said system fixed
> 
> Updated, now it uses av_find_best_stream().
>  
> > 
> > [....]
> > > +static av_cold void uninit(AVFilterContext *ctx)
> > > +{
> > > +    MovieContext *movie = ctx->priv;
> > > +
> > > +    if (movie->codec_ctx)
> > > +        avcodec_close(movie->codec_ctx);
> > > +    if (movie->format_ctx)
> > > +        av_close_input_file(movie->format_ctx);
> > > +    av_freep(&movie->frame);
> > > +    if (movie->picref)
> > > +        avfilter_unref_buffer(movie->picref);
> > 
> > some of these functions should get null pointer checks so that the callers
> > dont have to
> > 
> > [...]
> > > +    if (!movie->picref)
> > > +        movie->picref = avfilter_get_video_buffer(outlink,
> > > +                                                  AV_PERM_WRITE | AV_PERM_PRESERVE | AV_PERM_REUSE2,
> > > +                                                  outlink->w, outlink->h);
> > > +
> > > +    while (av_read_frame(movie->format_ctx, &packet) >= 0) {
> > > +        // Is this a packet from the video stream?
> > > +        if (packet.stream_index == movie->video_stream) {
> > > +            // Decode video frame
> > > +            avcodec_decode_video2(movie->codec_ctx, movie->frame, &frame_finished, &packet);
> > > +
> > > +            // Did we get a video frame?
> > > +            if (frame_finished) {
> > > +                av_image_copy(movie->picref->data, movie->picref->linesize,
> > > +                              movie->frame ->data, movie->frame ->linesize,
> > > +                              movie->picref->format, outlink->w, outlink->h);
> > > +
> > > +                movie->picref->pts = packet.pts;
> > > +                movie->picref->pos = packet.pos;
> > > +                movie->picref->video->pixel_aspect = movie->codec_ctx->sample_aspect_ratio;
> > > +                movie->picref->video->interlaced = movie->frame->interlaced_frame;
> > > +                movie->picref->video->top_field_first = movie->frame->top_field_first;
> > > +
> > > +#ifdef DEBUG
> > > +                av_log(outlink->src, AV_LOG_DEBUG,
> > > +                       "movie_get_frame(): file:'%s' pkt.pts:%"PRId64" t:%lf pts:%"PRId64"\n",
> > > +                       movie->file_name, packet.pts,
> > > +                       (double)packet.pts * av_q2d(movie->format_ctx->streams[movie->video_stream]->time_base),
> > > +                       movie->picref->pts);
> > > +#endif
> > > +
> > > +                // We got it. Free the packet since we are returning
> > > +                av_free_packet(&packet);
> > > +
> > > +                return 0;
> > > +            }
> > > +        }
> > > +        // Free the packet that was allocated by av_read_frame
> > > +        av_free_packet(&packet);
> > > +    }
> > 
> > There are 2 ways to implement this
> > 1. as you do get a frame from the next filter and draw into this (this is a bit
> > hard)
> > 2. make a AVFilterBufferRef out of the returned picture from the decoder
> >    you just recently wrote a function doing this, so it should be trivial
> > 
> > but taking a frame from the next filter and then forcing a copy as done is
> > really the wrong way and also more complex than 2. above
> 
> Fixed by using avfilter_get_video_buffer_ref_from_arrays().
> -- 
> FFmpeg = Foolish & Fundamental Magnificient Pure Efficient Gangster

> From c93063076fa9dd81c3d312cf8a662f0364cb93b0 Mon Sep 17 00:00:00 2001
> From: Stefano Sabatini <stefano.sabatini-lala at poste.it>
> Date: Sun, 31 Oct 2010 17:37:10 +0100
> Subject: [PATCH] Add movie video source.
> 
> ---
>  doc/filters.texi         |   35 ++++++
>  libavfilter/Makefile     |    2 +
>  libavfilter/allfilters.c |    1 +
>  libavfilter/vsrc_movie.c |  266 ++++++++++++++++++++++++++++++++++++++++++++++
>  4 files changed, 304 insertions(+), 0 deletions(-)
>  create mode 100644 libavfilter/vsrc_movie.c

If there are no comments I'll apply in few days.
-- 
FFmpeg = Fundamentalist & Fancy Moronic Portable Extravagant Genius



More information about the ffmpeg-devel mailing list