131 auto lock = lockObject();
134 return GST_FLOW_ERROR;
136 if (G_UNLIKELY(offset != guint64(-1) && guint64(file.pos()) != offset)) {
137 bool success = file.seek(int64_t(offset));
139 GST_ELEMENT_ERROR(
this, RESOURCE, READ, (
nullptr), GST_ERROR_SYSTEM);
140 return GST_FLOW_ERROR;
145 if (!gst_buffer_map(buf, &info, GST_MAP_WRITE)) {
146 GST_ELEMENT_ERROR(
this, RESOURCE, WRITE, (
nullptr), (
"Can't map buffer for writing"));
147 return GST_FLOW_ERROR;
150 int64_t remain = length;
151 int64_t totalRead = 0;
153 int64_t bytesRead = file.read(
reinterpret_cast<
char *>(info.data) + totalRead, remain);
154 if (bytesRead == -1) {
156 gst_buffer_unmap(buf, &info);
157 gst_buffer_resize(buf, 0, 0);
160 GST_ELEMENT_ERROR(
this, RESOURCE, READ, (
nullptr), GST_ERROR_SYSTEM);
161 gst_buffer_unmap(buf, &info);
162 gst_buffer_resize(buf, 0, 0);
163 return GST_FLOW_ERROR;
167 totalRead += bytesRead;
170 gst_buffer_unmap(buf, &info);
171 if (totalRead != length)
172 gst_buffer_resize(buf, 0, totalRead);
174 GST_BUFFER_OFFSET(buf) = offset;
175 GST_BUFFER_OFFSET_END(buf) = offset + totalRead;
192 Q_ASSERT(QLatin1StringView(location).startsWith(
"qrc:/"_L1));
195 auto lock = lockObject();
196 GstState state = GST_STATE(
this);
197 if (state != GST_STATE_READY && state != GST_STATE_NULL) {
198 g_warning(
"Changing the `uri' property on qrcsrc when the resource is open is not "
201 g_set_error(err, GST_URI_ERROR, GST_URI_ERROR_BAD_STATE,
202 "Changing the `uri' property on qrcsrc when the resource is open "
203 "is not supported.");
208 std::optional<QString> path = qQUrlToQrcPath(QString::fromUtf8(location));
211 auto lock = lockObject();
213 file.setFileName(path.value_or(u""_s));
216 g_object_notify(G_OBJECT(
this),
"uri");
250 GObjectClass *gobjectClass = G_OBJECT_CLASS(klass);
251 gobjectClass->set_property = [](GObject *instance, guint propId,
const GValue *value,
254 return src->setProperty(propId, value, pspec);
257 gobjectClass->get_property = [](GObject *instance, guint propId, GValue *value,
260 return src->getProperty(propId, value, pspec);
263 g_object_class_install_property(
264 gobjectClass, PROP_URI,
265 g_param_spec_string(
"uri",
"QRC Location",
"Path of the qrc to read",
nullptr,
266 GParamFlags(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS
267 | GST_PARAM_MUTABLE_READY)));
269 gobjectClass->finalize = [](GObject *instance) {
272 G_OBJECT_CLASS(parent_class)->finalize(instance);
276 GstElementClass *gstelementClass = GST_ELEMENT_CLASS(klass);
277 gst_element_class_set_static_metadata(gstelementClass,
"QRC Source",
"Source/QRC",
278 "Read from arbitrary point in QRC resource",
279 "Tim Blechmann <tim.blechmann@qt.io>");
281 static GstStaticPadTemplate srctemplate =
282 GST_STATIC_PAD_TEMPLATE(
"src", GST_PAD_SRC, GST_PAD_ALWAYS, GST_STATIC_CAPS_ANY);
284 gst_element_class_add_static_pad_template(gstelementClass, &srctemplate);
287 GstBaseSrcClass *gstbasesrcClass = GST_BASE_SRC_CLASS(klass);
288 gstbasesrcClass->start = [](GstBaseSrc *basesrc) -> gboolean {
289 QGstQrcSrc *src = asQGstQrcSrc(basesrc);
292 gstbasesrcClass->stop = [](GstBaseSrc *basesrc) -> gboolean {
293 QGstQrcSrc *src = asQGstQrcSrc(basesrc);
297 gstbasesrcClass->is_seekable = [](GstBaseSrc *) -> gboolean {
300 gstbasesrcClass->get_size = [](GstBaseSrc *basesrc, guint64 *size) -> gboolean {
301 QGstQrcSrc *src = asQGstQrcSrc(basesrc);
302 auto optionalSize = src->size();
305 *size = optionalSize.value();
308 gstbasesrcClass->fill = [](GstBaseSrc *basesrc, guint64 offset, guint length,
309 GstBuffer *buf) -> GstFlowReturn {
310 QGstQrcSrc *src = asQGstQrcSrc(basesrc);
311 return src->fill(offset, length, buf);
325 GstURIHandlerInterface *iface = (GstURIHandlerInterface *)g_handlerInterface;
327 iface->get_type = [](GType) {
330 iface->get_protocols = [](GType) {
331 static constexpr const gchar *protocols[] = {
337 iface->get_uri = [](GstURIHandler *handler) -> gchar * {
338 QGstQrcSrc *src = asQGstQrcSrc(handler);
339 auto lock = src->lockObject();
340 std::optional<QUrl> url = qQrcPathToQUrl(src->file.fileName());
342 return g_strdup(url->toString().toUtf8().constData());
346 iface->set_uri = [](GstURIHandler *handler,
const gchar *uri, GError **err) -> gboolean {
347 QGstQrcSrc *src = asQGstQrcSrc(handler);
348 return src->setURI(uri, err);