Hallo,
ich versuche VDR (Klaus Schmidinger's Video Disk recorder, siehe
http://www.cadsoft.de/people/kls/vdr) Wiedergabe auf einer
Nokia Sat dbox2 zum Laufen zu kriegen.
Nachdem ich ein paar einfache Probleme ("find -type" busybox
Konfiguration fuer das VDR recordings menue, big endian bug
in VDR index file input) geloest habe, gibt's jetzt ein
Problem, bei dem ich ohne Hilfe nicht weiter komme.
VDR startet die Wiedergabe und beginnt nach dem setup mit
write calls auf das DVB device.
Ausnahmlos alle write calls bekommen errno=EAGAIN und der
Bildschirm bleibt schwarz.
Ich vermute, das EAGAIN wird von der routine avia_gt_dmx_queue_write
in driver/dvb/drivers/media/dvb/avia/avia_gt_dmx.c gemeldet.
Scheinbar wird die queue nie leer?
Ich vermute, dass der setup, den VDR macht (welcher natuerlich
auf PCs unter Linux mit DVB Karte einwandfrei funktioniert)
fuer diesen Treiber nicht ausreicht.
Die entscheidenden Stellen im VDR code findet man in dvbdevice.c.
Dort geschieht initial:
* in cDvbDevice::TurnOffLiveMode
ioctl(fd_audio, AUDIO_SET_MUTE, true);
ioctl(fd_video,VIDEO_SET_BLANK);
ioctl(fd_audio,AUDIO_STOP);
ioctl(fd_video,VIDEO_STOP);
* in cDvbDevice::SetPlayMode
ioctl(fd_video, VIDEO_SET_BLANK, true);
ioctl(fd_audio, AUDIO_SELECT_SOURCE, AUDIO_SOURCE_MEMORY);
ioctl(fd_audio, AUDIO_SET_AV_SYNC, PlayMode == pmAudioVideo);
ioctl(fd_audio, AUDIO_PLAY);
ioctl(fd_video, VIDEO_SELECT_SOURCE, VIDEO_SOURCE_MEMORY);
ioctl(fd_video, VIDEO_PLAY);
Und dann beginnen die writes:
write(fd_video, Data, Length);
An der Stelle habe ich Testausschriebe eingebaut.
int cDvbDevice::PlayVideo(const uchar *Data, int Length)
{
int fd = (playMode == pmAudioOnly || playMode == pmAudioOnlyBlack) ? fd_audio : fd_video;
int ret = -1;
if (fd >= 0)
ret = write(fd, Data, Length);
dsyslog("write(%d, %x, %d)=%d, errno=%d", fd, int(Data), Length, ret, errno);
return ret;
}
Die sehen alle ausnahmslos so aus:
Feb 15 15:29:02 dbox user.debug vdr[113]: write(5, 10292eb0, 54313)=-1, errno=11
Hat jemand einen Tip fuer mich?
Fehlt oben noch ein entscheidender ioctl, um das Ganze in Schwung
zu bringen?
Danke und Gruss,
Carsten.
Avia Treiber haengt bei VDR Wiedergabe auf dbox2.
-
- Neugieriger
- Beiträge: 3
- Registriert: Samstag 14. Februar 2004, 21:20
-
- Senior Member
- Beiträge: 1282
- Registriert: Montag 12. November 2001, 00:00
Re: Avia Treiber haengt bei VDR Wiedergabe auf dbox2.
was ist "das DVB device"?cko hat geschrieben:VDR startet die Wiedergabe und beginnt nach dem setup mit
write calls auf das DVB device.
jacko hat geschrieben:Ausnahmlos alle write calls bekommen errno=EAGAIN und der
Bildschirm bleibt schwarz.
Ich vermute, das EAGAIN wird von der routine avia_gt_dmx_queue_write
in driver/dvb/drivers/media/dvb/avia/avia_gt_dmx.c gemeldet.
Scheinbar wird die queue nie leer?
die alten dvb karten mit av7110 benutzen kein standardformat sondern "avpes". vdr schreibt also eine datei bestehend aus zusammengeschmissenem audio und video pes nach video0. vdr ist nebenbei zu doof, den treiber vorher zu fragen, ob er das versteht, weil kls ja denkt, dass es nur intel und av7110 karten gibt.Ich vermute, dass der setup, den VDR macht (welcher natuerlich
auf PCs unter Linux mit DVB Karte einwandfrei funktioniert)
fuer diesen Treiber nicht ausreicht.
du hast die moeglichkeiten, TS nach dvr0 zu schreiben oder PES nach video0 und audio0 zu schreiben. was momentan passiert ist offenbar, dass du muell nach video0 schreibst, dazu av sync an hast aber nichts nach audio0 schreibst.
-
- Neugieriger
- Beiträge: 3
- Registriert: Samstag 14. Februar 2004, 21:20
Danke fuer den Tip!obi hat geschrieben: du hast die moeglichkeiten, TS nach dvr0 zu schreiben oder PES nach video0 und audio0 zu schreiben. was momentan passiert ist offenbar, dass du muell nach video0 schreibst, dazu av sync an hast aber nichts nach audio0 schreibst.
Das hat mir sehr viel weiter geholfen.
Ich habe jetzt also in vdr-1.2.6/dvbdevice.c cDvbDevice::PlayVideo
so erweitert, dass es die Pakete analysiert und Tonpakete nach fd_audio
sowie Bildpakete nach fd_video schreibt:
Code: Alles auswählen
int cDvbDevice::PlayVideo(const uchar *Data, int Length)
{
int total_bytes = 0;
for (int i = 0; i < Length - 6; i++)
if (Data[i] == 0x00 && Data[i + 1] == 0x00 && Data[i + 2] == 0x01)
{
const int packet_length = Data[i + 4] * 256 + Data[i + 5] + 6;
if (packet_length > 0)
{
const uchar packet_id = Data[i + 3];
int fd;
switch (packet_id)
{
case 0xBD: // dolby
case 0xC0 ... 0xC1: // audio
fd = fd_audio;
break;
case 0xE0 ... 0xEF: // video
fd = fd_video;
break;
default:
esyslog("ERROR: unexpected packet id %02X.", packet_id);
fd = -1;
}
if (fd != -1)
{
int bytes_written = 0;
while (bytes_written < packet_length)
{
int l = write(fd, Data + bytes_written + i, packet_length - bytes_written);
if (l > 0)
bytes_written += l;
else if (l == -1)
{
if (errno == EAGAIN)
usleep(1);
else
{
esyslog("ERROR: PlayVideo write returns %d.", errno);
return -1;
}
}
}
total_bytes += packet_length;
i += packet_length - 1; // the loop increments, too!
}
}
}
else
esyslog("ERROR: bad packet header %02X %02X %02X.", Data[i], Data[i + 1], Data[i +2]);
return total_bytes;
}
Leider nur intermittierend.
Manchmal laufen Bild und Ton perfekt, manchmal nur das Bild ohne Ton und manchmal guter Ton mit ruckelndem Bild. Ein System konnte ich nicht erkennen. Selbst, wenn ich in aufeinanderfolgenden Tests direkt nach dem
booten die Wiedergabe gestartet habe, lief es mal perfekt, meist jedoch mit perfektem Video ohne Audio.
Hast Du noch nen Tip?
Danke und Gruss.
Carsten.
-
- Senior Member
- Beiträge: 1282
- Registriert: Montag 12. November 2001, 00:00
Code: Alles auswählen
const int packet_length = Data[i + 4] * 256 + Data[i + 5] + 6;
if (packet_length > 0)
spontan faellt mir eigentlich nur auf, dass video pakete keine gueltige laengenangabe enthalten muessen. stattdessen ist laenge==0 erlaubt, was so viel heisst wie "hoert da auf wo das naechste anfaengt".
dann koennte noch passieren, dass z.b. die video queue voll ist und du dich eine weile mit EAGAIN beschaeftigst, ohne daten in die audio queue schreiben zu koennen. so kommts vielleicht im audio decoder zum buffer underrun. der avia wird dann evtl. sync ausschalten oder ins stottern kommen oder was auch immer
da waere es vielleicht sinnvoll, audio und video schon vorher in getrennten dateien zu haben, am besten neu verpackt, so dass immer gueltige laengenangaben auch beim video header vorhanden sind.
noch besser waere, die daten als TS zu schreiben, was enigma und neutrino auch machen. das kann vdr wohl (noch?) nicht.