Output jpeg-frames on DC10+

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]



Hi!

I asked about this a few days ago, and got some help from Ronald Bultje who said I needed to do the following:

"To show the image, just open the device, setup the zoran parameters
(v4l1: MJPIOC_S_PARAMS, v4l2: VIDIOC_S_JPEGCOMP and VIDIOC_S_FMT),
request buffers (v4l1: MJPIOC_REQBUFS, v4l2: VIDIOC_REQBUFS), mmap the
buffers, write your data into the buffer, then queue the buffer, start
playback, sync on the buffer and stop playback (v4l1:
MJPIOC_QBUF_PLAY/autodone/MJPIOC_SYNC/MJPIOC_QBUF_PLAY(framenum=-1),
v4l2: VIDIOC_QBUF/VIDIOC_STREAMON/VIDIOC_DQBUF/VIDIOC_STREAMOFF), then
close the device. That's all."

"However, you need to make sure that:
A) the JPEG image has Huffman/Quantization tables (I think the zoran
chipset requires that)
B) the internal encoding of the JPEG image must be YUY2. RGB24/32 can't
be read by the zoran chipset.
C) if the imageheight  is larger than the max. field height (240 for
NTSC, 288 for PAL), then the image must be interlaced (i.e., two
seperately-encoded JPEG fields sequentially). The zoran chipset can't
read JPEG fields larger than that."

Sounded fairly easy :) so I started, and have made some progress, but now I'm stuck. My TV-screen just flickers and rolls, and only shows black background, and some noise now and then. Here is the code I execute:

void PS_VideoDriver::openDevice() {
	struct mjpeg_params bp;
	struct video_mbuf vm;

	// Open the video device
	vid_fd = open(device.c_str(), O_RDWR);    //device = "/dev/video"
	if(vid_fd == -1){
		cout << "***Could not open video device " << device << endl << "::" << strerror(errno) << endl;
	}

	//Settings
	//Get params
	ioctl(vid_fd, MJPIOC_G_PARAMS, &bp);
	
	//Store params
	bp.norm = 0; //PAL
	bp.quality = 100;
    	bp.field_per_buff = 1;
   	bp.img_width = 352;
	bp.img_height = 240;
	if (ioctl(vid_fd, MJPIOC_S_PARAMS, &bp) < 0) {
		cout << "***Error setting video parameters" << endl << "::" << strerror(errno) << endl;
    	}

	/* REQBUFS */
	if(ioctl(vid_fd, MJPIOC_REQBUFS, &vm)<0) {
		cout << "***Error requesting buffers" << endl << "::" << strerror(errno) << endl;
	}
	
	/* mmap */
	vm.frames = 5;
	vm.size = 352*240*3*5; 
	if((buff=mmap(0, vm.size, PROT_READ|PROT_WRITE, MAP_SHARED, vid_fd, 0))==(char *)-1) {
		cout << "***Error mapping the video buffer" << endl << "::" << strerror(errno) << endl;
	}

	buffSize = vm.size;
}



void PS_VideoDriver::update() {
	/* fread example: read a complete file */
	FILE * pFile;
	long lSize;
	cout << "PS_VideoDriver::update(), Opening file..." << endl;
	string s = "sample.jpg";
	pFile = fopen (s.c_str(),"rb");
	if (pFile==NULL) exit (1);
	cout << "PS_VideoDriver::update(), File opened." << endl;

	// obtain file size.
	fseek (pFile , 0 , SEEK_END);
	lSize = ftell (pFile);
	rewind (pFile);

	// copy the file into the buffer.
	cout << "PS_VideoDriver::update(), Buffering file...(" << lSize << " bytes > " << buff << ")" << endl;
	fread (buff,1,lSize,pFile);
	cout << "PS_VideoDriver::update(), File buffered." << endl;
	rewind (pFile);


	/*** the whole file is loaded in the buffer. ***/

	// terminate
	fclose (pFile);

	struct mjpeg_sync bs;

	int frameNbr=0;
	//Queue the buffer
	if (ioctl(vid_fd, MJPIOC_QBUF_PLAY, &frameNbr) < 0) {
		cout << "***Error playing the video buffer" << endl << "::" << strerror(errno) << endl;
    	}

	bs.frame = 0;
	bs.seq = 0;
	//Sync on buffer
	if (ioctl(vid_fd, MJPIOC_SYNC, &bs) < 0) {
		cout << "***Error syncing on buffer" << endl << "::" << strerror(errno) << endl;
	}

/**
	frameNbr=-1;
	//Play the buffer
	if (ioctl(vid_fd, MJPIOC_QBUF_PLAY, &frameNbr) < 0) {
		cout << "***Error stopping the buffer" << endl << "::" << strerror(errno) << endl;
	}
*/
}

I've tried (quite) a few different settings on the buffer size and different jpeg-images. (sample.jpg in this version is a 352x240 image from www.linuxmedialabs.com (Sample JPEG image captured at 350x240 resolution) I thought that this image hopefully has the same format as the dc10+ desires.)

(The code is inspired of lavplay, www.cplusplus.com c reference, and some other open source projects)

any help appreciated!
sincerely
Markus Nilsson (Student at Lund Institute of Technology)





[Index of Archives]     [Linux DVB]     [Video Disk Recorder]     [Asterisk]     [Photo]     [DCCP]     [Netdev]     [Xorg]     [Util Linux NG]     [Xfree86]     [Free Photo Albums]     [Fedora Users]     [Fedora Women]     [ALSA Users]     [ALSA Devel]     [Linux USB]

Powered by Linux