You've already forked FFmpeg
mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-08-15 14:13:16 +02:00
kmsgrab: Refactor and clean error cases
This commit is contained in:
@@ -81,70 +81,44 @@ static void kmsgrab_free_frame(void *opaque, uint8_t *data)
|
|||||||
av_frame_free(&frame);
|
av_frame_free(&frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int kmsgrab_read_packet(AVFormatContext *avctx, AVPacket *pkt)
|
static int kmsgrab_get_fb(AVFormatContext *avctx,
|
||||||
|
drmModePlane *plane,
|
||||||
|
AVDRMFrameDescriptor *desc)
|
||||||
{
|
{
|
||||||
KMSGrabContext *ctx = avctx->priv_data;
|
KMSGrabContext *ctx = avctx->priv_data;
|
||||||
drmModePlane *plane;
|
drmModeFB *fb = NULL;
|
||||||
drmModeFB *fb;
|
|
||||||
AVDRMFrameDescriptor *desc;
|
|
||||||
AVFrame *frame;
|
|
||||||
int64_t now;
|
|
||||||
int err, fd;
|
int err, fd;
|
||||||
|
|
||||||
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) {
|
|
||||||
av_log(avctx, AV_LOG_ERROR, "Failed to get plane "
|
|
||||||
"%"PRIu32".\n", ctx->plane_id);
|
|
||||||
return AVERROR(EIO);
|
|
||||||
}
|
|
||||||
if (!plane->fb_id) {
|
|
||||||
av_log(avctx, AV_LOG_ERROR, "Plane %"PRIu32" no longer has "
|
|
||||||
"an associated framebuffer.\n", ctx->plane_id);
|
|
||||||
return AVERROR(EIO);
|
|
||||||
}
|
|
||||||
|
|
||||||
fb = drmModeGetFB(ctx->hwctx->fd, plane->fb_id);
|
fb = drmModeGetFB(ctx->hwctx->fd, plane->fb_id);
|
||||||
if (!fb) {
|
if (!fb) {
|
||||||
|
err = errno;
|
||||||
av_log(avctx, AV_LOG_ERROR, "Failed to get framebuffer "
|
av_log(avctx, AV_LOG_ERROR, "Failed to get framebuffer "
|
||||||
"%"PRIu32".\n", plane->fb_id);
|
"%"PRIu32": %s.\n", plane->fb_id, strerror(err));
|
||||||
return AVERROR(EIO);
|
err = AVERROR(err);
|
||||||
|
goto fail;
|
||||||
}
|
}
|
||||||
if (fb->width != ctx->width || fb->height != ctx->height) {
|
if (fb->width != ctx->width || fb->height != ctx->height) {
|
||||||
av_log(avctx, AV_LOG_ERROR, "Plane %"PRIu32" framebuffer "
|
av_log(avctx, AV_LOG_ERROR, "Plane %"PRIu32" framebuffer "
|
||||||
"dimensions changed: now %"PRIu32"x%"PRIu32".\n",
|
"dimensions changed: now %"PRIu32"x%"PRIu32".\n",
|
||||||
ctx->plane_id, fb->width, fb->height);
|
ctx->plane_id, fb->width, fb->height);
|
||||||
return AVERROR(EIO);
|
err = AVERROR(EIO);
|
||||||
|
goto fail;
|
||||||
}
|
}
|
||||||
if (!fb->handle) {
|
if (!fb->handle) {
|
||||||
av_log(avctx, AV_LOG_ERROR, "No handle set on framebuffer.\n");
|
av_log(avctx, AV_LOG_ERROR, "No handle set on framebuffer.\n");
|
||||||
return AVERROR(EIO);
|
err = AVERROR(EIO);
|
||||||
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = drmPrimeHandleToFD(ctx->hwctx->fd, fb->handle, O_RDONLY, &fd);
|
err = drmPrimeHandleToFD(ctx->hwctx->fd, fb->handle, O_RDONLY, &fd);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
err = errno;
|
err = errno;
|
||||||
av_log(avctx, AV_LOG_ERROR, "Failed to get PRIME fd from "
|
av_log(avctx, AV_LOG_ERROR, "Failed to get PRIME fd from "
|
||||||
"framebuffer handle: %s.\n", strerror(errno));
|
"framebuffer handle: %s.\n", strerror(err));
|
||||||
return AVERROR(err);
|
err = AVERROR(err);
|
||||||
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
desc = av_mallocz(sizeof(*desc));
|
|
||||||
if (!desc)
|
|
||||||
return AVERROR(ENOMEM);
|
|
||||||
|
|
||||||
*desc = (AVDRMFrameDescriptor) {
|
*desc = (AVDRMFrameDescriptor) {
|
||||||
.nb_objects = 1,
|
.nb_objects = 1,
|
||||||
.objects[0] = {
|
.objects[0] = {
|
||||||
@@ -164,31 +138,93 @@ static int kmsgrab_read_packet(AVFormatContext *avctx, AVPacket *pkt)
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
frame = av_frame_alloc();
|
frame = av_frame_alloc();
|
||||||
if (!frame)
|
if (!frame) {
|
||||||
return AVERROR(ENOMEM);
|
err = AVERROR(ENOMEM);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
frame->hw_frames_ctx = av_buffer_ref(ctx->frames_ref);
|
frame->hw_frames_ctx = av_buffer_ref(ctx->frames_ref);
|
||||||
if (!frame->hw_frames_ctx)
|
if (!frame->hw_frames_ctx) {
|
||||||
return AVERROR(ENOMEM);
|
err = AVERROR(ENOMEM);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
frame->buf[0] = av_buffer_create((uint8_t*)desc, sizeof(*desc),
|
frame->buf[0] = av_buffer_create((uint8_t*)desc, sizeof(*desc),
|
||||||
&kmsgrab_free_desc, avctx, 0);
|
&kmsgrab_free_desc, avctx, 0);
|
||||||
if (!frame->buf[0])
|
if (!frame->buf[0]) {
|
||||||
return AVERROR(ENOMEM);
|
err = AVERROR(ENOMEM);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
frame->data[0] = (uint8_t*)desc;
|
frame->data[0] = (uint8_t*)desc;
|
||||||
frame->format = AV_PIX_FMT_DRM_PRIME;
|
frame->format = AV_PIX_FMT_DRM_PRIME;
|
||||||
frame->width = fb->width;
|
frame->width = ctx->width;
|
||||||
frame->height = fb->height;
|
frame->height = ctx->height;
|
||||||
|
|
||||||
drmModeFreeFB(fb);
|
|
||||||
drmModeFreePlane(plane);
|
drmModeFreePlane(plane);
|
||||||
|
plane = NULL;
|
||||||
|
desc = NULL;
|
||||||
|
|
||||||
pkt->buf = av_buffer_create((uint8_t*)frame, sizeof(*frame),
|
pkt->buf = av_buffer_create((uint8_t*)frame, sizeof(*frame),
|
||||||
&kmsgrab_free_frame, avctx, 0);
|
&kmsgrab_free_frame, avctx, 0);
|
||||||
if (!pkt->buf)
|
if (!pkt->buf) {
|
||||||
return AVERROR(ENOMEM);
|
err = AVERROR(ENOMEM);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
pkt->data = (uint8_t*)frame;
|
pkt->data = (uint8_t*)frame;
|
||||||
pkt->size = sizeof(*frame);
|
pkt->size = sizeof(*frame);
|
||||||
@@ -196,6 +232,12 @@ static int kmsgrab_read_packet(AVFormatContext *avctx, AVPacket *pkt)
|
|||||||
pkt->flags |= AV_PKT_FLAG_TRUSTED;
|
pkt->flags |= AV_PKT_FLAG_TRUSTED;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
drmModeFreePlane(plane);
|
||||||
|
av_freep(&desc);
|
||||||
|
av_frame_free(&frame);
|
||||||
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct {
|
static const struct {
|
||||||
@@ -289,9 +331,10 @@ static av_cold int kmsgrab_read_header(AVFormatContext *avctx)
|
|||||||
} else {
|
} else {
|
||||||
plane_res = drmModeGetPlaneResources(ctx->hwctx->fd);
|
plane_res = drmModeGetPlaneResources(ctx->hwctx->fd);
|
||||||
if (!plane_res) {
|
if (!plane_res) {
|
||||||
|
err = errno;
|
||||||
av_log(avctx, AV_LOG_ERROR, "Failed to get plane "
|
av_log(avctx, AV_LOG_ERROR, "Failed to get plane "
|
||||||
"resources: %s.\n", strerror(errno));
|
"resources: %s.\n", strerror(err));
|
||||||
err = AVERROR(EINVAL);
|
err = AVERROR(err);
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -402,13 +445,9 @@ static av_cold int kmsgrab_read_header(AVFormatContext *avctx)
|
|||||||
|
|
||||||
err = 0;
|
err = 0;
|
||||||
fail:
|
fail:
|
||||||
if (plane_res)
|
drmModeFreePlaneResources(plane_res);
|
||||||
drmModeFreePlaneResources(plane_res);
|
drmModeFreePlane(plane);
|
||||||
if (plane)
|
drmModeFreeFB(fb);
|
||||||
drmModeFreePlane(plane);
|
|
||||||
if (fb)
|
|
||||||
drmModeFreeFB(fb);
|
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user