[FFmpeg-devel] [WIP] movie video source

Michael Niedermayer michaelni
Sun Nov 21 17:49:57 CET 2010


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


[....]
> +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

[...]
-- 
Michael     GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB

When the tyrant has disposed of foreign enemies by conquest or treaty, and
there is nothing more to fear from them, then he is always stirring up
some war or other, in order that the people may require a leader. -- Plato
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: Digital signature
URL: <http://lists.mplayerhq.hu/pipermail/ffmpeg-devel/attachments/20101121/d94d715c/attachment.pgp>



More information about the ffmpeg-devel mailing list