diff --git a/src/h264.c b/src/h264.c index f41a88c..ee28469 100644 --- a/src/h264.c +++ b/src/h264.c @@ -186,12 +186,15 @@ static void h264_fill_dpb(struct request_data *data, struct h264_dpb_entry *entry = &context->dpb.entries[i]; struct object_surface *surface = SURFACE(data, entry->pic.picture_id); + uint64_t timestamp; if (!entry->valid) continue; - if (surface) - dpb->buf_index = surface->destination_index; + if (surface) { + timestamp = v4l2_timeval_to_ns(&surface->timestamp); + dpb->timestamp = timestamp; + } dpb->frame_num = entry->pic.frame_idx; dpb->top_field_order_cnt = entry->pic.TopFieldOrderCnt; diff --git a/src/h265.c b/src/h265.c index fac9d33..4650a51 100644 --- a/src/h265.c +++ b/src/h265.c @@ -272,6 +272,8 @@ static void h265_fill_slice_params(VAPictureParameterBufferHEVC *picture, num_rps_poc_lt_curr = 0; for (i = 0; i < 15 && slice_type != V4L2_HEVC_SLICE_TYPE_I ; i++) { + uint64_t timestamp; + hevc_picture = &picture->ReferenceFrames[i]; if (hevc_picture->picture_id == VA_INVALID_SURFACE || @@ -284,8 +286,8 @@ static void h265_fill_slice_params(VAPictureParameterBufferHEVC *picture, if (surface_object == NULL) break; - slice_params->dpb[i].buffer_index = - surface_object->destination_index; + timestamp = v4l2_timeval_to_ns(&surface_object->timestamp); + slice_params->dpb[i].timestamp = timestamp; if ((hevc_picture->flags & VA_PICTURE_HEVC_RPS_ST_CURR_BEFORE) != 0) { slice_params->dpb[i].rps = diff --git a/src/mpeg2.c b/src/mpeg2.c index 9916366..9297fc5 100644 --- a/src/mpeg2.c +++ b/src/mpeg2.c @@ -54,6 +54,7 @@ int mpeg2_set_controls(struct request_data *driver_data, struct v4l2_ctrl_mpeg2_quantization quantization; struct object_surface *forward_reference_surface; struct object_surface *backward_reference_surface; + uint64_t timestamp; unsigned int i; int rc; @@ -102,21 +103,19 @@ int mpeg2_set_controls(struct request_data *driver_data, forward_reference_surface = SURFACE(driver_data, picture->forward_reference_picture); - if (forward_reference_surface != NULL) - slice_params.forward_ref_index = - forward_reference_surface->destination_index; - else - slice_params.forward_ref_index = - surface_object->destination_index; + if (forward_reference_surface == NULL) + forward_reference_surface = surface_object; + + timestamp = v4l2_timeval_to_ns(&forward_reference_surface->timestamp); + slice_params.forward_ref_ts = timestamp; backward_reference_surface = SURFACE(driver_data, picture->backward_reference_picture); - if (backward_reference_surface != NULL) - slice_params.backward_ref_index = - backward_reference_surface->destination_index; - else - slice_params.backward_ref_index = - surface_object->destination_index; + if (backward_reference_surface == NULL) + backward_reference_surface = surface_object; + + timestamp = v4l2_timeval_to_ns(&backward_reference_surface->timestamp); + slice_params.backward_ref_ts = timestamp; rc = v4l2_set_control(driver_data->video_fd, surface_object->request_fd, V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS, diff --git a/src/picture.c b/src/picture.c index 6f18e23..aa86265 100644 --- a/src/picture.c +++ b/src/picture.c @@ -296,6 +296,8 @@ VAStatus RequestEndPicture(VADriverContextP context, VAContextID context_id) if (surface_object == NULL) return VA_STATUS_ERROR_INVALID_SURFACE; + gettimeofday(&surface_object->timestamp, NULL); + request_fd = surface_object->request_fd; if (request_fd < 0) { request_fd = media_request_alloc(driver_data->media_fd); @@ -310,13 +312,14 @@ VAStatus RequestEndPicture(VADriverContextP context, VAContextID context_id) if (rc != VA_STATUS_SUCCESS) return rc; - rc = v4l2_queue_buffer(driver_data->video_fd, -1, capture_type, + rc = v4l2_queue_buffer(driver_data->video_fd, -1, capture_type, NULL, surface_object->destination_index, 0, surface_object->destination_buffers_count); if (rc < 0) return VA_STATUS_ERROR_OPERATION_FAILED; rc = v4l2_queue_buffer(driver_data->video_fd, request_fd, output_type, + &surface_object->timestamp, surface_object->source_index, surface_object->slices_size, 1); if (rc < 0) diff --git a/src/surface.h b/src/surface.h index 0da39ae..41007f8 100644 --- a/src/surface.h +++ b/src/surface.h @@ -62,6 +62,8 @@ struct object_surface { unsigned int slices_size; unsigned int slices_count; + struct timeval timestamp; + union { struct { VAPictureParameterBufferMPEG2 picture; diff --git a/src/v4l2.c b/src/v4l2.c index 250b054..d5000ac 100644 --- a/src/v4l2.c +++ b/src/v4l2.c @@ -330,8 +330,8 @@ int v4l2_request_buffers(int video_fd, unsigned int type, } int v4l2_queue_buffer(int video_fd, int request_fd, unsigned int type, - unsigned int index, unsigned int size, - unsigned int buffers_count) + struct timeval *timestamp, unsigned int index, + unsigned int size, unsigned int buffers_count) { struct v4l2_plane planes[buffers_count]; struct v4l2_buffer buffer; @@ -358,6 +358,9 @@ int v4l2_queue_buffer(int video_fd, int request_fd, unsigned int type, buffer.request_fd = request_fd; } + if (timestamp != NULL) + buffer.timestamp = *timestamp; + rc = ioctl(video_fd, VIDIOC_QBUF, &buffer); if (rc < 0) { request_log("Unable to queue buffer: %s\n", strerror(errno)); diff --git a/src/v4l2.h b/src/v4l2.h index ec40080..73e9a42 100644 --- a/src/v4l2.h +++ b/src/v4l2.h @@ -47,8 +47,8 @@ int v4l2_query_buffer(int video_fd, unsigned int type, unsigned int index, int v4l2_request_buffers(int video_fd, unsigned int type, unsigned int buffers_count); int v4l2_queue_buffer(int video_fd, int request_fd, unsigned int type, - unsigned int index, unsigned int size, - unsigned int buffers_count); + struct timeval *timestamp, unsigned int index, + unsigned int size, unsigned int buffers_count); int v4l2_dequeue_buffer(int video_fd, int request_fd, unsigned int type, unsigned int index, unsigned int buffers_count); int v4l2_export_buffer(int video_fd, unsigned int type, unsigned int index,