Beiträge von zirias

    Nur mal zum Vergleich, da es bei mir ja funktioniert: Ich starte vdr-sxfe im Moment folgendermaßen:

    Code
    vdr-sxfe --video=xv --audio=alsa --hotkeys --lirc --width=1024 --height=576 xvdr://${HOST:-127.0.0.1}


    Meine ersten Ideen wären jetzt, Probleme bei alsa und/oder xv zu suchen. Ich nehme an wir haben die gleiche Version installiert, kann ich aber erst nachsehen wenn ich zuhause bin.


    "hier" schließt natürlich ein "die Software, die ich nutze". Das ist momentan ein vollständiger KDE4 (mit Kontact, Amarok, K3b), Chromium, Gimp, Libreoffice und insbesondere eben vdr-sxfe. Und das tut eben. Einen Kernel konnte ich nicht nutzen, weil der beim KMS für meine Radeon (AMD APU) abgestürzt ist -- ein älterer hat aber funktioniert und mittlerweile ist das Problem behoben und ich bin auf dem aktuellsten Kernel. Das war bisher das einzige Problem, das ich mit Wheezy beobachtet habe. Daher komme ich zu dem Schluss:


    Wheezy läuft HIER perfekt ;)

    Wheezy läuft hier perfekt (auch nach mehreren größeren dist-upgrades), vdr und vdr-sxfe aus den originalen wheezy Paketquellen.


    Firefox/Iceweasel hab ich schon einige Zeit vorher konsequent durch Chromium ersetzt weil es zu fett und langsam geworden war, kann DAZU also nichts sagen.

    Der VDR ist kompakt geschrieben, mit Blick auf Effizienz und wenig Speicherverbrauch.
    Wenn ich mir da anschaue, wie großzügig Du mit int32 umgehst - ohne nachzudenken und ohne Not.
    Hm, das sieht für mich nicht so aus, als hättest Du viel Erfahrung in C-Programmierung.


    Also schau dir mal die Wertebereiche der Zahlendatentypen an.
    Die Anzahl an Audiokanälen passt locker in einen char-Datentyp (0 - 256 unsigned, bzw. bis 127 signed - reicht auch noch ewig)
    Wenn Du einen numerischen Funktionsparameter brauchst, ist int das performanteste. also lieber dann in der Funktion konvertieren. Die Konvertierung von Ganzzahlen kleiner int nach int macht der Compiler implizit. Nur andersherum brauchst Du nen cast.


    Ohne den Thread jetzt ZU sehr aufzublähen, aber zumindest das ist ausgemachter Quatsch. Erstens mal ist "wenig Speicherverbrauch" nicht automatisch effizient, wenn man dafür dann unterschiedliche Werte in einem Wort mühevoll "auseinanderklamüsern" muss wo man sie ansonsten (bei gescheitem alignment) sehr effizient in Datenregister laden könnte. Was interessiert dich mehr, eine Handvoll "verschwendete" Bytes in einer Datenstruktur (bei RAM-Größen von mehreren GB) oder verschwendete Rechenzyklen in einem tight loop? Zweitens: Nein, nicht "int" ist das performanteste sondern das native Wort des Systems. Das wäre auf AMD64 ein 64bit-Wort (z.B. int64_t). Bei GCC hat man aber entschieden, dass int auch auf AMD64 einem 32bit-Wort entspricht. "int" ist meistens das performanteste, aber eben nicht immer.


    edit: Ich MUSS auch was zum Coding-Stil sagen. Mir stößt schon, wie schon erwähnt, diese ungarische Notation in der VDR codebase übel auf. Das macht heute keiner mehr. es hilft nicht fürs Verständnis und verunstaltet die Namen mit sinnlosen Zusatz-Buchstaben. Auch andere Dinge gefallen mir nicht. Wenn ich direkt an einer Codebase arbeite (sagen wir, ich würde einen Patch für VDR bauen) -- dann halte ich mich selbstverständlich GANZ genau an den bereits vorhandenen Stil. Hab ich bei mutt gemacht (keine Ahnung, was ich seinerzeit daran "gepatcht" habe) -- würd ich bei jedem anderen OSS Projekt machen. ABER: Ein Plugin ist was anderes ... das hat ne klar definierte Schnittstelle, die es einzuhalten gilt. Der Rest ist allein MEINE SACHE, als Entwickler. Wenn am Ende was besser lesbares rauskommt als der original VDR Code -- mir soll es recht sein. /edit

    hmm.. so hatte ich es erst. Da aber die Klasse cMetadata in etwa die gleiche Struktur hat, wie die SQLite-Tabellen, weiß ich dann nicht, wie ich eine Suche über diese Felder durchführe. Es war auch so Gedacht, dass die wichtigsten Felder über Getter/Setter schnell erreichbar sind, wobei die theoretisch hinten heraus in die gleiche Datenstruktur schreiben und lesen könnten. Hmm.. wie gesagt, wenn mir jemand erklärt, wie ich die Property-Liste effizient in eine Datenbank pressen, aber immer noch über die Felder eine SQL-Suche durchführen kann, wäre die Idee auch nicht sooo blöd.


    Also ich würde ja einfach mal sagen: Es gibt keinen zwingenden Grund, die Struktur in Tabellen 1:1 in Objekten nachzubilden (oder umgekehrt). Die Persistenzschicht muss sowieso Daten kopieren und Objekte anlegen, dabei kann auch die Struktur verändert werden, und Tabellen sind eben was anderes als Objekte (passt auch zu der Frage Objektgraph oder Sammlung von Objekten mit IDs).


    Aber letztlich ist es natürlich ein Implementierungsdetail (das ist jetzt der "Fehler" von C++, dass es am Interface ÜBERHAUPT erkennbar wird, wie du es machst). Du kannst natürlich auch mit anderen Mitteln verhindern, dass GetPropertyByKey("Title").GetValue() etwas anderes liefert als GetTitle(). Auf jeden Fall (egal wie es nun intern aussieht) fände ich string-Konstanten für die "well-known properties" sinnvoll.

    Hi,
    habe mir jetzt nur die Metadata Klasse angesehen, dazu ein paar Ideen, über die man natürlich geteilter Meinung sein kann.


    (0. ich find Ungarische Notation für Klassennamen doof, aber ich weiß, dass das VDR Coding Stil ist *fg*)


    1. string cMetadata::Property::operator()() -- würde mir überlegen, ob ich das nicht lieber weglasse. Die Property enthält ja zwei Strings, Key und Value, und ich meine es wäre saubererer (und selbstdokumentierender) Code, auf diese auch explizit zuzugreifen.


    2. cMetadata::AddProperty() und cMetaData::SetProperty() -- könnte ich mir Überladungen mit string key, string/long/bool value vorstellen, als "convenience". Die Semantik bei cMetaData::SetProperty() müsste dafür natürlich genau geklärt sein (alle existierenden mit dem Key weg, nur den ersten überschreiben, ...?)


    3. cMetaData::SetParentID() und cMetaData::SetParentID() -- sind nur für die Persistenz da, richtig? Ich glaube nicht, dass sie dann ins objektorientierte Interface gehören -- da würde ich eher Dinge erwarten wie Get/SetParent() und Get/Set/AddChildren().


    4. Title, UpnpClass, Restricted, Description usw sind wie ich das verstehe "well-known properties". Sollte man die nicht auch als cMetadata::Property ablegen, mit als const definierten Keys (public const string cMetadata::Property::TITLE = "Title"; sowas ...)? Dann wäre es jedenfalls ausgeschlossen, dass jemand eine zusätzliche Property "Title" einführt, die dann als etwas anderes interpretiert wird.


    Wie gesagt, nur Vorschläge -- kann sein dass die auch gar nicht gut sind, dazu kenne ich die Materie viel zu wenig :)

    Eventuell in dem Zusammenhang nicht uninteressant: https://en.wikipedia.org/wiki/Nested_set_model


    Da muss ich jetzt einfach mal sagen: Das ist cool :tup
    Hoffe ich erinnere mich dran wenn ich wieder in die Verlegenheit komme, Bäume in ein RDBMS "pressen" zu müssen. Könnte man ja sogar mit etwas Redundanz noch verbessern: Zusätzlich Tiefe UND parent-child Relationen speichern, dann kann man für jeden Query-Typ das effizienteste wählen :)

    Okay, um das zusammen zu fassen: SQLite ist und bleibt die beste Wahl.


    Da bin ich mir zwar nicht sicher, vermute es aber stark -- einfach weil ich jetzt kein so leichtgewichtiges DBMS mit hierarchischem Datenmodell kenne. Eventuell wäre aber auch BDB was, wenn du den Vorschlag hier aufgreifst, auf die Hierarchie direkt zu verzichten (weiß nicht, ob das für dich praktikabel ist)


    Der Check auf die ParentID wird nur noch im Source-Code gemacht. Wenn ein Nutzer in der DB rumpfuscht und seine Integrität gefährdet, ist er selbst schuld.


    Bei DBMS-Servern kann man das so oder so sehen -- ich bevorzuge auch da den Ansatz, dass eine Komponente die "Datenhoheit" hat. Bei einem embeddable DBMS wie SQLite würde ich das aber auf JEDEN Fall so sehen :)


    Zitat

    DLNA ist - wie ich schon häufig erwähnt habe - nicht so kompliziert, wenn man den Standard hat. Okay, es gibt jede Menge seltsame Sachen, aber in der Regel ist es kein Hexenwerk.


    Viel Erfolg!

    Diese Daten sollen irgendwo zentral gecacht werden, um nicht bei jedem Zugriff, erneut die ganzen Daten abzufragen. Die Felder ObjectID und ParentID sollen dabei die Baumstruktur abbilden.


    Wenn ich jetzt alle Objekte des Ordners mit ID XY haben möchte, dann mach ich ein SELECT * FROM objects WHERE parentID = XY. Ich kann immer nur einen Container abfragen und ich traversiere auch niemals über die einzelnen Container hinweg.


    Ok, also auch wenn ich es schade finde, für solche Dinge immer wieder die konzeptionell eigentlich unpassenden relationalen Datenbanken heranzuziehen -- denke mit DEN Anforderungen kommst du mit SQLite WIRKLICH am schnellsten hin. Ich fand es nur keine so besonders gute Idee, mich ausgerechnet bei SQLite auf constraints checking verlassen zu wollen :)


    Was aber Performance angeht, die wird für den hier geschilderten Anwendungsfall sicher sehr gut -- besonders mit einem Index auf "parentID".


    Habe auch einen kurzen Blick auf XQilla geworfen und mir scheint, dass es sich hier AUSSCHLIESSLICH um eine XQuery/XPath Implementierung handelt -- ohne Persistenz-Komponente. Die wirst du aber wohl kaum selbst schreiben wollen, und "einfach" XML-Textfiles zu nehmen wäre vermutlich für deinen Anwendungsfall nicht performant genug.

    Aber wie sieht es dort mit CRUD aus? Wie bekommt man das performant hin und welche Bibliotheken sind hier notwendig?


    Also ich habe selbst keine Erfahrung im Einsatz von XML-basierten Datenbanken -- aber viele bieten z.B. ein REST API, das deckt ja CRUD (etwas anders, als man es gewohnt ist) ab:
    GET -> read
    POST -> beliebige Operation
    PUT -> create / update
    DELETE -> delete


    Ansonsten gibt es Standards wie XPath / XQuery ... Oder auch DOM-basierte APIs (document.createElement() et al).


    Wenn das Backend ein DOM direkt speichern kann (was ja hierarchisch wäre) würde ich mal vermuten, dass das für den Anwendungsfall, hierarchische Daten zu speichern, performant ist :)


    ---
    edit: Trotzdem würde ich glaube ich aus rein pragmatischen Gründen bei dem "einfachen Tool" SQLite bleiben und eben einfach die nötigen Constraints selbst implementieren -- ODER sicherstellen, dass die verwendete SQLite-Version foreign keys UND trigger unterstützt, z.B. statisch linken.

    Zu der Baum-Struktur: Auch richtig, das nicht in die DB zu pressen. Wenn jemand eine einfachere aber trotzdem leichtgewichtige Lösung kennt, wie ich über Query-Statements alá SQL Metadaten speichern und lesen kann, dann immer her damit. Das Dateisystem ist als Speicherort leider nicht geeignet, da ich die Metadaten dort wieder in Dateien speichern müsste, was auch nicht performant ist.


    Deshalb hatte ich ja gemeint -- in SQLite speichern wäre schon auch mein Ansatz, eben weil es leichtgewichtig und effizient ist. Ich würde nur hier auf Constraints verzichten und lieber eine Schicht dazwischen einziehen, die zwischen Objekten im Speicher und SQLite "mappt" und dafür sorgt, dass der Baum intakt ist. Das ist zwar nicht unbedingt performanter (verschiedene Quellen schlagen vor, Logik IN die Datenbank zu bringen für mehr Performance, das hängt aber davon ab, wie du SQLite ansprichst -- "native" mit C/C++ sollte das irrelevant sein) -- aber sicherer! Ansonsten könnte deine Software einmal versehentlich mit einer SQLite lib laufen, die MIT foreign keys, aber OHNE trigger compiliert ist -- Effekt: Die Constraints werden akzeptiert, aber nie wirklich überprüft.


    Es gibt wahrscheinlich auch diverse NoSQL Möglichkeiten, die z.B. direkt einen Objektgraphen speichern können. Ob man da aber was leichtgewichtiges findet, was sich einfach dazulinken lässt -- fängt ja schon mit der verwendeten Programmiersprache an, zu der es passen muss.

    Wenn du dir das hier anschaust verstehst du vielleicht, warum ich vorgeschlagen habe, es lieber zu lassen:


    http://www.sqlite.org/foreignkeys.html


    Selbst in einem großen DBMS würde ich nicht versuchen, eine Baumstruktur durch Constraints zu erzwingen, einfach weil es in meinen Augen eh ein Kompromiss ist, einen Baum in Tabellen zu speichern. Bei SQLite sind Constraints -- zumindest so wie ich die Dokumentation lese -- ein etwas stiefmütterliches "der-Vollständigkeit-halber-Feature"; ausgelegt ist SQLite darauf, schnell, einfach und effizient Daten zu speichern und dabei "irgendwie" zu SQL kompatibel zu sein.


    That said, was du willst MÜSSTE (ohne es jetzt zu testen) ungefähr so funktionieren:


    CHECK ((objectID=0 AND parentID=-1) OR EXISTS(SELECT 1 FROM object o WHERE o.objectID = parentID))


    Ob SQLite das korrekt auswerten kann weiß ich aber nun wirklich nicht...

    Und wieder Bäume in "flachen" Tabellen -- also wenn du es "richtig" (semantisch) machen willst, suche dir ein freies DBMS, das entweder objektorientiert oder hierarchisch arbeitet -- NICHT relational. Sowas soll es geben ;) Weiß aber gerade keines, gerade bei objektorientierten DBMS hängt es ja auch sehr von der verwendeten Programmiersprache ab.


    Andererseits ist SQLite ganz sicher der "pragmatische" Ansatz, man kann einfach und effizient Daten speichern. Keine Ahnung, ob das, was du hier vorhast, mit SQLite /überhaupt/ machbar ist, aber ich sag mal folgendes: Du machst in deinem CREATE TABLE allerdings eh schon Zugeständnisse an SQLite, indem du auf Datentypen verzichtest. Wieso dann Constraints? Ich denke dafür ist SQLite nicht gebaut worden. Ich würde zu "Dokumentationszwecken" einen foreign key setzen, für parentID NULL erlauben und in der Software sicherstellen, dass es nur einen einzigen Eintrag mit NULL in parentID gibt.

    Oder hast du die selben Geräte?


    Würde sagen ja:


    Die Frage ist: was hast du für eine Fernbedienung? wenn ich deine Ausgabe von irrecord richtig lese vermutet lirc eine RC-6? Die sollte dann allerdings eigentlich auch ganz ohne lirc funktionieren...

    Ich musste auch meinem Asrock Board 3 verschiedene BIOS-Versionen ausprobieren bis ich eine gefunden habe, mit der CIR funktioniert hat -- ziemlich buggy, was die da liefern. Letztendlich funktioniert hat übrigens NICHT die neueste, sondern die zweitneueste.

    BTW: Unter Windows scheren sich die meisten Entwickler (gerade die "professionellen" die richtig Geld für ihre Software verlangen) nen Dreck um sowas, was dabei rauskommt sieht man als Anwender der nix davon hält gewohnheitsmässig als root zu arbeiten. Ständig Fehlfunktionen weil Programme Dateien in Bereiche schreiben wollen auf denen User keinen Schreibzugriff haben.


    Als Entwickler (und zwar bezahlterweise auf Windows, .NET) muss ich da doch mal einen Halb-OT Kommentar einschieben: Die Situation bessert sich hier glücklicherweise. Man findet weniger Software, die sämtliche Konfiguration in ihr Programmverzeichnis schmeißt. Oder die neue Root-Level Verzeichnisse "erfindet". Das sind zum Glück nur noch Altlasten, heutzutage wissen wohl die meisten Entwickler gut, was zum Beispiel unbedingt nach %USERPROFILE% gehört. Man kämpft inzwischen mit subtilerem -- wieso schreiben die Mozilla-Produkte sämtliche Caches und Datenbanken in den Roaming-Teil des Profils? Ich könnte mich viel besser damit arrangieren, sowas wie die Browser-History nicht zwischen verschiedenen Workstations zu teilen, als auf jeden Domain-Logon/off per WLAN ne halbe Ewigkeit warten zu müssen, weil der ganze Kram synchronisiert wird.


    That said, mein erster Gedanke bei "alles schön einfach in EIN Verzeichnis" war in der Tat auch: Das ist irgendwie Windows (9x) Denke :)

    Das hat jetzt nicht direkt etwas mit VDR zu tun, aber ich habe schon gemerkt, dass hier die Leute mit Ahnung/Erfahrung zu RC-Core und LIRC unterwegs sind, daher versuche ich es mal:


    Wie schon erwähnt habe ich ja einen Desktop-PC als VDR (und gleichzeitig DVD/BD- und Musik-Player) und würde daher gern mehr fernsteuern als "nur" den VDR. Habe jetzt schon VDR selbst von lirc "getrennt" (/dev/null) und leite dafür lirc-events über vdr-sxfe weiter. Ein erster Erfolg, VDR lässt sich nur noch fernbedienen, wenn das frontend auch offen ist, ich ihn also tatsächlich nutze. Jetzt habe ich mir aber auch Konfigurationen für verschiedene andere Programme gemacht (mplayer, xine, amarok), die alle die ~/.lircrc verwenden. Schön und gut, aber wenn mal zwei der Programme gleichzeitig offen sind, reagieren natürlich beide.


    lircrc Modes wären wahrscheinlich eine Lösung, aber erstens finde ich das umständlich (muss an der FB etwas drücken um umzuschalten) und zweitens unterstützt der VDR das ja eh nicht von Haus aus. Was ich perfekt fände wäre eine Möglichkeit, quasi eine Prioritätenliste der LIRC clients anzulegen: Wenn VDR läuft bekommt der die Events, ansonsten xine, ansonsten amarok ... so in der Art. Jemand eine Idee, ob sich sowas eventuell per scripting lösen lässt?