+ err = 0;
+fail:
+ drmModeFreeFB(fb);
+ return err;
+}
+
+static int kmsgrab_read_packet(AVFormatContext *avctx, AVPacket *pkt)
+{
+ KMSGrabContext *ctx = avctx->priv_data;
+ drmModePlane *plane = NULL;
+ AVDRMFrameDescriptor *desc = NULL;
+ AVFrame *frame = NULL;
+ int64_t now;
+ int err;
+
+ now = av_gettime();
+ if (ctx->frame_last) {
+ int64_t delay;
+ while (1) {
+ delay = ctx->frame_last + ctx->frame_delay - now;
+ if (delay <= 0)
+ break;
+ av_usleep(delay);
+ now = av_gettime();
+ }
+ }
+ ctx->frame_last = now;
+
+ plane = drmModeGetPlane(ctx->hwctx->fd, ctx->plane_id);
+ if (!plane) {
+ err = errno;
+ av_log(avctx, AV_LOG_ERROR, "Failed to get plane "
+ "%"PRIu32": %s.\n", ctx->plane_id, strerror(err));
+ err = AVERROR(err);
+ goto fail;
+ }
+ if (!plane->fb_id) {
+ av_log(avctx, AV_LOG_ERROR, "Plane %"PRIu32" no longer has "
+ "an associated framebuffer.\n", ctx->plane_id);
+ err = AVERROR(EIO);
+ goto fail;
+ }
+
+ desc = av_mallocz(sizeof(*desc));
+ if (!desc) {
+ err = AVERROR(ENOMEM);
+ goto fail;
+ }
+
+ err = kmsgrab_get_fb(avctx, plane, desc);
+ if (err < 0)
+ goto fail;
+