From: Stefan Ringel <stefan.ringel@arcor.de>
To: Mauro Carvalho Chehab <mchehab@redhat.com>
Cc: Linux Media Mailing List <linux-media@vger.kernel.org>
Subject: Re: tm6000 calculating urb buffer
Date: Tue, 04 May 2010 21:13:06 +0200 [thread overview]
Message-ID: <4BE071C2.4050309@arcor.de> (raw)
In-Reply-To: <4BE066B7.2050704@redhat.com>
-----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-----
next prev parent reply other threads:[~2010-05-04 19:13 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <4BDB067E.4070501@arcor.de>
[not found] ` <4BDB3017.9070101@arcor.de>
2010-05-04 15:38 ` tm6000 calculating urb buffer Stefan Ringel
2010-05-04 18:25 ` Mauro Carvalho Chehab
2010-05-04 19:13 ` Stefan Ringel [this message]
2010-05-04 19:50 ` Mauro Carvalho Chehab
2010-05-04 19:58 ` Stefan Ringel
2010-05-05 6:07 ` Mauro Carvalho Chehab
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4BE071C2.4050309@arcor.de \
--to=stefan.ringel@arcor.de \
--cc=linux-media@vger.kernel.org \
--cc=mchehab@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox