#ifdef BUILD_VAAPI_RECORDER
static void
+recorder_destroy(struct drm_output *output)
+{
+ vaapi_recorder_destroy(output->recorder);
+ output->recorder = NULL;
+
+ output->base.disable_planes--;
+
+ wl_list_remove(&output->recorder_frame_listener.link);
+ weston_log("[libva recorder] done\n");
+}
+
+static void
recorder_frame_notify(struct wl_listener *listener, void *data)
{
struct drm_output *output;
return;
}
- vaapi_recorder_frame(output->recorder, fd, output->current->stride);
+ ret = vaapi_recorder_frame(output->recorder, fd,
+ output->current->stride);
+ if (ret < 0) {
+ weston_log("[libva recorder] aborted: %m\n");
+ recorder_destroy(output);
+ }
}
static void *
weston_log("[libva recorder] initialized\n");
} else {
- vaapi_recorder_destroy(output->recorder);
- output->recorder = NULL;
-
- output->base.disable_planes--;
-
- wl_list_remove(&output->recorder_frame_listener.link);
- weston_log("[libva recorder] done\n");
+ recorder_destroy(output);
}
}
#else
#include <string.h>
#include <unistd.h>
#include <assert.h>
+#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
int width, height;
int frame_count;
+ int error;
int destroying;
pthread_t worker_thread;
pthread_mutex_t mutex;
return VA_INVALID_ID;
}
-static int
+enum output_write_status {
+ OUTPUT_WRITE_SUCCESS,
+ OUTPUT_WRITE_OVERFLOW,
+ OUTPUT_WRITE_FATAL
+};
+
+static enum output_write_status
encoder_write_output(struct vaapi_recorder *r, VABufferID output_buf)
{
VACodedBufferSegment *segment;
status = vaMapBuffer(r->va_dpy, output_buf, (void **) &segment);
if (status != VA_STATUS_SUCCESS)
- return -1;
+ return OUTPUT_WRITE_FATAL;
if (segment->status & VA_CODED_BUF_STATUS_SLICE_OVERFLOW_MASK) {
r->encoder.output_size *= 2;
vaUnmapBuffer(r->va_dpy, output_buf);
- return -1;
+ return OUTPUT_WRITE_OVERFLOW;
}
count = write(r->output_fd, segment->buf, segment->size);
vaUnmapBuffer(r->va_dpy, output_buf);
- return count;
+ if (count < 0)
+ return OUTPUT_WRITE_FATAL;
+
+ return OUTPUT_WRITE_SUCCESS;
}
static void
VABufferID buffers[8];
int count = 0;
-
- int slice_type;
- int ret, i;
+ int i, slice_type;
+ enum output_write_status ret;
if ((r->frame_count % r->encoder.intra_period) == 0)
slice_type = SLICE_TYPE_I;
output_buf = VA_INVALID_ID;
vaDestroyBuffer(r->va_dpy, buffers[--count]);
- } while (ret < 0);
+ } while (ret == OUTPUT_WRITE_OVERFLOW);
+
+ if (ret == OUTPUT_WRITE_FATAL)
+ r->error = errno;
for (i = 0; i < count; i++)
vaDestroyBuffer(r->va_dpy, buffers[i]);
return NULL;
}
-void
+int
vaapi_recorder_frame(struct vaapi_recorder *r, int prime_fd, int stride)
{
+ int ret = 0;
+
pthread_mutex_lock(&r->mutex);
+ if (r->error) {
+ errno = r->error;
+ ret = -1;
+ goto unlock;
+ }
+
/* The mutex is never released while encoding, so this point should
* never be reached if input.valid is true. */
assert(!r->input.valid);
r->input.valid = 1;
pthread_cond_signal(&r->input_cond);
+unlock:
pthread_mutex_unlock(&r->mutex);
+
+ return ret;
}
vaapi_recorder_create(int drm_fd, int width, int height, const char *filename);
void
vaapi_recorder_destroy(struct vaapi_recorder *r);
-void
+int
vaapi_recorder_frame(struct vaapi_recorder *r, int fd, int stride);
#endif /* _VAAPI_RECORDER_H_ */