if (!surf || !surf->buffer)
return VA_STATUS_ERROR_INVALID_SURFACE;
+ context->target_id = render_target;
+ surf->ctx = context_id;
context->target = surf->buffer;
if (!context->decoder) {
vlVaDriver *drv;
vlVaContext *context;
vlVaBuffer *coded_buf;
+ vlVaSurface *surf;
unsigned int coded_size;
void *feedback;
return VA_STATUS_SUCCESS;
}
+ pipe_mutex_lock(drv->mutex);
+ surf = handle_table_get(drv->htab, context->target_id);
context->mpeg4.frame_num++;
if (context->decoder->entrypoint == PIPE_VIDEO_ENTRYPOINT_ENCODE) {
context->decoder->begin_frame(context->decoder, context->target, &context->desc.base);
context->decoder->encode_bitstream(context->decoder, context->target,
coded_buf->derived_surface.resource, &feedback);
+ surf->frame_num_cnt = context->desc.h264enc.frame_num_cnt;
+ surf->feedback = feedback;
+ surf->coded_buf = coded_buf;
context->decoder->end_frame(context->decoder, context->target, &context->desc.base);
- context->decoder->flush(context->decoder);
- context->decoder->get_feedback(context->decoder, feedback, &coded_size);
- coded_buf->coded_size = coded_size;
}
else
context->decoder->end_frame(context->decoder, context->target, &context->desc.base);
+ pipe_mutex_unlock(drv->mutex);
return VA_STATUS_SUCCESS;
}
VAStatus
vlVaSyncSurface(VADriverContextP ctx, VASurfaceID render_target)
{
+ vlVaDriver *drv;
+ vlVaContext *context;
+ vlVaSurface *surf;
+ void *pbuff;
+
if (!ctx)
return VA_STATUS_ERROR_INVALID_CONTEXT;
+ drv = VL_VA_DRIVER(ctx);
+ if (!drv)
+ return VA_STATUS_ERROR_INVALID_CONTEXT;
+
+ pipe_mutex_lock(drv->mutex);
+ surf = handle_table_get(drv->htab, render_target);
+
+ if (!surf || !surf->buffer)
+ return VA_STATUS_ERROR_INVALID_SURFACE;
+
+ context = handle_table_get(drv->htab, surf->ctx);
+ if (!context) {
+ pipe_mutex_unlock(drv->mutex);
+ return VA_STATUS_ERROR_INVALID_CONTEXT;
+ }
+
+ if (context->decoder->entrypoint == PIPE_VIDEO_ENTRYPOINT_ENCODE) {
+ int frame_diff;
+ if (context->desc.h264enc.frame_num_cnt > surf->frame_num_cnt)
+ frame_diff = context->desc.h264enc.frame_num_cnt - surf->frame_num_cnt;
+ else
+ frame_diff = 0xFFFFFFFF - surf->frame_num_cnt + 1 + context->desc.h264enc.frame_num_cnt;
+ if (frame_diff < 2)
+ context->decoder->flush(context->decoder);
+ context->decoder->get_feedback(context->decoder, surf->feedback, &(surf->coded_buf->coded_size));
+ }
+ pipe_mutex_unlock(drv->mutex);
return VA_STATUS_SUCCESS;
}
struct vl_deint_filter *deint;
struct vlVaBuffer *coded_buf;
+ int target_id;
} vlVaContext;
typedef struct {
typedef struct {
struct pipe_video_buffer templat, *buffer;
struct util_dynarray subpics; /* vlVaSubpicture */
+ VAContextID ctx;
+ vlVaBuffer *coded_buf;
+ void *feedback;
+ unsigned int frame_num_cnt;
} vlVaSurface;
// Public functions: