av_buffersink_get_frame_flags接口注意事项

/**
 * Get a frame with filtered data from sink and put it in frame.
 *
 * @param ctx    pointer to a buffersink or abuffersink filter context.
 * @param frame  pointer to an allocated frame that will be filled with data.
 *               The data must be freed using av_frame_unref() / av_frame_free()
 * @param flags  a combination of AV_BUFFERSINK_FLAG_* flags
 *
 * @return  >= 0 in for success, a negative AVERROR code for failure.
 */

int av_buffersink_get_frame_flags(AVFilterContext *ctx, AVFrame *frame, int flags);
//伪代码
av_bprintf(&args,
           "buffer=video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d:frame_rate=%d/%d[main];"
           "buffer=video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d:frame_rate=%d/%d[logo];"
        //    "[main]format=yuv420p[result];"
           "[main][logo]overlay=x=10:y=10[result];"
        //    "[result]format=yuv420p[result_2];"
           "[result]buffersink",
           frame->width, frame->height, frame->format, tb.num, tb.den, sar.num, sar.den, fr.num, fr.den,
           logo_frame->width, logo_frame->height, logo_frame->format, logo_tb.num, logo_tb.den,
           logo_sar.num, logo_sar.den, logo_fr.num, logo_fr.den);
//伪代码
int ret = av_buffersrc_add_frame_flags(mainsrc_ctx, frame, AV_BUFFERSRC_FLAG_PUSH);
if (ret < 0)
{
    printf("Error: av_buffersrc_add_frame failed\n");
    return ret;
}

    ret = av_buffersink_get_frame_flags(resultsink_ctx, result_frame, AV_BUFFERSINK_FLAG_NO_REQUEST);
    if (ret == AVERROR_EOF)
    {
        // 没有更多的 AVFrame
        printf("no more avframe output \n");
        // break;
    }
    else if (ret == AVERROR(EAGAIN))
    {
        // 需要输入更多的 AVFrame
        printf("need more avframe input \n");
        // break;
    }
    else if (ret >= 0)
    {
        // 保存进去文件。
        printf("save_yuv_to_file success\n");

        // save_yuv_to_file(result_frame, frame_num);
        frame_num++;
    }
//伪代码
logo_next_pts = frame->pts + frame->pkt_duration;
int ret = av_buffersrc_close(mainsrc_ctx, logo_next_pts, AV_BUFFERSRC_FLAG_PUSH);

1.在使用这个函数时需要注意,它每次都会给result_frame分配空间,因此每次在使用前都需要释放之前的空间,frame av_frame_unref(result_frame);
2.这个函数会把frame里的一些字节拷贝到result_frame,比如宽高,pts。
3.add一帧A数据,就可以从get得到A数据,不存在缓存。
4.add用的一个宏

/**
 * Immediately push the frame to the output.
 */
AV_BUFFERSRC_FLAG_PUSH = 4,

5.av_buffersrc_close()关闭时需要给好pts,也就是EOF时总共时长。

/**
 * Close the buffer source after EOF.
 *
 * This is similar to passing NULL to av_buffersrc_add_frame_flags()
 * except it takes the timestamp of the EOF, i.e. the timestamp of the end
 * of the last frame.
 */
int av_buffersrc_close(AVFilterContext *ctx, int64_t pts, unsigned flags);

ffmpeg是音视频必备,但即使从业数年,它似乎依然有无穷的秘密,感兴趣添加笔者微信:YQW1163720468,加入ffmpeg微信群讨论。但记得备注:ffmpeg爱好者

你可能感兴趣的:(ffmpeg,API,ffmpeg,滤镜)