91 std::unique_lock lock{ *
this };
92 if (file.fileName().isEmpty()) {
94 GST_ELEMENT_ERROR(&baseSrc, RESOURCE, NOT_FOUND,
95 (
"No resource name specified for reading."), (
nullptr));
99 bool opened = file.open(QIODevice::ReadOnly);
102 GST_ELEMENT_ERROR(&baseSrc, RESOURCE, NOT_FOUND, (
nullptr),
103 (
"No such resource \"%s\"", file.fileName().toUtf8().constData()));
107 gst_base_src_set_dynamic_size(&baseSrc,
false);
109 Q_ASSERT(file.isOpen());
130 std::unique_lock guard{ *
this };
133 return GST_FLOW_ERROR;
135 if (G_UNLIKELY(offset != guint64(-1) && guint64(file.pos()) != offset)) {
136 bool success = file.seek(int64_t(offset));
139 GST_ELEMENT_ERROR(&baseSrc, RESOURCE, READ, (
nullptr), GST_ERROR_SYSTEM);
140 return GST_FLOW_ERROR;
145 if (!gst_buffer_map(buf, &info, GST_MAP_WRITE)) {
147 GST_ELEMENT_ERROR(&baseSrc, RESOURCE, WRITE, (
nullptr), (
"Can't map buffer for writing"));
148 return GST_FLOW_ERROR;
151 int64_t remain = length;
152 int64_t totalRead = 0;
154 int64_t bytesRead = file.read(
reinterpret_cast<
char *>(info.data) + totalRead, remain);
155 if (bytesRead == -1) {
157 gst_buffer_unmap(buf, &info);
158 gst_buffer_resize(buf, 0, 0);
162 GST_ELEMENT_ERROR(&baseSrc, RESOURCE, READ, (
nullptr), GST_ERROR_SYSTEM);
163 gst_buffer_unmap(buf, &info);
164 gst_buffer_resize(buf, 0, 0);
165 return GST_FLOW_ERROR;
169 totalRead += bytesRead;
172 gst_buffer_unmap(buf, &info);
173 if (totalRead != length)
174 gst_buffer_resize(buf, 0, totalRead);
176 GST_BUFFER_OFFSET(buf) = offset;
177 GST_BUFFER_OFFSET_END(buf) = offset + totalRead;
194 Q_ASSERT(QLatin1StringView(location).startsWith(
"qrc:/"_L1));
197 std::lock_guard guard{ *
this };
198 GstState state = GST_STATE(
this);
199 if (state != GST_STATE_READY && state != GST_STATE_NULL) {
200 g_warning(
"Changing the `uri' property on qrcsrc when the resource is open is not "
203 g_set_error(err, GST_URI_ERROR, GST_URI_ERROR_BAD_STATE,
204 "Changing the `uri' property on qrcsrc when the resource is open "
205 "is not supported.");
210 std::optional<QString> path = qQUrlToQrcPath(QString::fromUtf8(location));
213 std::lock_guard guard{ *
this };
215 file.setFileName(path.value_or(u""_s));
218 g_object_notify(G_OBJECT(
this),
"uri");
252 GObjectClass *gobjectClass = G_OBJECT_CLASS(klass);
253 gobjectClass->set_property = [](GObject *instance, guint propId,
const GValue *value,
256 return src->setProperty(propId, value, pspec);
259 gobjectClass->get_property = [](GObject *instance, guint propId, GValue *value,
262 return src->getProperty(propId, value, pspec);
265 g_object_class_install_property(
266 gobjectClass, PROP_URI,
267 g_param_spec_string(
"uri",
"QRC Location",
"Path of the qrc to read",
nullptr,
268 GParamFlags(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS
269 | GST_PARAM_MUTABLE_READY)));
271 gobjectClass->finalize = [](GObject *instance) {
274 G_OBJECT_CLASS(parent_class)->finalize(instance);
278 GstElementClass *gstelementClass = GST_ELEMENT_CLASS(klass);
279 gst_element_class_set_static_metadata(gstelementClass,
"QRC Source",
"Source/QRC",
280 "Read from arbitrary point in QRC resource",
281 "Tim Blechmann <tim.blechmann@qt.io>");
283 static GstStaticPadTemplate srctemplate =
284 GST_STATIC_PAD_TEMPLATE(
"src", GST_PAD_SRC, GST_PAD_ALWAYS, GST_STATIC_CAPS_ANY);
286 gst_element_class_add_static_pad_template(gstelementClass, &srctemplate);
289 GstBaseSrcClass *gstbasesrcClass = GST_BASE_SRC_CLASS(klass);
290 gstbasesrcClass->start = [](GstBaseSrc *basesrc) -> gboolean {
291 QGstQrcSrc *src = asQGstQrcSrc(basesrc);
294 gstbasesrcClass->stop = [](GstBaseSrc *basesrc) -> gboolean {
295 QGstQrcSrc *src = asQGstQrcSrc(basesrc);
299 gstbasesrcClass->is_seekable = [](GstBaseSrc *) -> gboolean {
302 gstbasesrcClass->get_size = [](GstBaseSrc *basesrc, guint64 *size) -> gboolean {
303 QGstQrcSrc *src = asQGstQrcSrc(basesrc);
304 auto optionalSize = src->size();
307 *size = optionalSize.value();
310 gstbasesrcClass->fill = [](GstBaseSrc *basesrc, guint64 offset, guint length,
311 GstBuffer *buf) -> GstFlowReturn {
312 QGstQrcSrc *src = asQGstQrcSrc(basesrc);
313 return src->fill(offset, length, buf);
327 GstURIHandlerInterface *iface = (GstURIHandlerInterface *)g_handlerInterface;
329 iface->get_type = [](GType) {
332 iface->get_protocols = [](GType) {
333 static constexpr const gchar *protocols[] = {
339 iface->get_uri = [](GstURIHandler *handler) -> gchar * {
340 QGstQrcSrc *src = asQGstQrcSrc(handler);
341 std::lock_guard guard{ *src };
342 std::optional<QUrl> url = qQrcPathToQUrl(src->file.fileName());
344 return g_strdup(url->toString().toUtf8().constData());
348 iface->set_uri = [](GstURIHandler *handler,
const gchar *uri, GError **err) -> gboolean {
349 QGstQrcSrc *src = asQGstQrcSrc(handler);
350 return src->setURI(uri, err);