[FFmpeg-devel] [WIP] movie video source
Stefano Sabatini
stefano.sabatini-lala
Tue Dec 28 14:42:33 CET 2010
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
More information about the ffmpeg-devel
mailing list