June 13, 2011

qttrekker qttrekker
Lab Rat
16 posts

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?

  1. QFile dvd("/dev/dvd");
  2. dvd.open(QIODevice::ReadOnly);
  3. QDataStream dstream(&dvd);
  4. while (!dstream.atEnd()) {
  5.   bytesRead = dstream.readRawData(buffer, max);
  6. }

4 replies

June 13, 2011

Lukas Geyer Lukas Geyer
Lab Rat
2068 posts

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 [cdrecord.berlios.de] and/or the dvd+rw tools [fy.chalmers.se] or, as many other applications do, just rely on them.

June 13, 2011

qttrekker qttrekker
Lab Rat
16 posts

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 //0×0100
IO_Async

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

  1. / *
  2.   * Qt thinks if a file is not S_IFREG, you cannot seek in it. It's false (what about
  3.  * block devices for example?
  4.  */
  5.  
  6. #ifdef __linux__
  7.    m |= IO_Async; //On linux, set O_NONBLOCK, opens CD-ROMs faster
  8. #endif
  9.    ret=QFile::open(m);
  10.    if (ret && isSequentialAccess() ) {
  11.        setType(IO_Direct);
  12.    }
  13.    return ret;

June 13, 2011

qttrekker qttrekker
Lab Rat
16 posts

After running a few additional tests it turns out that I can open and read from the disc successfully with QFile.

  1. QFile dvd("/dev/dvd");
  2. dvd.open(QIODevice::ReadOnly);
  3. 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

June 14, 2011

zester zester
Lab Rat
81 posts

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.

 
  ‹‹ Constrains of LGPL of Qt      Windows 8 Support ››

You must log in to post a reply. Not a member yet? Register here!