{
struct v4l2_decoder_cmd cmd = {
.cmd = V4L2_DEC_CMD_STOP,
+ .flags = 0,
};
int ret;
{
struct v4l2_encoder_cmd cmd = {
.cmd = V4L2_ENC_CMD_STOP,
+ .flags = 0,
};
int ret;
.events = POLLIN | POLLRDNORM | POLLPRI | POLLOUT | POLLWRNORM, /* default blocking capture */
.fd = ctx_to_m2mctx(ctx)->fd,
};
- int ret;
+ int i, ret;
+
+ /* if we are draining and there are no more capture buffers queued in the driver we are done */
+ if (!V4L2_TYPE_IS_OUTPUT(ctx->type) && ctx_to_m2mctx(ctx)->draining) {
+ for (i = 0; i < ctx->num_buffers; i++) {
+ if (ctx->buffers[i].status == V4L2BUF_IN_DRIVER)
+ goto start;
+ }
+ ctx->done = 1;
+ return NULL;
+ }
+start:
if (V4L2_TYPE_IS_OUTPUT(ctx->type))
pfd.events = POLLOUT | POLLWRNORM;
+ else {
+ /* no need to listen to requests for more input while draining */
+ if (ctx_to_m2mctx(ctx)->draining)
+ pfd.events = POLLIN | POLLRDNORM | POLLPRI;
+ }
for (;;) {
ret = poll(&pfd, 1, timeout);
break;
if (errno == EINTR)
continue;
-
- /* timeout is being used to indicate last valid bufer when draining */
- if (ctx_to_m2mctx(ctx)->draining)
- ctx->done = 1;
-
return NULL;
}
ret = v4l2_handle_event(ctx);
if (ret < 0) {
/* if re-init failed, abort */
- ctx->done = EINVAL;
+ ctx->done = 1;
return NULL;
}
if (ret) {
ret = ioctl(ctx_to_m2mctx(ctx)->fd, VIDIOC_DQBUF, &buf);
if (ret) {
if (errno != EAGAIN) {
- ctx->done = errno;
+ ctx->done = 1;
if (errno != EPIPE)
av_log(logger(ctx), AV_LOG_DEBUG, "%s VIDIOC_DQBUF, errno (%s)\n",
ctx->name, av_err2str(AVERROR(errno)));
}
- } else {
- avbuf = &ctx->buffers[buf.index];
- avbuf->status = V4L2BUF_AVAILABLE;
- avbuf->buf = buf;
- if (V4L2_TYPE_IS_MULTIPLANAR(ctx->type)) {
- memcpy(avbuf->planes, planes, sizeof(planes));
- avbuf->buf.m.planes = avbuf->planes;
- }
+ return NULL;
}
+
+ avbuf = &ctx->buffers[buf.index];
+ avbuf->status = V4L2BUF_AVAILABLE;
+ avbuf->buf = buf;
+ if (V4L2_TYPE_IS_MULTIPLANAR(ctx->type)) {
+ memcpy(avbuf->planes, planes, sizeof(planes));
+ avbuf->buf.m.planes = avbuf->planes;
+ }
+ return avbuf;
}
- return avbuf;
+ return NULL;
}
static V4L2Buffer* v4l2_getfree_v4l2buf(V4L2Context *ctx)
{
V4L2Buffer* avbuf = NULL;
- /* if we are draining, we are no longer inputing data, therefore enable a
- * timeout so we can dequeue and flag the last valid buffer.
- *
+ /*
* blocks until:
* 1. decoded frame available
* 2. an input buffer is ready to be dequeued
*/
- avbuf = v4l2_dequeue_v4l2buf(ctx, ctx_to_m2mctx(ctx)->draining ? 200 : -1);
+ avbuf = v4l2_dequeue_v4l2buf(ctx, -1);
if (!avbuf) {
if (ctx->done)
return AVERROR_EOF;
{
V4L2Buffer* avbuf = NULL;
- /* if we are draining, we are no longer inputing data, therefore enable a
- * timeout so we can dequeue and flag the last valid buffer.
- *
+ /*
* blocks until:
* 1. encoded packet available
* 2. an input buffer ready to be dequeued
*/
- avbuf = v4l2_dequeue_v4l2buf(ctx, ctx_to_m2mctx(ctx)->draining ? 200 : -1);
+ avbuf = v4l2_dequeue_v4l2buf(ctx, -1);
if (!avbuf) {
if (ctx->done)
return AVERROR_EOF;