Re: tm6000 calculating urb buffer

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

 



-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
 
Am 04.05.2010 20:25, schrieb Mauro Carvalho Chehab:
> Hi Stefan,
>
> Stefan Ringel wrote:
>> Am 30.04.2010 21:31, schrieb Stefan Ringel:
>>> Am 30.04.2010 18:34, schrieb Stefan Ringel:
>>>  
>>>> Hi Mauro,
>>>>
>>>> Today I'm writing directly to you, because it doesn't work the mailing
>>>> list. I thought over the calculating urb buffer and I have follow idea:
>>>>
>>>> buffer = endpoint fifo size (3072 Bytes) * block size (184 Bytes)
>>>>
>>>> The actually calculating is a video frame size (image = width * hight *
>>>> 2 Bytes/Pixel), so that this buffer has to begin and to end an
>>>> uncomplete block. followed blocks are setting the logic to an err_mgs
>>>> block, so that going to lost frames.
>>>>
>>>>  
>>>>    
>>> I forgot a log with old calculating.
>>>
>>>  
>>
>>
>>
>> datagram from urb to videobuf
>>
>> urb           copy to     temp         copy to         1. videobuf
>>                          buffer                        2. audiobuf
>>                                                        3. vbi
>> 184 Packets   ------->   184 * 3072    ---------->     4. etc.
>> a 3072 bytes               bytes
>>                184 *                   3072 *
>>              3072 bytes              180 bytes
>>                                 (184 bytes - 4 bytes
>>                                     header )
>
> In order to receive 184 packets with 3072 bytes each, the USB code will
> try to allocate the next power-of-two memory block capable of receiving
> such data block. As: 184 * 3072 = 565248, the kernel allocator will seek
> for a continuous block of 1 MB, that can do DMA transfers (required by
> ehci driver). On a typical machine, due to memory fragmentation,
> in general, there aren't many of such blocks. So, this will increase the
> probability of not having any such large block available, causing an
horrible
> dump at kernel, plus a -ENOMEM on the driver, generally requiring a reboot
> if you want to run the driver again.
>
And direct copy from urb to videobuf/alsa/vbi in 184 Bytes segments.

urb                      1. videobuf
              copy to    2. audiobuf
                         3. vbi
184 Packets   ------->   4. etc.
a 3072 bytes   
              180 Bytes (without headers)


or how can I copy 180 Bytes Data from 184 Bytes block with an
anligment of 184 urb pipe (184 * 3072 Bytes)?


>>                                    
>>
>> step 1
>>
>> copy from urb to temp buffer
>
> Why do you want to do triple buffering? This is a very bad idea.
> If you do it at the wrong way, by handling the copy at interrupt time,
> you're eating more power (and batteries, on notebooks), and reducing
> the machine speed. If you split it into two halves, you'll need a larger
> buffer area, since kernel will eventually join a few consecutive
workqueue tasks
> into one, to avoid damaging other kernel process. Also, it will risk
loosing
> frames or introduce a high delay.
>
> It is already bad enough to have a double buffering with those usb
devices.
> Just as an example, the last time I've measured em28xx driver performance,
> after doing lots of optimization at the code, it were still consuming
> about 30% of CPU time of the machine I used for test (a typical
> mono-core Intel CPU).
>
> I know that the code would be simpler if we use a temporary buffer,
> but this way, we save CPU time. Also, if we do triple buffering, you'll
> likely add some delay when syncing between audio and video, due to
> the workqueue time.
>
> So, in summary, what we need to do is to validate the code and simplify
> it to be faster. If you take a look at tm6000-video.c, you'll see that I've
> tried already some different approaches. The one that is currently working
> is the first approach I did. As the newer solutions didn't solve the loss
> of data, but introduced newer bugs, I did a rollback to the code. At
the time
> I stopped working on tm6000, I was about to write a new (simpler) approach,
> but still avoiding the double buffering.
>
>>
>> snip
>> ----
>> for (i = 0; i < urb->number_of_packets; i++) {
>>     int status = urb->iso_frame_desc[i].status;
>>    
>>     if (status<0) {
>>         print_err_status (dev,i,status);
>>         continue;
>>     }
>>
>>     len=urb->iso_frame_desc[i].actual_length;
>>
>>     memcpy (t_buf[i*len], urb->transfer_buffer[i*len], len);
>>     copied += len;
>>     if (copied >= size || !buf)
>>         break;
>>
>> }
>>
>> if (!urb->iso_frame_desc[i].status) {
>>     if ((buf->fmt->fourcc)==V4L2_PIX_FMT_TM6000) {
>>         rc=copy_multiplexed(t_buf, outp, len, urb, &buf);
>
> copy_multiplexed() is about what you want: It just copies everything
> (except for the URB headers), into a buffer, allowing decoding the
> data on userspace. There's an userspace application that gets those
> data, at v4l-utils tree. With this approach, you may add a decoder
> at libv4l for TM6000 format, and let userspace to do the audio/video/TS
> decoding.
>
>>         if (rc<=0)
>>             return rc;
>>     } else {
>>         copy_streams(t_buf, outp, len, urb, &buf);
>>     }
>> }
>> ---
>> snip
>>
>> step 2
>>
>> copy from temp buffer into videobuffer
>>
>> snip
>> ---
>>
>> for (i=0;i<3072;i++) {
>
> Doesn't work: nothing warrants that the device will start with a frame.
>
>>     switch(cmd) {
>>         case TM6000_URB_MSG_VIDEO:
>>             /* Fills video buffer */
>>             memcpy(&out_p[(line << 1 + field) * block * 180],
>>                 ptr[(i*184)+4], 180);
>>             printk (KERN_INFO "cmd=%s, size=%d\n",
>>             tm6000_msg_type[cmd],size);
>>             break;
>>         case TM6000_URB_MSG_PTS:
>>             printk (KERN_INFO "cmd=%s, size=%d\n",
>>             tm6000_msg_type[cmd],size);
>>             break;
>>         case TM6000_URB_MSG_AUDIO:
>>             /* Need some code to process audio */
>>             printk ("%ld: cmd=%s, size=%d\n", jiffies,
>>             tm6000_msg_type[cmd],size);
>>             break;
>>         default:
>>             dprintk (dev, V4L2_DEBUG_ISOC, "cmd=%s, size=%d\n",
>>             printk (KERN_INFO "cmd=%s, size=%d\n",
>>             tm6000_msg_type[cmd],size);
>>         }
>>     }
>> }
>>
>> ---
>> snip
>>
>> This is a schemata to copy in videobuf.
>>
>> temp_buf = fifo size * block size
>>
>> viodeobuf = hight * wight * 2
>>
>>
>> Questions
>>
>> 1. Is it right if I copy the block without header to videobufer?
>> 2. Can I full the videobuffer have more temp_bufs?
>> 3. How are the actually data schema from urb to videobuffer?
>
>

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.12 (MingW32)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/
 
iQEcBAEBAgAGBQJL4HHCAAoJEDX/lZlmjdJlnfwIAKTVHHCMCha0GH5qJUUkJPY2
OJtHYpiJzYo8v/k4fT24vJpy/nT74i3ssrKk8sS7Y1yj+1HwPnuUBgny1hqS/O3B
2D43eiFCN1riKnDkxIlTs+tbo3wvKOBOrY1rdRgOrC6FhAvFyQ5WS3PdraYt5oaQ
5oAAI6QT3lCfyQ6LSLfuw64BAtohRZ1jNVp5rh5CBr0gWsfrQrQsset0F6w6o0O9
Gj02w6HqMJJdZBKImMhgkbgY11jN9476JsyRoh2me1Hhf18kWt30Cjyccvfydo2U
tdc5EelrAXseu8HmdBZlMgYrarWvL0AHXXH/hJfxzt7sW/d2Mw/XuSJD+BMh7rk=
=Zx8V
-----END PGP SIGNATURE-----

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Input]     [Video for Linux]     [Gstreamer Embedded]     [Mplayer Users]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]
  Powered by Linux