How to read from sequential device like /dev/dvd



  • Is it possible to directly access and read from /dev/dvd using qt? I've tried creating a QFile and opening it as read only. The isSequential() method returns true but I have no idea how to read data from the device. After reading through the documentation for QFile and QIODevice it seems that most methods like size() and seek() cannot be used for sequential devices. I'm also unable to retrieve the total size of the disc. The bytesAvailable() method returns 0. How can I modify the code below to read from a cdrom drive and how can I determine the total size in bytes?

    @
    QFile dvd("/dev/dvd");
    dvd.open(QIODevice::ReadOnly);
    QDataStream dstream(&dvd);
    while (!dstream.atEnd()) {
    bytesRead = dstream.readRawData(buffer, max);
    }
    @



  • Well, the question is - what do you want to accomplish?

    • If you need to access files stored on a DVD you have to mount it first.
    • If you need to access raw data stored on the disc (including its metadata like disc capacity, sessions and sessions sizes) it is more complicated then just retrieving the stream size.
      You should probably take a look at the sources of the "cdrtools":http://cdrecord.berlios.de/private/cdrecord.html and/or the "dvd+rw tools":http://fy.chalmers.se/~appro/linux/DVD+RW/ or, as many other applications do, just rely on them.


  • My goal was to read from a cd/dvd directly without mounting it similar to the dd command below.

    dd if=/dev/dvd iflag=direct

    I've looked through the source of kio_iso that was developed with a much earlier version of qt and it is able to directly access data from /dev/dvd using QFile. It uses a couple of flags that were apparently removed in qt4.

    IO_Direct //0x0100
    IO_Async

    The code below was taken from kio_iso. Is there any way to accomplish this in qt4?

    @
    / *

    • Qt thinks if a file is not S_IFREG, you cannot seek in it. It's false (what about
    • block devices for example?
      */

    #ifdef linux
    m |= IO_Async; //On linux, set O_NONBLOCK, opens CD-ROMs faster
    #endif
    ret=QFile::open(m);
    if (ret && isSequentialAccess() ) {
    setType(IO_Direct);
    }
    return ret;
    @



  • After running a few additional tests it turns out that I can open and read from the disc successfully with QFile.
    @
    QFile dvd("/dev/dvd");
    dvd.open(QIODevice::ReadOnly);
    bytesRead = dvd.read(buffer, max);
    @
    Apparently the reason it didn't appear to be reading the disc was the while loop. Since seek(), pos(), atEnd() and peek() cannot be used for a sequential device I'm only able to read data from the disc into a buffer one time. I can increase the buffer size but unless I set a 700 mb buffer it's not going to help much because I'm still only going to be able to read one time. I can keep track of the total bytes read and I can detect the end of the disc but how can I start reading at a certain position on the disc? I need to be able to specify something like "read(startPosition, buffer, max)" but as far as I know there isn't any way to accomplish that in qt. Any suggestions how I can code the while loop?

    I also discovered that dvd.seek(32000) returns true even though it's a sequential device. According to the docs seek is supposed to return false for sequential devices.

    http://doc.trolltech.com/4.7/qiodevice.html#seek



  • I'm not sure what platform your on but http://libburnia-project.org/ might be more appropriate for what your trying to do.

    Libburnia is an open-source library for reading, mastering and writing optical discs. For now this means CD-R, CD-RW, DVD-RAM, DVD+RW, DVD+R, DVD+R/DL, DVD-RW, DVD-R, BD-RE.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.