Media Detection

Andrew Milton akm at theinternet.com.au
Mon Apr 12 21:29:11 PDT 2004


+-------[ Tim Aslat ]----------------------
| Hi All,
| 
| Just trying to set up a PVR type device and would like to throw in a
| feature to detect what media (if any) is inserted into the DVD burner.

[snip]

| How would I go about checking the media if it's a blank, non-blank or RW
| disk?
| 
| C or C++ code would be great.


I don't have a DVD burner, but, the following chunk of code serves me fairly
well for my atapi DVD and CD drives. SCSI drives have a different API to ATA
ones, so this may not work for SCSI or ATAPICAM devices. There's some debug in
there that could go, but, it might help you so I left it in. It compiles under
-current.

It's also based on empircal loading of different media types I have lying
around, so YMMV w.r.t to detection d8)

returns 0 for NO DISK
returns 1 for Audio or Audio + Copy Protection/Data.
returns 2 for Data
returns 3 for Unknown (something is loaded, but, we don't know what).

------------------------------------------------------------------------
#include <unistd.h>
#include <ctype.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/cdio.h>
#include <sys/stat.h>

#define CD_TYPE_AUDIO 100
#define CD_TYPE_MIXED 105
#define CD_STATUS_OK 4
#define CD_STATUS_NO_DISC 1

int CD_getTOCHeader(int fd, struct ioc_toc_header *ith)
{
        if(ioctl(fd, CDIOREADTOCHEADER, ith) < 0)
        {
                perror("Read TOC");
                return(0);
        }
        return(1);
}

int CD_Status(int fd)
{
        struct ioc_read_toc_entry irte;
        struct cd_toc_entry *tocP;
        struct ioc_toc_header ith;
        u_int control;
        u_char track;
        int status = 0, i;

        status = CD_STATUS_NO_DISC;

        if(CD_getTOCHeader(fd, &ith) < 0)
        {
                perror("read toc header");
                return(0);
        }
        printf("Start: %d\n", ith.starting_track);
        printf("End: %d\n", ith.ending_track);
        printf("Length %d\n", ith.len);
        
        memset(&irte, 0, sizeof(struct ioc_read_toc_entry));
        irte.data = (struct cd_toc_entry *)malloc(ith.len * sizeof(struct cd_toc_entry));
        irte.data_len = ith.len * sizeof(struct cd_toc_entry);;
        irte.address_format = CD_LBA_FORMAT;
        irte.starting_track = 0;
        if(ioctl(fd, CDIOREADTOCENTRYS, &irte) < 0)
        {
                free(irte.data);
                perror("read toc");
                return(0);
        }
        for(i = 0; i <irte.data_len; ++i)
        {
                tocP = &(irte.data[i]);
                control = tocP->control;
                track = tocP->track;
                if(track == 0)
                {
                        break;
                }
                if(control == 0 && status != CD_TYPE_MIXED)
                {
                        status = CD_TYPE_AUDIO;
                }
                else if(control != 0)
                {
                        if(status == CD_TYPE_AUDIO)
                        {
                                status = CD_TYPE_MIXED;
                        }
                        else
                        {
                                status = 100 + control;
                        }
                }
                else if(control == 5)
                {
                        status = CD_TYPE_MIXED;
                        
                }
        }
        free(irte.data);
        if(status == CD_TYPE_AUDIO || status == CD_TYPE_MIXED)
        {
                return(1);
        }
        status == lseek(fd, 0x8000, SEEK_SET);
        if(status < 0)
        {
                perror("lseek");
                return(3);
        }
        return(2);
}

-- 
Totally Holistic Enterprises Internet|                      | Andrew Milton
The Internet (Aust) Pty Ltd          |  M:+61 416 022 411   |
ACN: 082 081 472 ABN: 83 082 081 472 |akm at theinternet.com.au| Carpe Daemon


More information about the freebsd-multimedia mailing list