The open source OpenXR runtime
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

d/vf: Refactor frame handling

authored by

Jakob Bornecrantz and committed by
Jakob Bornecrantz
a6a5b3dd f04a1136

+97 -31
+97 -31
src/xrt/drivers/vf/vf_driver.c
··· 91 91 enum u_logging_level ll; 92 92 }; 93 93 94 + /*! 95 + * Frame wrapping a GstSample/GstBuffer. 96 + * 97 + * @implements xrt_frame 98 + */ 99 + struct vf_frame 100 + { 101 + struct xrt_frame base; 102 + 103 + GstSample *sample; 104 + 105 + GstVideoFrame frame; 106 + }; 107 + 94 108 95 109 /* 96 110 * 97 - * Misc helper functions 111 + * Cast helpers. 98 112 * 99 113 */ 100 114 ··· 106 120 { 107 121 return (struct vf_fs *)xfs; 108 122 } 123 + 124 + /*! 125 + * Cast to derived type. 126 + */ 127 + static inline struct vf_frame * 128 + vf_frame(struct xrt_frame *xf) 129 + { 130 + return (struct vf_frame *)xf; 131 + } 132 + 133 + 134 + /* 135 + * 136 + * Frame methods. 137 + * 138 + */ 139 + 140 + static void 141 + vf_frame_destroy(struct xrt_frame *xf) 142 + { 143 + struct vf_frame *vff = vf_frame(xf); 144 + 145 + gst_video_frame_unmap(&vff->frame); 146 + 147 + if (vff->sample != NULL) { 148 + gst_sample_unref(vff->sample); 149 + vff->sample = NULL; 150 + } 151 + 152 + free(vff); 153 + } 154 + 155 + 156 + /* 157 + * 158 + * Misc helper functions 159 + * 160 + */ 161 + 109 162 110 163 static void 111 164 vf_fs_frame(struct vf_fs *vid, GstSample *sample) 112 165 { 166 + // Noop. 167 + if (!vid->sink) { 168 + return; 169 + } 170 + 171 + GstVideoInfo info; 113 172 GstBuffer *buffer; 173 + GstCaps *caps; 114 174 buffer = gst_sample_get_buffer(sample); 115 - GstCaps *caps = gst_sample_get_caps(sample); 116 - 117 - static int seq = 0; 175 + caps = gst_sample_get_caps(sample); 118 176 119 - GstVideoFrame frame; 120 - GstVideoInfo info; 121 177 gst_video_info_init(&info); 122 178 gst_video_info_from_caps(&info, caps); 123 - if (gst_video_frame_map(&frame, &info, buffer, GST_MAP_READ)) { 124 179 125 - int plane = 0; 180 + static int seq = 0; 181 + struct vf_frame *vff = U_TYPED_CALLOC(struct vf_frame); 126 182 127 - struct xrt_frame *xf = NULL; 183 + if (!gst_video_frame_map(&vff->frame, &info, buffer, GST_MAP_READ)) { 184 + VF_ERROR(vid, "Failed to map frame %d", seq); 185 + // Yes, we should do this here because we don't want the destroy function to to run. 186 + free(vff); 187 + return; 188 + } 128 189 129 - u_frame_create_one_off(vid->format, vid->width, vid->height, &xf); 190 + // We now want to hold onto the sample for as long as the frame lives. 191 + gst_sample_ref(sample); 192 + vff->sample = sample; 130 193 131 - //! @todo Sequence number and timestamp. 132 - xf->width = vid->width; 133 - xf->height = vid->height; 134 - xf->format = vid->format; 135 - xf->stereo_format = vid->stereo_format; 194 + // Hardcoded first plane. 195 + int plane = 0; 136 196 137 - xf->data = frame.data[plane]; 138 - xf->stride = info.stride[plane]; 139 - xf->size = info.size; 140 - xf->source_id = vid->base.source_id; 141 - xf->source_sequence = seq; 142 - xf->timestamp = os_monotonic_get_ns(); 143 - if (vid->sink) { 144 - vid->sink->push_frame(vid->sink, xf); 145 - // The frame is requeued as soon as the refcount reaches 146 - // zero, this can be done safely from another thread. 147 - // xrt_frame_reference(&xf, NULL); 148 - } 149 - gst_video_frame_unmap(&frame); 150 - } else { 151 - VF_ERROR(vid, "Failed to map frame %d", seq); 152 - } 197 + struct xrt_frame *xf = &vff->base; 198 + xf->reference.count = 1; 199 + xf->destroy = vf_frame_destroy; 200 + xf->width = vid->width; 201 + xf->height = vid->height; 202 + xf->format = vid->format; 203 + xf->stride = info.stride[plane]; 204 + xf->data = vff->frame.data[plane]; 205 + xf->stereo_format = vid->stereo_format; 206 + xf->size = info.size; 207 + xf->source_id = vid->base.source_id; 208 + 209 + //! @todo Proper sequence number and timestamp. 210 + xf->source_sequence = seq; 211 + xf->timestamp = os_monotonic_get_ns(); 212 + 213 + xrt_sink_push_frame(vid->sink, &vff->base); 214 + 215 + xrt_frame_reference(&xf, NULL); 216 + vff = NULL; 153 217 154 218 seq++; 155 219 } ··· 179 243 return GST_FLOW_OK; 180 244 } 181 245 246 + // Takes ownership of the sample. 182 247 vf_fs_frame(vid, sample); 183 248 249 + // Done with sample now. 184 250 gst_sample_unref(sample); 185 251 186 252 return GST_FLOW_OK;