I am still having problems with getting mmap to work in a system with a BT848 card. The current system works fine on my development system with a USB Webcam that only supports read(), but on my test system with a BT848 Capture card that only supports mmap, I'm having problems. My main problem is that the mmap doesn't seem to be working, it prints out the output line, but the screen remains black no matter what combination of resolutions and video sources I use. I've used XawTV to get an image from the camera, so I know it works so I assume that the problem is in my code somehwere, possibly with using the wrong buffers. I hope someone can help me, thanks in advance Incidently, it's a Redhat 7.2 running kernel 2.4.7-10, which has the default kernel version of v4l on it (not v4l2). I'm loath to modify the kernel as it might cause problems with a lot of the other custom hardware that is in this machine, but am willing to give it a try if necessary. Thanks in Advance. Michael Spall My relevant code is as follows (it's c++, so have shown the two methods of my objects that are important, needless to say I do some checks to make sure that the VIDEO_CAPS shows that we support mmap). Before this we have setup SIZE, PAL, MAXY and MAXX, MAXX and MAXY are user configurable, PAL is the pallette type, currently VIDEO_PALETTE_RGB565. SIZE = MAXY * MAXX * BYTES, where BYTES is BPP / 8, and BPP is set of this pallete to 16. dispaly is a SDL Surface, it's arranged to match the video palette as closely as possibly, RGB565 for this mode, haven't started on matching other formats :( main --> if (bttv) { cout << "BTTV cards need mmap, so try that" << endl; // BTTV cards don't handle read() functions so we mmap v.SetMmap(SIZE, PAL, MAXY, MAXX); } // this is our processing loop, hope it works! while (running) { if (SDL_PollEvent(&event)) { if (event.type==SDL_KEYDOWN) running = false; }; // This should now have a buffer from my webcam, scary huh? // I need to dispaly this somehow, I hate this stuff // guess it's off ot SDL for a quick and dirty window // to blit onto. SDL_LockSurface(display); v.GetImage(display->pixels, SIZE); SDL_UnlockSurface(display); SDL_Flip(display); // End of processing Loop } <-- Set Mmap is supposed to deal with initialising the mmap structures, and so on, This was based on the code that Gontran Fournier very kindly sent me --> struct video_mbuff memBuffer ioctl( fd, VIDIOCGMBUF, memBuffer ) char *memAdrs memAdrs = (char*)mmap( 0, memBuffer.size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0 ); // Update the video_mmap structure array for each frame and start the capture //====================================================================== struct video_mmap mappedFrames[memBuffer.frames] int i; for( i = 0; i < memBuffer.frames; i++ ) { mappedFrames[i].frame = i; mappedFrames[i].width = width; mappedFrames[i].height = height; mappedFrames[i].format = palette; } // Set first frame to be grabbed (keep a variable containing the next frame to be grabbed) //================================================================ frameNo = 0; // This is the frame you will SYNC on if( ioctl( fd, VIDIOCMCAPTURE, &(mappedFrames[frameNo]) ) == -1 ) { perror( "ioctl( VIDIOCMCAPTURE )" ); return -1; } <-- and here is my take on it. --> void Video::SetMmap(size_t buffer_size, unsigned int format, int h, int w) { if (m_valid) { if (GetCaps()->Supports(VID_TYPE_CAPTURE)) { if (ioctl(mp_device->Descriptor(),VIDIOCGMBUF, mp_vmb) == 0) { mp_buffer = mmap(0, mp_vmb->size, PROT_READ | PROT_WRITE, MAP_SHARED, mp_device->Descriptor(), 0); if (mp_buffer != MAP_FAILED) { for (int i = 0; i < mp_vmb->frames; i++) { m_vmm[i].frame = i; m_vmm[i].height = h; m_vmm[i].width = w; m_vmm[i].format = format; } if (ioctl(mp_device->Descriptor(),VIDIOCMCAPTURE, &(m_vmm[0])) == 0) { m_mmap = true; cout << "Setup mmap OK" << endl; } else { cout << "could not start capture with mmap" << endl; } } else { cout << "mmap returned invalid memory location" << endl; } } else { cout << "Could not get mbuf structure filled" << endl; } } else { cout << "Device does not support mmap capture" << endl; } } } <-- Finally my read function, this is supposed ot be a dual usable function, if the member m_mmap is false then we just do read(), if it is set then we do mmap to transfer the data. Currently I am only interested in getting some frame data, I don't want to buffer multiple frames or anything, os we only ever request frame 0. There is currenlty an output statement in the read function, that is there for debugging, it showed me that the read() was blocking but would never complete on a bttv system. --> void Video::GetImage(void * buffer, size_t buffer_size) { if (m_valid) { if (m_mmap) { // Use mmap to get screen cout << "Using mmap Read" << endl; // Tell MMAP to sync the device and get a full frame into mp_buffer ioctl(mp_device->Descriptor(),VIDIOCSYNC,0); // Copy from buffer to external buffer memcpy(mp_buffer,buffer,buffer_size); // Now tell it to start getting the next frame, cos we have got the full frame ioctl(mp_device->Descriptor(),VIDIOCMCAPTURE,&(m_vmm[0])); } else { // Standard Read cout << "Using Standard Read" << endl; read(mp_device->Descriptor(),buffer, buffer_size); } } } <-- --- Mib