if (!drv)
return VA_STATUS_ERROR_INVALID_CONTEXT;
- pipe_mutex_lock(drv->mutex);
+ mtx_lock(&drv->mutex);
context = handle_table_get(drv->htab, context_id);
if (!context) {
- pipe_mutex_unlock(drv->mutex);
+ mtx_unlock(&drv->mutex);
return VA_STATUS_ERROR_INVALID_CONTEXT;
}
surf = handle_table_get(drv->htab, render_target);
- pipe_mutex_unlock(drv->mutex);
+ mtx_unlock(&drv->mutex);
if (!surf || !surf->buffer)
return VA_STATUS_ERROR_INVALID_SURFACE;
context->target_id = render_target;
surf->ctx = context_id;
context->target = surf->buffer;
+ context->mjpeg.sampling_factor = 0;
if (!context->decoder) {
context->target->buffer_format != PIPE_FORMAT_R8G8B8A8_UNORM &&
context->target->buffer_format != PIPE_FORMAT_B8G8R8X8_UNORM &&
context->target->buffer_format != PIPE_FORMAT_R8G8B8X8_UNORM &&
- context->target->buffer_format != PIPE_FORMAT_NV12)
+ context->target->buffer_format != PIPE_FORMAT_NV12 &&
+ context->target->buffer_format != PIPE_FORMAT_P016)
return VA_STATUS_ERROR_UNIMPLEMENTED;
return VA_STATUS_SUCCESS;
context->desc.h264enc.rate_ctrl.fill_data_enable = 1;
context->desc.h264enc.rate_ctrl.enforce_hrd = 1;
context->desc.h264enc.enable_vui = false;
- if (context->desc.h264enc.rate_ctrl.frame_rate_num == 0)
- context->desc.h264enc.rate_ctrl.frame_rate_num = 30;
+ if (context->desc.h264enc.rate_ctrl.frame_rate_num == 0 ||
+ context->desc.h264enc.rate_ctrl.frame_rate_den == 0) {
+ context->desc.h264enc.rate_ctrl.frame_rate_num = 30;
+ context->desc.h264enc.rate_ctrl.frame_rate_den = 1;
+ }
context->desc.h264enc.rate_ctrl.target_bits_picture =
- context->desc.h264enc.rate_ctrl.target_bitrate / context->desc.h264enc.rate_ctrl.frame_rate_num;
+ context->desc.h264enc.rate_ctrl.target_bitrate *
+ ((float)context->desc.h264enc.rate_ctrl.frame_rate_den /
+ context->desc.h264enc.rate_ctrl.frame_rate_num);
context->desc.h264enc.rate_ctrl.peak_bits_picture_integer =
- context->desc.h264enc.rate_ctrl.peak_bitrate / context->desc.h264enc.rate_ctrl.frame_rate_num;
- context->desc.h264enc.rate_ctrl.peak_bits_picture_fraction = 0;
+ context->desc.h264enc.rate_ctrl.peak_bitrate *
+ ((float)context->desc.h264enc.rate_ctrl.frame_rate_den /
+ context->desc.h264enc.rate_ctrl.frame_rate_num);
+ context->desc.h264enc.rate_ctrl.peak_bits_picture_fraction = 0;
context->desc.h264enc.ref_pic_mode = 0x00000201;
}
vlVaHandlePictureParameterBufferHEVC(drv, context, buf);
break;
+ case PIPE_VIDEO_FORMAT_JPEG:
+ vlVaHandlePictureParameterBufferMJPEG(drv, context, buf);
+ break;
+
default:
break;
}
/* Create the decoder once max_references is known. */
if (!context->decoder) {
+ enum pipe_video_format format =
+ u_reduce_video_profile(context->templat.profile);
+
if (!context->target)
return VA_STATUS_ERROR_INVALID_CONTEXT;
- if (context->templat.max_references == 0)
+ if (context->templat.max_references == 0 &&
+ format != PIPE_VIDEO_FORMAT_JPEG)
return VA_STATUS_ERROR_INVALID_BUFFER;
- if (u_reduce_video_profile(context->templat.profile) ==
- PIPE_VIDEO_FORMAT_MPEG4_AVC)
+ if (format == PIPE_VIDEO_FORMAT_MPEG4_AVC)
context->templat.level = u_get_h264_level(context->templat.width,
context->templat.height, &context->templat.max_references);
vlVaHandleIQMatrixBufferHEVC(context, buf);
break;
+ case PIPE_VIDEO_FORMAT_JPEG:
+ vlVaHandleIQMatrixBufferMJPEG(context, buf);
+ break;
+
default:
break;
}
vlVaHandleSliceParameterBufferHEVC(context, buf);
break;
+ case PIPE_VIDEO_FORMAT_JPEG:
+ vlVaHandleSliceParameterBufferMJPEG(context, buf);
+ break;
+
default:
break;
}
vlVaDecoderFixMPEG4Startcode(context);
buffers[num_buffers] = (void *)context->mpeg4.start_code;
sizes[num_buffers++] = context->mpeg4.start_code_size;
+ case PIPE_VIDEO_FORMAT_JPEG:
+ /* TODO */
+ break;
default:
break;
}
handleVAEncMiscParameterTypeFrameRate(vlVaContext *context, VAEncMiscParameterBuffer *misc)
{
VAEncMiscParameterFrameRate *fr = (VAEncMiscParameterFrameRate *)misc->data;
- context->desc.h264enc.rate_ctrl.frame_rate_num = fr->framerate;
+ if (fr->framerate & 0xffff0000) {
+ context->desc.h264enc.rate_ctrl.frame_rate_num = fr->framerate & 0xffff;
+ context->desc.h264enc.rate_ctrl.frame_rate_den = fr->framerate >> 16 & 0xffff;
+ } else {
+ context->desc.h264enc.rate_ctrl.frame_rate_num = fr->framerate;
+ context->desc.h264enc.rate_ctrl.frame_rate_den = 1;
+ }
return VA_STATUS_SUCCESS;
}
context->gop_coeff = VL_VA_ENC_GOP_COEFF;
context->desc.h264enc.gop_size = h264->intra_idr_period * context->gop_coeff;
context->desc.h264enc.rate_ctrl.frame_rate_num = h264->time_scale / 2;
- context->desc.h264enc.rate_ctrl.frame_rate_den = 1;
+ context->desc.h264enc.rate_ctrl.frame_rate_den = h264->num_units_in_tick;
return VA_STATUS_SUCCESS;
}
PIPE_USAGE_STREAM, coded_buf->size);
context->coded_buf = coded_buf;
- context->desc.h264enc.frame_idx[h264->CurrPic.picture_id] = h264->frame_num;
+ util_hash_table_set(context->desc.h264enc.frame_idx,
+ UINT_TO_PTR(h264->CurrPic.picture_id),
+ UINT_TO_PTR(h264->frame_num));
+
if (context->desc.h264enc.is_idr)
context->desc.h264enc.picture_type = PIPE_H264_ENC_PICTURE_TYPE_IDR;
else
for (int i = 0; i < 32; i++) {
if (h264->RefPicList0[i].picture_id != VA_INVALID_ID) {
if (context->desc.h264enc.ref_idx_l0 == VA_INVALID_ID)
- context->desc.h264enc.ref_idx_l0 = context->desc.h264enc.frame_idx[h264->RefPicList0[i].picture_id];
+ context->desc.h264enc.ref_idx_l0 = PTR_TO_UINT(util_hash_table_get(context->desc.h264enc.frame_idx,
+ UINT_TO_PTR(h264->RefPicList0[i].picture_id)));
}
if (h264->RefPicList1[i].picture_id != VA_INVALID_ID && h264->slice_type == 1) {
if (context->desc.h264enc.ref_idx_l1 == VA_INVALID_ID)
- context->desc.h264enc.ref_idx_l1 = context->desc.h264enc.frame_idx[h264->RefPicList1[i].picture_id];
+ context->desc.h264enc.ref_idx_l1 = PTR_TO_UINT(util_hash_table_get(context->desc.h264enc.frame_idx,
+ UINT_TO_PTR(h264->RefPicList1[i].picture_id)));
}
}
if (!drv)
return VA_STATUS_ERROR_INVALID_CONTEXT;
- pipe_mutex_lock(drv->mutex);
+ mtx_lock(&drv->mutex);
context = handle_table_get(drv->htab, context_id);
if (!context) {
- pipe_mutex_unlock(drv->mutex);
+ mtx_unlock(&drv->mutex);
return VA_STATUS_ERROR_INVALID_CONTEXT;
}
for (i = 0; i < num_buffers; ++i) {
vlVaBuffer *buf = handle_table_get(drv->htab, buffers[i]);
if (!buf) {
- pipe_mutex_unlock(drv->mutex);
+ mtx_unlock(&drv->mutex);
return VA_STATUS_ERROR_INVALID_BUFFER;
}
vaStatus = handleVAEncSliceParameterBufferType(drv, context, buf);
break;
+ case VAHuffmanTableBufferType:
+ vlVaHandleHuffmanTableBufferType(context, buf);
+ break;
+
default:
break;
}
}
- pipe_mutex_unlock(drv->mutex);
+ mtx_unlock(&drv->mutex);
return vaStatus;
}
vlVaBuffer *coded_buf;
vlVaSurface *surf;
void *feedback;
+ struct pipe_screen *screen;
+ bool interlaced;
+ bool realloc = false;
+ enum pipe_format format;
if (!ctx)
return VA_STATUS_ERROR_INVALID_CONTEXT;
if (!drv)
return VA_STATUS_ERROR_INVALID_CONTEXT;
- pipe_mutex_lock(drv->mutex);
+ mtx_lock(&drv->mutex);
context = handle_table_get(drv->htab, context_id);
- pipe_mutex_unlock(drv->mutex);
+ mtx_unlock(&drv->mutex);
if (!context)
return VA_STATUS_ERROR_INVALID_CONTEXT;
return VA_STATUS_SUCCESS;
}
- pipe_mutex_lock(drv->mutex);
+ mtx_lock(&drv->mutex);
surf = handle_table_get(drv->htab, context->target_id);
context->mpeg4.frame_num++;
+ screen = context->decoder->context->screen;
+ interlaced = screen->get_video_param(screen, context->decoder->profile,
+ PIPE_VIDEO_ENTRYPOINT_BITSTREAM,
+ PIPE_VIDEO_CAP_SUPPORTS_INTERLACED);
+
+ if (surf->buffer->interlaced != interlaced) {
+ surf->templat.interlaced = screen->get_video_param(screen, context->decoder->profile,
+ PIPE_VIDEO_ENTRYPOINT_BITSTREAM,
+ PIPE_VIDEO_CAP_PREFERS_INTERLACED);
+ realloc = true;
+ }
+
+ format = screen->get_video_param(screen, context->decoder->profile,
+ PIPE_VIDEO_ENTRYPOINT_BITSTREAM,
+ PIPE_VIDEO_CAP_PREFERED_FORMAT);
+
+ if (surf->buffer->buffer_format != format &&
+ surf->buffer->buffer_format == PIPE_FORMAT_NV12) {
+ /* check originally as NV12 only */
+ surf->templat.buffer_format = format;
+ realloc = true;
+ }
+
+ if (u_reduce_video_profile(context->templat.profile) == PIPE_VIDEO_FORMAT_JPEG &&
+ surf->buffer->buffer_format == PIPE_FORMAT_NV12) {
+ if (context->mjpeg.sampling_factor == 0x211111 ||
+ context->mjpeg.sampling_factor == 0x221212) {
+ surf->templat.buffer_format = PIPE_FORMAT_YUYV;
+ realloc = true;
+ } else if (context->mjpeg.sampling_factor != 0x221111) {
+ /* Not NV12 either */
+ mtx_unlock(&drv->mutex);
+ return VA_STATUS_ERROR_INVALID_SURFACE;
+ }
+ }
+
+ if (realloc) {
+ surf->buffer->destroy(surf->buffer);
+
+ if (vlVaHandleSurfaceAllocate(ctx, surf, &surf->templat) != VA_STATUS_SUCCESS) {
+ mtx_unlock(&drv->mutex);
+ return VA_STATUS_ERROR_ALLOCATION_FAILED;
+ }
+
+ context->target = surf->buffer;
+ }
+
if (context->decoder->entrypoint == PIPE_VIDEO_ENTRYPOINT_ENCODE) {
coded_buf = context->coded_buf;
getEncParamPreset(context);
surf->force_flushed = true;
}
}
- pipe_mutex_unlock(drv->mutex);
+ mtx_unlock(&drv->mutex);
return VA_STATUS_SUCCESS;
}