* Chromium acceleration @ 2014-03-19 20:49 Eric Nelson 2014-03-19 21:00 ` Carlos Rafael Giani 2014-03-20 12:47 ` Lauren Post 0 siblings, 2 replies; 37+ messages in thread From: Eric Nelson @ 2014-03-19 20:49 UTC (permalink / raw) To: Post Lauren-RAA013, meta-freescale Hi Lauren, A while back, you mentioned that 3.10.17-ga would help provide support for "Chromium acceleration" but didn't provide details. Did you mean WebGL support (i.e. GPU acceleration), or video acceleration (VPU support)? My understanding is that Chromium is using ffmpeg-mt as the basis for accelerated video: http://www.chromium.org/developers/design-documents/video Is anyone currently working on support for ffmpeg-mt and i.MX video? Is anyone interested? Please advise, Eric ^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: Chromium acceleration 2014-03-19 20:49 Chromium acceleration Eric Nelson @ 2014-03-19 21:00 ` Carlos Rafael Giani 2014-03-19 22:40 ` Eric Nelson 2014-03-20 12:47 ` Lauren Post 1 sibling, 1 reply; 37+ messages in thread From: Carlos Rafael Giani @ 2014-03-19 21:00 UTC (permalink / raw) To: meta-freescale Hello, I wrote a patch for VPU acceleration in Chromium months ago for a company project. I got the OK from the customer to cleanup and eventually opensource the patches, but didn't have the time yet. Together with other colleagues we also got HW-accelerated WebGL to work, though some other areas weren't running so well (multitouch for example). Also, Canvas remained unaccelerated. As the Chromium developers explained, there are conceptual problems with the Canvas API that make acceleration difficult. What is also missing is a zerocopy method for displaying video frames. In theory, the direct textures from the Vivante GPU could be used; however, this requires passing the physical buffers through to a modified renderer somehow. Chromium can use OpenGL ES for rendering everything, but does not contain anything to introduce special video textures yet. Carlos On 03/19/2014 09:49 PM, Eric Nelson wrote: > Hi Lauren, > > A while back, you mentioned that 3.10.17-ga would help provide > support for "Chromium acceleration" but didn't provide details. > > Did you mean WebGL support (i.e. GPU acceleration), or video > acceleration (VPU support)? > > My understanding is that Chromium is using ffmpeg-mt as the > basis for accelerated video: > http://www.chromium.org/developers/design-documents/video > > Is anyone currently working on support for ffmpeg-mt and i.MX > video? > > Is anyone interested? > > Please advise, > > > Eric ^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: Chromium acceleration 2014-03-19 21:00 ` Carlos Rafael Giani @ 2014-03-19 22:40 ` Eric Nelson 2014-03-20 1:29 ` Christian Betz 0 siblings, 1 reply; 37+ messages in thread From: Eric Nelson @ 2014-03-19 22:40 UTC (permalink / raw) To: Carlos Rafael Giani, meta-freescale Hi Carlos, On 03/19/2014 02:00 PM, Carlos Rafael Giani wrote: > Hello, > > I wrote a patch for VPU acceleration in Chromium months ago for a > company project. I got the OK from the customer to cleanup and > eventually opensource the patches, but didn't have the time yet. You're the man! What can we do to help find you the time? > Together with other colleagues we also got HW-accelerated WebGL to work, > though some other areas weren't running so well (multitouch for > example). Also, Canvas remained unaccelerated. As the Chromium > developers explained, there are conceptual problems with the Canvas API > that make acceleration difficult. > Nice! I have to admit being a bit less interested in WebGL than in video acceleration, but I'm sure others really want this. > > What is also missing is a zerocopy method for displaying video frames. > Do we really want zero copy? It seems that at some level, having a single copy into a GPU accelerated rendering stack is more convenient. > In theory, the direct textures from the Vivante GPU could be used; > however, this requires passing the physical buffers through to a > modified renderer somehow. > > Chromium can use OpenGL ES for rendering everything, but does not > contain anything to introduce special video textures yet. > I'm not quite sure I'm grokking this. The Vivante libraries can map the physical buffers produced by the VPU directly, so they could do format conversion on their way to the graphics stack if the Chromium bindings have access to that (the "single copy" I referred to above). Or, (he says instead of finding the code), is this handled by ffmpeg-mt? Using an IPU overlay (a.la. mfw_v4lsink) is nice, but makes doing overlays and such more difficult, and you probably know how web-developers can be ;). Regards, Eric ^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: Chromium acceleration 2014-03-19 22:40 ` Eric Nelson @ 2014-03-20 1:29 ` Christian Betz 2014-03-20 2:50 ` Eric Nelson 0 siblings, 1 reply; 37+ messages in thread From: Christian Betz @ 2014-03-20 1:29 UTC (permalink / raw) To: Eric Nelson; +Cc: meta-freescale [-- Attachment #1: Type: text/plain, Size: 2199 bytes --] > > The Vivante libraries can map the physical buffers produced by > the VPU directly, so they could do format conversion on their > way to the graphics stack if the Chromium bindings have access > to that (the "single copy" I referred to above). > in my experience "zero-copy" really means zero memcpy() (or similar system call, or really anything that involves the cpu to move around image data. *metadata *such as buffer pointers is generally allowed). in other words having the GPU do format conversion isn't considered a copy. here's a great article on this general technique implemented in webkit/gtk+: http://blogs.igalia.com/vjaquez/2013/07/26/composited-video-support-in-webkitgtk/ moving beyond semantics... let me tell you what i know about this particular issue: there is source code in chromium to accomplish a similar goal. specifically there is a "generic" android driver, which works out of the box with i.mx6 because freescale implements the standard android video decode interface that allows VPU -> GPU texture uploading (don't quote me on this, i'm just reading the source code: https://chromium.googlesource.com/chromium/src/+/a361fce28da709ea872062f30fb4b65fcc37b695/content/common/gpu/media/android_video_decode_accelerator.cc ) sadly there is no such standard interface on GNU/Linux. outside of android (i.e. chromeos), there are drivers for particular chipsets, like samsung exynos. here is the source for that: https://chromium.googlesource.com/chromium/src/+/a361fce28da709ea872062f30fb4b65fcc37b695/content/common/gpu/media/exynos_video_decode_accelerator.cc the group should also be aware of the current situation regarding these modules *only* working when certain flags to enable "chromeos" are used (explained here: https://code.google.com/p/chromium/wiki/LinuxHWVideoDecode). in other words: this stuff doesn't work on your x86 with the chrome you download from google. @carlos: have you implemented a module along the lines of this exynos accelerator or did you take another route? a team member is actually about to attack this problem next week so it'd be great to see what you have before we reinvent your wheel. [-- Attachment #2: Type: text/html, Size: 3243 bytes --] ^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: Chromium acceleration 2014-03-20 1:29 ` Christian Betz @ 2014-03-20 2:50 ` Eric Nelson 2014-03-20 8:30 ` Carlos Rafael Giani 0 siblings, 1 reply; 37+ messages in thread From: Eric Nelson @ 2014-03-20 2:50 UTC (permalink / raw) To: Christian Betz; +Cc: meta-freescale Thanks Christian, On 03/19/2014 06:29 PM, Christian Betz wrote: > The Vivante libraries can map the physical buffers produced by > the VPU directly, so they could do format conversion on their > way to the graphics stack if the Chromium bindings have access > to that (the "single copy" I referred to above). > > > in my experience "zero-copy" really means zero memcpy() (or similar > system call, or really anything that involves the cpu to move around > image data. /metadata /such as buffer pointers is generally allowed). in > other words having the GPU do format conversion isn't considered a copy. > > here's a great article on this general technique implemented in > webkit/gtk+: > http://blogs.igalia.com/vjaquez/2013/07/26/composited-video-support-in-webkitgtk/ > That's a nice article, and if Webkit (Blink) retains the same mapping, video buffers from the VPU would end up hitting a RenderObject and the only "copy" would be in rendering that to the Framebuffer. Since we're on the fat end of the pipe here, that copy can be expensive and might limit things to 1x1080P decode, but I'd be happy with that. In the mfw_v4lsink case at least, this can be bypassed by having the V4L2 buffer filled by the VPU and also displayed by the IPU (such that copy), but aiming there would keep the video out of the rest of the RenderLayer tree (I think). This is what I was so awkwardly trying to suggest. > moving beyond semantics... let me tell you what i know about this > particular issue: > > there is source code in chromium to accomplish a similar goal. > specifically there is a "generic" android driver, which works out of the > box with i.mx6 because freescale implements the standard android video > decode interface that allows VPU -> GPU texture uploading (don't quote > me on this, i'm just reading the source code: > https://chromium.googlesource.com/chromium/src/+/a361fce28da709ea872062f30fb4b65fcc37b695/content/common/gpu/media/android_video_decode_accelerator.cc) > > sadly there is no such standard interface on GNU/Linux. outside of > android (i.e. chromeos), there are drivers for particular chipsets, like > samsung exynos. here is the source for that: > https://chromium.googlesource.com/chromium/src/+/a361fce28da709ea872062f30fb4b65fcc37b695/content/common/gpu/media/exynos_video_decode_accelerator.cc > > the group should also be aware of the current situation regarding these > modules /only/ working when certain flags to enable "chromeos" are used > (explained here: > https://code.google.com/p/chromium/wiki/LinuxHWVideoDecode). in other > words: this stuff doesn't work on your x86 with the chrome you download > from google. > Again, thanks for the info. Regards, Eric ^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: Chromium acceleration 2014-03-20 2:50 ` Eric Nelson @ 2014-03-20 8:30 ` Carlos Rafael Giani 2014-03-20 12:22 ` Otavio Salvador 2014-03-20 13:46 ` Christian Betz 0 siblings, 2 replies; 37+ messages in thread From: Carlos Rafael Giani @ 2014-03-20 8:30 UTC (permalink / raw) To: Eric Nelson, Christian Betz; +Cc: meta-freescale Hi Eric and Christian, I wanted to avoid _any_ copy involving the CPU, including any texture upload. The Vivante GLES direct texture extension can color-convert, yes, but it can also read pixels directly from a DMA buffer, without any copy. This is what I use for the GLES-based sink in my GStreamer plugins, and allows me to play 1080p videos with less than 6% CPU usage. v4lsink would be another idea, but I am a bit skeptical, because it wouldn't play well with any X11 or Wayland compositor, since it would essentially act like an overlay. This is even worse with the isink (if the regular, non-overlay layer is used), because then, the sink simply overwrites pixels drawn by X11. What the isink does is to make sure the pixels are blit in the area of its output window, so it does not overwrite anything outside. But again, with desktop compositing this would break down. (Also, the isink is quite slow.) I would consider this one texture upload only if absolutely necessary. My idea was to actually produce the texture in the decoder myself, and just send the texture GL name around to the renderer. This would require that everything is drawn with GLES of course - what would a software renderer do with a GL name? As for the decoder itself: I implemented it in the Chromium media framework, in media/ . I simply took the vpx decoder code, copied it, and modified it to use the VPU. I had VP8, MPEG2, MPEG4, and h264 decoding working. It wasnt much code, but unfortunately, the interfaces tend to change between versions, so the code would have to be updated for the newest Chromium version. It is not much code, I will try to clean it up a bit and post it. In addition, I will ask the colleagues for the other patches for accelerating the 2D and WebGL rendering. Carlos On 2014-03-20 03:50, Eric Nelson wrote: > Thanks Christian, > > On 03/19/2014 06:29 PM, Christian Betz wrote: >> The Vivante libraries can map the physical buffers produced by >> the VPU directly, so they could do format conversion on their >> way to the graphics stack if the Chromium bindings have access >> to that (the "single copy" I referred to above). >> >> >> in my experience "zero-copy" really means zero memcpy() (or similar >> system call, or really anything that involves the cpu to move around >> image data. /metadata /such as buffer pointers is generally allowed). in >> other words having the GPU do format conversion isn't considered a copy. >> >> here's a great article on this general technique implemented in >> webkit/gtk+: >> http://blogs.igalia.com/vjaquez/2013/07/26/composited-video-support-in-webkitgtk/ >> >> > > That's a nice article, and if Webkit (Blink) retains the same mapping, > video buffers from the VPU would end up hitting a RenderObject and > the only "copy" would be in rendering that to the Framebuffer. > > Since we're on the fat end of the pipe here, that copy can be expensive > and might limit things to 1x1080P decode, but I'd be happy with that. > > In the mfw_v4lsink case at least, this can be bypassed by having > the V4L2 buffer filled by the VPU and also displayed by the IPU > (such that copy), but aiming there would keep the video out of the > rest of the RenderLayer tree (I think). > > This is what I was so awkwardly trying to suggest. > >> moving beyond semantics... let me tell you what i know about this >> particular issue: >> >> there is source code in chromium to accomplish a similar goal. >> specifically there is a "generic" android driver, which works out of the >> box with i.mx6 because freescale implements the standard android video >> decode interface that allows VPU -> GPU texture uploading (don't quote >> me on this, i'm just reading the source code: >> https://chromium.googlesource.com/chromium/src/+/a361fce28da709ea872062f30fb4b65fcc37b695/content/common/gpu/media/android_video_decode_accelerator.cc) >> >> >> sadly there is no such standard interface on GNU/Linux. outside of >> android (i.e. chromeos), there are drivers for particular chipsets, like >> samsung exynos. here is the source for that: >> https://chromium.googlesource.com/chromium/src/+/a361fce28da709ea872062f30fb4b65fcc37b695/content/common/gpu/media/exynos_video_decode_accelerator.cc >> >> >> the group should also be aware of the current situation regarding these >> modules /only/ working when certain flags to enable "chromeos" are used >> (explained here: >> https://code.google.com/p/chromium/wiki/LinuxHWVideoDecode). in other >> words: this stuff doesn't work on your x86 with the chrome you download >> from google. >> > > Again, thanks for the info. > > Regards, > > > Eric ^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: Chromium acceleration 2014-03-20 8:30 ` Carlos Rafael Giani @ 2014-03-20 12:22 ` Otavio Salvador 2014-03-20 14:07 ` Christian Betz 2014-03-20 14:29 ` Eric Nelson 2014-03-20 13:46 ` Christian Betz 1 sibling, 2 replies; 37+ messages in thread From: Otavio Salvador @ 2014-03-20 12:22 UTC (permalink / raw) To: Carlos Rafael Giani; +Cc: meta-freescale On Thu, Mar 20, 2014 at 5:30 AM, Carlos Rafael Giani <dv@pseudoterminal.org> wrote: > Hi Eric and Christian, > > I wanted to avoid _any_ copy involving the CPU, including any texture > upload. The Vivante GLES direct texture extension can color-convert, yes, > but it can also read pixels directly from a DMA buffer, without any copy. > This is what I use for the GLES-based sink in my GStreamer plugins, and > allows me to play 1080p videos with less than 6% CPU usage. > v4lsink would be another idea, but I am a bit skeptical, because it wouldn't > play well with any X11 or Wayland compositor, since it would essentially act > like an overlay. This is even worse with the isink (if the regular, > non-overlay layer is used), because then, the sink simply overwrites pixels > drawn by X11. What the isink does is to make sure the pixels are blit in the > area of its output window, so it does not overwrite anything outside. But > again, with desktop compositing this would break down. (Also, the isink is > quite slow.) > > I would consider this one texture upload only if absolutely necessary. > > My idea was to actually produce the texture in the decoder myself, and just > send the texture GL name around to the renderer. This would require that > everything is drawn with GLES of course - what would a software renderer do > with a GL name? > > As for the decoder itself: I implemented it in the Chromium media framework, > in media/ . I simply took the vpx decoder code, copied it, and modified it > to use the VPU. I had VP8, MPEG2, MPEG4, and h264 decoding working. It wasnt > much code, but unfortunately, the interfaces tend to change between > versions, so the code would have to be updated for the newest Chromium > version. It is not much code, I will try to clean it up a bit and post it. > In addition, I will ask the colleagues for the other patches for > accelerating the 2D and WebGL rendering. \m/ bear on mind I pushed Chromium 35 in meta-browser ;-) -- Otavio Salvador O.S. Systems http://www.ossystems.com.br http://code.ossystems.com.br Mobile: +55 (53) 9981-7854 Mobile: +1 (347) 903-9750 ^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: Chromium acceleration 2014-03-20 12:22 ` Otavio Salvador @ 2014-03-20 14:07 ` Christian Betz 2014-03-20 15:02 ` Otavio Salvador 2014-03-20 14:29 ` Eric Nelson 1 sibling, 1 reply; 37+ messages in thread From: Christian Betz @ 2014-03-20 14:07 UTC (permalink / raw) To: Otavio Salvador; +Cc: meta-freescale [-- Attachment #1.1: Type: text/plain, Size: 955 bytes --] > > \m/ bear on mind I pushed Chromium 35 in meta-browser ;-) > this is great news. with any luck we'll let you know how it builds and works for us sometime next week. thank you! i assume you got it built successfully and have it running in some fashion. In case we have trouble, can you share what your exact setup was? I'm just assuming you used a imx6qsabresd machine with code from fsl master-next or master-branches (i.e. latest GPU drivers). did you look at chrome://gpu and confirm various acceleration modes are enabled? i attached a screenshot from my **intel/nvidia** system for reference. I think lauren is curious if webgl is working for you with latest vivante drivers. And *I* am curious about 'accelerated compositing'. btw everyone: m35 is a very ambitious release where google has ripped out GTK and replaced it with 'Aura' (a combined widget and compositing toolkit apparently). i just wanted to mention that. [-- Attachment #1.2: Type: text/html, Size: 1428 bytes --] [-- Attachment #2: about_gpu_nvidia_x86_64.png --] [-- Type: image/png, Size: 70457 bytes --] ^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: Chromium acceleration 2014-03-20 14:07 ` Christian Betz @ 2014-03-20 15:02 ` Otavio Salvador 0 siblings, 0 replies; 37+ messages in thread From: Otavio Salvador @ 2014-03-20 15:02 UTC (permalink / raw) To: Christian Betz; +Cc: meta-freescale On Thu, Mar 20, 2014 at 11:07 AM, Christian Betz <christian.betz@gmail.com> wrote: >> \m/ bear on mind I pushed Chromium 35 in meta-browser ;-) > > > this is great news. with any luck we'll let you know how it builds and works > for us sometime next week. thank you! > > i assume you got it built successfully and have it running in some fashion. > In case we have trouble, can you share what your exact setup was? I'm just > assuming you used a imx6qsabresd machine with code from fsl master-next or > master-branches (i.e. latest GPU drivers). Gary did. > did you look at chrome://gpu and confirm various acceleration modes are > enabled? i attached a screenshot from my **intel/nvidia** system for > reference. > > I think lauren is curious if webgl is working for you with latest vivante > drivers. And *I* am curious about 'accelerated compositing'. I didn't build the new chromium for a while (working for a customer with a way older version for a specific version). > btw everyone: m35 is a very ambitious release where google has ripped out > GTK and replaced it with 'Aura' (a combined widget and compositing toolkit > apparently). i just wanted to mention that. Yes; this also opens the door for Wayland support in future ;-) -- Otavio Salvador O.S. Systems http://www.ossystems.com.br http://code.ossystems.com.br Mobile: +55 (53) 9981-7854 Mobile: +1 (347) 903-9750 ^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: Chromium acceleration 2014-03-20 12:22 ` Otavio Salvador 2014-03-20 14:07 ` Christian Betz @ 2014-03-20 14:29 ` Eric Nelson 2014-03-20 14:58 ` Otavio Salvador 1 sibling, 1 reply; 37+ messages in thread From: Eric Nelson @ 2014-03-20 14:29 UTC (permalink / raw) To: Otavio Salvador, Carlos Rafael Giani; +Cc: meta-freescale Thanks Otavio, On 03/20/2014 05:22 AM, Otavio Salvador wrote: > On Thu, Mar 20, 2014 at 5:30 AM, Carlos Rafael Giani > <dv@pseudoterminal.org> wrote: >> Hi Eric and Christian, >> >> <snip> >> >> As for the decoder itself: I implemented it in the Chromium media framework, >> in media/ . I simply took the vpx decoder code, copied it, and modified it >> to use the VPU. I had VP8, MPEG2, MPEG4, and h264 decoding working. It wasnt >> much code, but unfortunately, the interfaces tend to change between >> versions, so the code would have to be updated for the newest Chromium >> version. It is not much code, I will try to clean it up a bit and post it. >> In addition, I will ask the colleagues for the other patches for >> accelerating the 2D and WebGL rendering. > > \m/ bear on mind I pushed Chromium 35 in meta-browser ;-) > I sent an RFC patch yesterday regarding inclusion of meta-qt5 into fsl-community-bsp-platform. Is there any interest or conflict in the same for meta-browser? A simplistic test shows that it's really straightforward to add both Chromium and Firefox into fsl-image-gui by pulling in meta-browser. Regards, Eric ^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: Chromium acceleration 2014-03-20 14:29 ` Eric Nelson @ 2014-03-20 14:58 ` Otavio Salvador 2014-03-21 11:49 ` Diego 0 siblings, 1 reply; 37+ messages in thread From: Otavio Salvador @ 2014-03-20 14:58 UTC (permalink / raw) To: Eric Nelson; +Cc: meta-freescale On Thu, Mar 20, 2014 at 11:29 AM, Eric Nelson <eric.nelson@boundarydevices.com> wrote: > Thanks Otavio, > > > On 03/20/2014 05:22 AM, Otavio Salvador wrote: >> >> On Thu, Mar 20, 2014 at 5:30 AM, Carlos Rafael Giani >> <dv@pseudoterminal.org> wrote: >>> >>> Hi Eric and Christian, >>> >>> <snip> > >>> >>> As for the decoder itself: I implemented it in the Chromium media >>> framework, >>> in media/ . I simply took the vpx decoder code, copied it, and modified >>> it >>> to use the VPU. I had VP8, MPEG2, MPEG4, and h264 decoding working. It >>> wasnt >>> much code, but unfortunately, the interfaces tend to change between >>> versions, so the code would have to be updated for the newest Chromium >>> version. It is not much code, I will try to clean it up a bit and post >>> it. >>> In addition, I will ask the colleagues for the other patches for >>> accelerating the 2D and WebGL rendering. >> >> >> \m/ bear on mind I pushed Chromium 35 in meta-browser ;-) >> > > I sent an RFC patch yesterday regarding inclusion of meta-qt5 into > fsl-community-bsp-platform. > > Is there any interest or conflict in the same for meta-browser? > > A simplistic test shows that it's really straightforward to > add both Chromium and Firefox into fsl-image-gui by pulling > in meta-browser. The biggest problem adding more stuff is maintenance. This increases build time and tests needed for a good coverage. What people think? -- Otavio Salvador O.S. Systems http://www.ossystems.com.br http://code.ossystems.com.br Mobile: +55 (53) 9981-7854 Mobile: +1 (347) 903-9750 ^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: Chromium acceleration 2014-03-20 14:58 ` Otavio Salvador @ 2014-03-21 11:49 ` Diego 2014-03-21 14:17 ` Eric Nelson 0 siblings, 1 reply; 37+ messages in thread From: Diego @ 2014-03-21 11:49 UTC (permalink / raw) To: meta-freescale Otavio Salvador wrote: > Eric Nelson wrote: > > A simplistic test shows that it's really straightforward to > > add both Chromium and Firefox into fsl-image-gui by pulling > > in meta-browser. > > The biggest problem adding more stuff is maintenance. This increases > build time and tests needed for a good coverage. > > What people think? Hi Otavio and Eric, I think we can sum up your discussion in two points: - web applications and in general browser usage is really important nowadays in general, and it is taking its share of interest also in the embedded world; - firefox and chromium require quite a lot of resources both in terms of maintenance and in terms of build time and computation. I can confirm both points, as we have a couple of projects using Chromium. So on one hand it is something important to support and test regularly (and that would help finding build breakages), on the other hand build takes a lot time, and an overwhelming amount of RAM. I used to build images with Firefox and Chromium 29 with 6 bitbake build threads and it worked on a 4GB of RAM and 2GB swap, but now with Chromium 35 I had to pump up the VM to 12GB of RAM (8GB still killed the final ld linking process, which is the real "RAM eater"). So while testing browsers would be nice, I think the best option would be to test it somehow separately from the fsl-image-gui. Do you think defining an image in meta-browser would make sense? Bests, Diego ^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: Chromium acceleration 2014-03-21 11:49 ` Diego @ 2014-03-21 14:17 ` Eric Nelson 0 siblings, 0 replies; 37+ messages in thread From: Eric Nelson @ 2014-03-21 14:17 UTC (permalink / raw) To: Diego, meta-freescale Hi Diego, On 03/21/2014 04:49 AM, Diego wrote: > Otavio Salvador wrote: >> Eric Nelson wrote: >>> A simplistic test shows that it's really straightforward to >>> add both Chromium and Firefox into fsl-image-gui by pulling >>> in meta-browser. >> >> The biggest problem adding more stuff is maintenance. This increases >> build time and tests needed for a good coverage. >> >> What people think? > > Hi Otavio and Eric, > > I think we can sum up your discussion in two points: > - web applications and in general browser usage is really important nowadays > in general, and it is taking its share of interest also in the embedded world; > - firefox and chromium require quite a lot of resources both in terms of > maintenance and in terms of build time and computation. > > I can confirm both points, as we have a couple of projects using Chromium. So > on one hand it is something important to support and test regularly (and that > would help finding build breakages), on the other hand build takes a lot time, > and an overwhelming amount of RAM. I used to build images with Firefox and > Chromium 29 with 6 bitbake build threads and it worked on a 4GB of RAM and 2GB > swap, but now with Chromium 35 I had to pump up the VM to 12GB of RAM (8GB > still killed the final ld linking process, which is the real "RAM eater"). > > So while testing browsers would be nice, I think the best option would be to > test it somehow separately from the fsl-image-gui. Do you think defining an > image in meta-browser would make sense? > I wasn't suggesting that Chromium or Firefox be included in fsl-image-gui. Only that meta-browser (and I think meta-gnome as a dependency) be included in the default manifest. This will prevent the need to "git clone" the repositories separately, and allow inclusion through local.conf. Regards, Eric ^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: Chromium acceleration 2014-03-20 8:30 ` Carlos Rafael Giani 2014-03-20 12:22 ` Otavio Salvador @ 2014-03-20 13:46 ` Christian Betz 2014-03-20 23:19 ` Carlos Rafael Giani 1 sibling, 1 reply; 37+ messages in thread From: Christian Betz @ 2014-03-20 13:46 UTC (permalink / raw) To: Carlos Rafael Giani; +Cc: meta-freescale [-- Attachment #1: Type: text/plain, Size: 1507 bytes --] > > As for the decoder itself: I implemented it in the Chromium media > framework, in media/ . I simply took the vpx decoder code, copied it, and > modified it to use the VPU. I had VP8, MPEG2, MPEG4, and h264 decoding > working. It wasnt much code, but unfortunately, the interfaces tend to > change between versions, so the code would have to be updated for the > newest Chromium version. It is not much code, I will try to clean it up a > bit and post it. In addition, I will ask the colleagues for the other > patches for accelerating the 2D and WebGL rendering. thanks carlos! my analysis suggested that my team should reproduce these chunks of code which are for samsung exynos: https://chromium.googlesource.com/chromium/src/+/a361fce28da709ea872062f30fb4b65fcc37b695/content/common/gpu/media/exynos_video_decode_accelerator.cc to oversimplify greatly: we want to port 'exynos_video_decode_accelerator' to a new 'imx_video_decode_accelerator'. in this module we would make use of the same direct texture techniques as eglvivsink from gstreamer-imx. this is definitely not the route you have taken, from what I can tell. is this something you considered and steered away from? have you examined these code paths at all? there are a few other special modules besides exynos too. i might be wrong, but it could be the best chance of getting something upstreamed would be do it "like everyone else" (i.e. samsung). but i'm probably thinking *way* too far ahead here. [-- Attachment #2: Type: text/html, Size: 2088 bytes --] ^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: Chromium acceleration 2014-03-20 13:46 ` Christian Betz @ 2014-03-20 23:19 ` Carlos Rafael Giani 2014-03-21 12:21 ` Dmitriy B. 2014-04-01 19:22 ` Eric Nelson 0 siblings, 2 replies; 37+ messages in thread From: Carlos Rafael Giani @ 2014-03-20 23:19 UTC (permalink / raw) To: Christian Betz; +Cc: meta-freescale [-- Attachment #1.1: Type: text/plain, Size: 3898 bytes --] On 2014-03-20 14:46, Christian Betz wrote: > > As for the decoder itself: I implemented it in the Chromium media > framework, in media/ . I simply took the vpx decoder code, copied > it, and modified it to use the VPU. I had VP8, MPEG2, MPEG4, and > h264 decoding working. It wasnt much code, but unfortunately, the > interfaces tend to change between versions, so the code would have > to be updated for the newest Chromium version. It is not much > code, I will try to clean it up a bit and post it. In addition, I > will ask the colleagues for the other patches for accelerating the > 2D and WebGL rendering. > > > thanks carlos! > > my analysis suggested that my team should reproduce these chunks of > code which are for samsung exynos: > > https://chromium.googlesource.com/chromium/src/+/a361fce28da709ea872062f30fb4b65fcc37b695/content/common/gpu/media/exynos_video_decode_accelerator.cc > > to oversimplify greatly: we want to port > 'exynos_video_decode_accelerator' to a new > 'imx_video_decode_accelerator'. in this module we would make use of > the same direct texture techniques as eglvivsink from gstreamer-imx. > > this is definitely not the route you have taken, from what I can tell. > is this something you considered and steered away from? have you > examined these code paths at all? there are a few other special > modules besides exynos too. > > i might be wrong, but it could be the best chance of getting something > upstreamed would be do it "like everyone else" (i.e. samsung). but i'm > probably thinking *way* too far ahead here. Back then we needed some hw decoding quickly, so we did not look further into this, since we had spent a lot of time getting the 2D acceleration stable already. I could only briefly look at the exynos accelerator code, but it does look like the right direction, although the VPU uses physical addresses directly instead of dmabuf FDs. I am currently writing a frontend for the libfslvpuwrap, which takes care of certain complexities (like being able to pass userdata pointers to frames, to make it possible to associate input and output frames, which is essential for correct timestamping, especially when things like h264 frame reordering are active). This frontend will hide these things in a future gstreamer-imx release to make the decoder code clearer and easier to maintain, and is intended to be reusable, for example for Chromium integration, or XBMC. Beyond that, my patches are probably not that helpful anymore, since they were based on the vpx decoder way of decoding, and I agree that the exynos code is a better starting point. Nevertheless, I attached the patch. Keep in mind that it is very basic, old, and wasn't further developed on because it was "good enough" for the project. But here are some additional notes from our efforts to accelerate Chromium on imx6 (keep in mind these apply to version 32.0.1664.3 ) : 1. We started the google-chrome binary with these switches: --ignore-gpu-blacklist --enable-gpu --use-gl=egl --enable-accelerated-2d-canvas 2. To make building Chromium easier, we switched to component build (by default, it is all linked into one enormous binary). I attached a patch that was necessary to fix some minor issues. Perhaps it is not necessary anymore. 3. Chromium tried to load libEGL with dlopen() , which caused problems, because with the Vivante libraries, libEGL also needs libGAL. Usually, build scripts just add -lEGL -lGAL to the linker line. With dlopen() this wasn't possible of course. We patched the gyp scripts to link against this libraries during building instead. I attached this patch. It is really a hack, because it circumvents the sandboxing process (this is why Chromium loads EGL and GLESv2 with dlopen() ). Carlos [-- Attachment #1.2: Type: text/html, Size: 5719 bytes --] [-- Attachment #2: 0002-Fix-issue-with-component-linking.patch --] [-- Type: text/x-patch, Size: 823 bytes --] --- a/build/common.gypi 2013-09-05 12:33:58.000000000 +0200 +++ b/build/common.gypi 2013-09-13 09:29:24.185329621 +0200 @@ -2840,11 +2840,6 @@ '-Wl,--as-needed', ], }], - ['OS=="linux" and target_arch=="ia32"', { - 'ldflags': [ - '-Wl,--no-as-needed', - ], - }], ], }, 'Release_Base': { @@ -3460,6 +3455,10 @@ # gets the right path. '-B<(PRODUCT_DIR)/../../third_party/gold', ], + }, { + 'ldflags': [ + '-Wl,--no-as-needed', + ], }], ['native_discardable_memory', { 'defines': ['DISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY'], [-- Attachment #3: 0004-Modified-gl.gyp-to-link-libEGL-and-libGAL-at-build-t.patch --] [-- Type: text/x-patch, Size: 636 bytes --] diff --git a/ui/gl/gl.gyp b/ui/gl/gl.gyp index 274065b..e857f9c 100644 --- a/ui/gl/gl.gyp +++ b/ui/gl/gl.gyp @@ -123,6 +123,12 @@ '<(gl_binding_output_dir)/gl_bindings_autogen_osmesa.h', '<(gl_binding_output_dir)/gl_interface_autogen_gl.h', ], + 'link_settings': { + 'libraries': [ + '-lEGL', + '-lGAL', + ], + }, # hard_dependency is necessary for this target because it has actions # that generate header files included by dependent targets. The header # files must be generated before the dependents are compiled. The usual [-- Attachment #4: 0005-Added-hardware-accelerated-decoding-with-the-i.MX-VP.patch --] [-- Type: text/x-patch, Size: 28854 bytes --] diff --git a/content/renderer/media/webmediaplayer_impl.cc b/content/renderer/media/webmediaplayer_impl.cc index a99c3ae..1ec8bfa 100644 --- a/content/renderer/media/webmediaplayer_impl.cc +++ b/content/renderer/media/webmediaplayer_impl.cc @@ -47,6 +47,7 @@ #include "media/filters/gpu_video_decoder.h" #include "media/filters/opus_audio_decoder.h" #include "media/filters/video_renderer_base.h" +#include "media/filters/vpu_video_decoder.h" #include "media/filters/vpx_video_decoder.h" #include "third_party/WebKit/public/platform/WebMediaSource.h" #include "third_party/WebKit/public/platform/WebRect.h" @@ -1103,6 +1104,10 @@ void WebMediaPlayerImpl::StartPipeline() { new media::GpuVideoDecoder(gpu_factories_, media_log_)); } +#if !defined(MEDIA_DISABLE_IMXVPU) + video_decoders.push_back(new media::VpuVideoDecoder(media_loop_)); +#endif // !defined(MEDIA_DISABLE_IMXVPU) + // TODO(phajdan.jr): Remove ifdefs when libvpx with vp9 support is released // (http://crbug.com/174287) . #if !defined(MEDIA_DISABLE_LIBVPX) diff --git a/media/filters/vpu_framebuffers.cc b/media/filters/vpu_framebuffers.cc new file mode 100644 index 0000000..fce43fc --- /dev/null +++ b/media/filters/vpu_framebuffers.cc @@ -0,0 +1,106 @@ +#include <string.h> +#include <stdint.h> +#include "vpu_framebuffers.h" +#include "base/logging.h" + + +#define ALIGN_VAL_TO(LENGTH, ALIGN_SIZE) ( ((uintptr_t)((LENGTH) + (ALIGN_SIZE) - 1) / (ALIGN_SIZE)) * (ALIGN_SIZE) ) +#define FRAME_ALIGN 16 + + +namespace media { + + +VPUFramebuffers::VPUFramebuffers() { +} + + +void VPUFramebuffers::init(VpuDecHandle handle, VpuDecInitInfo const &init_info) { + framebuffers.resize(init_info.nMinFrameBufferCount); + + y_stride = ALIGN_VAL_TO(init_info.nPicWidth, FRAME_ALIGN); + if (init_info.nInterlace) + y_size = y_stride * ALIGN_VAL_TO(init_info.nPicHeight, (2 * FRAME_ALIGN)); + else + y_size = y_stride * ALIGN_VAL_TO(init_info.nPicHeight, FRAME_ALIGN); + + uv_stride = y_stride / 2; + u_size = v_size = mv_size = y_size / 4; + + int alignment = init_info.nAddressAlignment; + if (alignment > 1) + { + y_size = ALIGN_VAL_TO(y_size, alignment); + u_size = ALIGN_VAL_TO(u_size, alignment); + v_size = ALIGN_VAL_TO(v_size, alignment); + mv_size = ALIGN_VAL_TO(mv_size, alignment); + } + + pic_width = init_info.nPicWidth; + pic_height = init_info.nPicHeight; + + total_size = y_size + u_size + v_size + mv_size + alignment; + + LOG(INFO) << "Num VPU framebuffers: " << framebuffers.size(); + LOG(INFO) << "VPU framebuffer memory block size:" + << " total: " << total_size + << " Y " << y_size + << " U: " << u_size + << " V: " << v_size + << " Mv: " << mv_size + << " alignment: " << alignment + ; + + for (Framebuffers::iterator iter = framebuffers.begin(); iter != framebuffers.end(); ++iter) { + unsigned char *virt_ptr, *phys_ptr; + + VpuFrameBuffer &framebuffer = *iter; + + VpuMemDesc mem_desc; + memset(&mem_desc, 0, sizeof(VpuMemDesc)); + mem_desc.nSize = total_size; + VPU_DecGetMem(&mem_desc); + phys_mem_blocks.push_back(mem_desc); + + virt_ptr = (unsigned char*)(mem_desc.nVirtAddr); + phys_ptr = (unsigned char*)(mem_desc.nPhyAddr); + + if (alignment > 1) { + phys_ptr = (unsigned char*)ALIGN_VAL_TO(phys_ptr, alignment); + virt_ptr = (unsigned char*)ALIGN_VAL_TO(virt_ptr, alignment); + } + + framebuffer.nStrideY = y_stride; + framebuffer.nStrideC = uv_stride; + + /* fill phy addr*/ + framebuffer.pbufY = phys_ptr; + framebuffer.pbufCb = phys_ptr + y_size; + framebuffer.pbufCr = phys_ptr + y_size + u_size; + framebuffer.pbufMvCol = phys_ptr + y_size + u_size + v_size; + + /* fill virt addr */ + framebuffer.pbufVirtY = virt_ptr; + framebuffer.pbufVirtCb = virt_ptr + y_size; + framebuffer.pbufVirtCr = virt_ptr + y_size + u_size; + framebuffer.pbufVirtMvCol = virt_ptr + y_size + u_size + v_size; + + framebuffer.pbufY_tilebot = 0; + framebuffer.pbufCb_tilebot = 0; + framebuffer.pbufVirtY_tilebot = 0; + framebuffer.pbufVirtCb_tilebot = 0; + } + + VPU_DecRegisterFrameBuffer(handle, &(framebuffers[0]), framebuffers.size()); +} + + +VPUFramebuffers::~VPUFramebuffers() { + LOG(INFO) << "Freeing VPU framebuffer memory"; + for (PhysMemBlocks::iterator iter = phys_mem_blocks.begin(); iter != phys_mem_blocks.end(); ++iter) + VPU_DecFreeMem(&(*iter)); +} + + +} + diff --git a/media/filters/vpu_framebuffers.h b/media/filters/vpu_framebuffers.h new file mode 100644 index 0000000..bb9b021 --- /dev/null +++ b/media/filters/vpu_framebuffers.h @@ -0,0 +1,36 @@ +#ifndef MEDIA_FILTERS_VPU_FRAMEBUFFERS_H_ +#define MEDIA_FILTERS_VPU_FRAMEBUFFERS_H_ + +#include <list> +#include <vector> +#include <vpu_wrapper.h> + + +namespace media { + + +class VPUFramebuffers +{ +public: + explicit VPUFramebuffers(); + ~VPUFramebuffers(); + + void init(VpuDecHandle handle, VpuDecInitInfo const &init_info); + +private: + typedef std::vector < VpuFrameBuffer > Framebuffers; + typedef std::list < VpuMemDesc > PhysMemBlocks; + + PhysMemBlocks phys_mem_blocks; + Framebuffers framebuffers; + int y_stride, uv_stride; + int y_size, u_size, v_size, mv_size; + int total_size; + unsigned int pic_width, pic_height; +}; + + +} + + +#endif diff --git a/media/filters/vpu_video_decoder.cc b/media/filters/vpu_video_decoder.cc new file mode 100644 index 0000000..396d4f1 --- /dev/null +++ b/media/filters/vpu_video_decoder.cc @@ -0,0 +1,614 @@ +#include <list> +#include <vector> +#include <stddef.h> +#include <stdint.h> +#include <algorithm> +#include <string> + +#include <string.h> + +#include "media/filters/vpu_video_decoder.h" + +#include "base/bind.h" +#include "base/callback_helpers.h" +#include "base/command_line.h" +#include "base/location.h" +#include "base/logging.h" +#include "base/synchronization/lock.h" +#include "base/message_loop/message_loop_proxy.h" +#include "base/strings/string_number_conversions.h" +#include "base/sys_byteorder.h" +#include "media/base/bind_to_loop.h" +#include "media/base/decoder_buffer.h" +#include "media/base/demuxer_stream.h" +#include "media/base/media_switches.h" +#include "media/base/pipeline.h" +#include "media/base/video_decoder_config.h" +#include "media/base/video_frame.h" +#include "media/base/video_util.h" + +#include "media/filters/vpu_framebuffers.h" + +#include <vpu_wrapper.h> + + +#define ALIGN_VAL_TO(LENGTH, ALIGN_SIZE) ( ((uintptr_t)((LENGTH) + (ALIGN_SIZE) - 1) / (ALIGN_SIZE)) * (ALIGN_SIZE) ) + + + +namespace media { + + +namespace { + + +char const *VpuStrerror(VpuDecRetCode const code) { + switch (code) { + case VPU_DEC_RET_SUCCESS: return "success"; + case VPU_DEC_RET_FAILURE: return "failure"; + case VPU_DEC_RET_INVALID_PARAM: return "invalid param"; + case VPU_DEC_RET_INVALID_HANDLE: return "invalid handle"; + case VPU_DEC_RET_INVALID_FRAME_BUFFER: return "invalid frame buffer"; + case VPU_DEC_RET_INSUFFICIENT_FRAME_BUFFERS: return "insufficient frame buffers"; + case VPU_DEC_RET_INVALID_STRIDE: return "invalid stride"; + case VPU_DEC_RET_WRONG_CALL_SEQUENCE: return "wrong call sequence"; + case VPU_DEC_RET_FAILURE_TIMEOUT: return "failure timeout"; + default: + return NULL; + } +} + + +long inst_count = 0; +base::Lock vpu_load_lock; + + +void LoadDecoder() { + VpuDecRetCode ret; + + base::AutoLock alock(vpu_load_lock); + + if (inst_count == 0) { + ret = VPU_DecLoad(); + if (ret != VPU_DEC_RET_SUCCESS) { + LOG(ERROR) << "VPU loading failed: " << VpuStrerror(ret); + return; + } + + } + + ++inst_count; + + if (inst_count == 1) { + VpuVersionInfo version; + VpuWrapperVersionInfo wrapper_version; + + ret = VPU_DecGetVersionInfo(&version); + if (ret != VPU_DEC_RET_SUCCESS) { + LOG(ERROR) << "Getting version info failed: " << VpuStrerror(ret); + return; + } + + ret = VPU_DecGetWrapperVersionInfo(&wrapper_version); + if (ret != VPU_DEC_RET_SUCCESS) { + LOG(ERROR) << "Getting wrapper version info failed: " << VpuStrerror(ret); + return; + } + + LOG(INFO) << "VPU Loaded"; + LOG(INFO) << "VPU firmware version " << version.nFwMajor << "." << version.nFwMinor << "." << version.nFwRelease << "_r" << version.nFwCode; + LOG(INFO) << "VPU library version " << version.nLibMajor << "." << version.nLibMinor << "." << version.nLibRelease; + LOG(INFO) << "VPU wrapper version " << wrapper_version.nMajor << "." << wrapper_version.nMinor << "." << wrapper_version.nRelease << " " << wrapper_version.pBinary; + } +} + + +void UnloadDecoder() { + base::AutoLock alock(vpu_load_lock); + + if (inst_count == 0) + return; + + --inst_count; + + if (inst_count == 0) + VPU_DecUnLoad(); +} + + +} + + +struct VpuVideoDecoder::Internal +{ + typedef std::vector < uint8_t > VirtMemBlock; + typedef std::list < VirtMemBlock > VirtMemBlocks; + + typedef std::list < VpuMemDesc > PhysMemBlocks; + + VpuDecHandle handle; + + VpuDecInitInfo init_info; + VpuMemInfo mem_info; + + bool vpu_opened; + + VirtMemBlocks virt_mem_blocks; + PhysMemBlocks phys_mem_blocks; + + VPUFramebuffers framebuffers; + + Internal() + : vpu_opened(false) + { + } + + ~Internal() + { + FreeMemBlocks(); + } + + bool AllocMemBlocks() + { + VpuDecRetCode ret; + + memset(&mem_info, 0, sizeof(VpuMemInfo)); + ret = VPU_DecQueryMem(&mem_info); + if (ret != VPU_DEC_RET_SUCCESS) { + LOG(ERROR) << "Could not get VPU memory information: " << VpuStrerror(ret); + return false; + } + + for (int i = 0; i < mem_info.nSubBlockNum; ++i) + { + int size = mem_info.MemSubBlock[i].nAlignment + mem_info.MemSubBlock[i].nSize; + + LOG(INFO) << "Sub block " << i << " type: " << ((mem_info.MemSubBlock[i].MemType == VPU_MEM_VIRT) ? "virtual" : "phys") << " size: " << size; + + if (mem_info.MemSubBlock[i].MemType == VPU_MEM_VIRT) + { + unsigned char *virt_ptr; + virt_mem_blocks.push_back(VirtMemBlock()); + VirtMemBlock &blk = virt_mem_blocks.back(); + blk.resize(size); + virt_ptr = reinterpret_cast < unsigned char* > (&blk[0]); + + mem_info.MemSubBlock[i].pVirtAddr = (unsigned char *)ALIGN_VAL_TO(virt_ptr, mem_info.MemSubBlock[i].nAlignment); + } + else if (mem_info.MemSubBlock[i].MemType == VPU_MEM_PHY) + { + VpuMemDesc mem_desc; + memset(&mem_desc, 0, sizeof(VpuMemDesc)); + mem_desc.nSize = size; + if (VPU_DecGetMem(&mem_desc) != VPU_DEC_RET_SUCCESS) { + LOG(ERROR) << "Unable to allocate " << size << " bytes of physical memory"; + return false; + } + + phys_mem_blocks.push_back(mem_desc); + + mem_info.MemSubBlock[i].pVirtAddr = (unsigned char *)ALIGN_VAL_TO((unsigned char*)(mem_desc.nVirtAddr), mem_info.MemSubBlock[i].nAlignment); + mem_info.MemSubBlock[i].pPhyAddr = (unsigned char *)ALIGN_VAL_TO((unsigned char*)(mem_desc.nPhyAddr), mem_info.MemSubBlock[i].nAlignment); + } + else + LOG(WARNING) << "Sub block " << i << " type is unknown - skipping"; + } + + LOG(INFO) << "VPU memory blocks allocated"; + + return true; + } + + void FreeMemBlocks() + { + LOG(INFO) << "Freeing VPU memory blocks"; + + for (PhysMemBlocks::iterator iter = phys_mem_blocks.begin(); iter != phys_mem_blocks.end(); ++iter) + VPU_DecFreeMem(&(*iter)); + } +}; + + + +void CopyVpuFramebufferTo(VpuFrameBuffer *framebuffer, scoped_refptr<VideoFrame>* video_frame, VpuDecInitInfo &init_info, const VideoDecoderConfig& config); + + + + +VpuVideoDecoder::VpuVideoDecoder( + const scoped_refptr<base::MessageLoopProxy>& message_loop) + : message_loop_(message_loop), + weak_factory_(this), + state_(kUninitialized) { + LoadDecoder(); + internal = new Internal; +} + +VpuVideoDecoder::~VpuVideoDecoder() { + DCHECK_EQ(kUninitialized, state_); + CloseDecoder(); + delete internal; + UnloadDecoder(); +} + +void VpuVideoDecoder::Initialize(const VideoDecoderConfig& config, + const PipelineStatusCB& status_cb) { + DCHECK(message_loop_->BelongsToCurrentThread()); + DCHECK(config.IsValidConfig()); + DCHECK(!config.is_encrypted()); + DCHECK(decode_cb_.is_null()); + DCHECK(reset_cb_.is_null()); + + weak_this_ = weak_factory_.GetWeakPtr(); + + if (!internal->AllocMemBlocks()) { + status_cb.Run(PIPELINE_ERROR_INITIALIZATION_FAILED); + return; + } + + if (!ConfigureDecoder(config)) { + status_cb.Run(DECODER_ERROR_NOT_SUPPORTED); + return; + } + + // Success! + LOG(INFO) << "VPU decoder initialization succeeded"; + config_ = config; + state_ = kNormal; + status_cb.Run(PIPELINE_OK); +} + +bool VpuVideoDecoder::ConfigureDecoder(const VideoDecoderConfig& config) { + bool can_handle = false; + + if ((config.format() == VideoFrame::YV12) || (config.format() == VideoFrame::YV12A) || (config.format() == VideoFrame::I420)) { + switch (config.codec()) { + case kCodecH264: + case kCodecVC1: + case kCodecMPEG2: + case kCodecMPEG4: + case kCodecVP8: + can_handle = true; + default: + break; + } + } + + if (!can_handle) { + LOG(INFO) << "Cannot handle video config: " << config.AsHumanReadableString(); + return false; + } + + CloseDecoder(); + return OpenDecoder(config); +} + +bool VpuVideoDecoder::OpenDecoder(const VideoDecoderConfig& config) { + if (internal->vpu_opened) + return true; + + VpuDecOpenParam open_param; + VpuDecRetCode ret; + + memset(&open_param, 0, sizeof(open_param)); + + switch (config.codec()) + { + case kCodecH264: + open_param.CodecFormat = VPU_V_AVC; + open_param.nReorderEnable = 1; + LOG(INFO) << "Setting h.264 as stream format"; + break; + case kCodecVC1: + open_param.CodecFormat = VPU_V_VC1_AP; + LOG(INFO) << "Setting VC1 as stream format"; + break; + case kCodecMPEG2: + open_param.CodecFormat = VPU_V_MPEG2; + LOG(INFO) << "Setting MPEG-2 as stream format"; + break; + case kCodecMPEG4: + open_param.CodecFormat = VPU_V_MPEG4; + LOG(INFO) << "Setting MPEG-4 as stream format"; + break; + case kCodecVP8: + open_param.CodecFormat = VPU_V_VP8; + LOG(INFO) << "Setting VP8 as stream format"; + break; + default: + LOG(ERROR) << "Could not set unknown stream format"; + break; + } + + open_param.nChromaInterleave = 0; + open_param.nMapType = 0; + open_param.nTiled2LinearEnable = 0; + open_param.nEnableFileMode = 0; + open_param.nPicWidth = config.coded_size().width(); + open_param.nPicHeight = config.coded_size().height(); + + ret = VPU_DecOpen(&(internal->handle), &open_param, &(internal->mem_info)); + if (ret != VPU_DEC_RET_SUCCESS) { + LOG(ERROR) << "Opening new VPU handle failed: " << VpuStrerror(ret); + return false; + } + + int config_param; + + config_param = VPU_DEC_SKIPNONE; + ret = VPU_DecConfig(internal->handle, VPU_DEC_CONF_SKIPMODE, &config_param); + if (ret != VPU_DEC_RET_SUCCESS) { + LOG(ERROR) << "Could not configure skip mode: " << VpuStrerror(ret); + return false; + } + + config_param = 0; + ret = VPU_DecConfig(internal->handle, VPU_DEC_CONF_BUFDELAY, &config_param); + if (ret != VPU_DEC_RET_SUCCESS) { + LOG(ERROR) << "Could not configure buffer delay: " << VpuStrerror(ret); + return false; + } + + config_param = VPU_DEC_IN_NORMAL; + ret = VPU_DecConfig(internal->handle, VPU_DEC_CONF_INPUTTYPE, &config_param); + if (ret != VPU_DEC_RET_SUCCESS) { + LOG(ERROR) << "Could not configure input type: " << VpuStrerror(ret); + return false; + } + + internal->vpu_opened = true; + + return true; +} + +void VpuVideoDecoder::CloseDecoder() { + VpuDecRetCode ret; + + if (!(internal->vpu_opened)) + return; + + ret = VPU_DecFlushAll(internal->handle); + if (ret != VPU_DEC_RET_SUCCESS) + LOG(ERROR) << "Flushing decoder failed: " << VpuStrerror(ret); + VPU_DecClose(internal->handle); + if (ret != VPU_DEC_RET_SUCCESS) + LOG(ERROR) << "Closing decoder failed: " << VpuStrerror(ret); + + internal->vpu_opened = false; +} + +void VpuVideoDecoder::Decode(const scoped_refptr<DecoderBuffer>& buffer, + const DecodeCB& decode_cb) { + DCHECK(message_loop_->BelongsToCurrentThread()); + DCHECK(!decode_cb.is_null()); + CHECK_NE(state_, kUninitialized); + CHECK(decode_cb_.is_null()) << "Overlapping decodes are not supported."; + + decode_cb_ = BindToCurrentLoop(decode_cb); + + if (state_ == kError) { + base::ResetAndReturn(&decode_cb_).Run(kDecodeError, NULL); + return; + } + + // Return empty frames if decoding has finished. + if (state_ == kDecodeFinished) { + base::ResetAndReturn(&decode_cb_).Run(kOk, VideoFrame::CreateEmptyFrame()); + return; + } + + DecodeBuffer(buffer); +} + +void VpuVideoDecoder::Reset(const base::Closure& closure) { + DCHECK(message_loop_->BelongsToCurrentThread()); + DCHECK(reset_cb_.is_null()); + reset_cb_ = BindToCurrentLoop(closure); + + // Defer the reset if a decode is pending. + if (!decode_cb_.is_null()) + return; + + DoReset(); +} + +void VpuVideoDecoder::Stop(const base::Closure& closure) { + DCHECK(message_loop_->BelongsToCurrentThread()); + base::ScopedClosureRunner runner(BindToCurrentLoop(closure)); + + if (state_ == kUninitialized) + return; + + if (!decode_cb_.is_null()) { + base::ResetAndReturn(&decode_cb_).Run(kOk, NULL); + // Reset is pending only when decode is pending. + if (!reset_cb_.is_null()) + base::ResetAndReturn(&reset_cb_).Run(); + } + + state_ = kUninitialized; +} + +bool VpuVideoDecoder::HasAlpha() const { + return false; +} + +void VpuVideoDecoder::DecodeBuffer(const scoped_refptr<DecoderBuffer>& buffer) { + DCHECK(message_loop_->BelongsToCurrentThread()); + DCHECK_NE(state_, kUninitialized); + DCHECK_NE(state_, kDecodeFinished); + DCHECK_NE(state_, kError); + DCHECK(reset_cb_.is_null()); + DCHECK(!decode_cb_.is_null()); + DCHECK(buffer); + + // Transition to kDecodeFinished on the first end of stream buffer. + if (state_ == kNormal && buffer->end_of_stream()) { + state_ = kDecodeFinished; + base::ResetAndReturn(&decode_cb_).Run(kOk, VideoFrame::CreateEmptyFrame()); + return; + } + + scoped_refptr<VideoFrame> video_frame; + if (!VpuDecode(buffer, &video_frame)) { + state_ = kError; + base::ResetAndReturn(&decode_cb_).Run(kDecodeError, NULL); + return; + } + + // If we didn't get a frame we need more data. + if (!video_frame.get()) { + base::ResetAndReturn(&decode_cb_).Run(kNotEnoughData, NULL); + return; + } + + base::ResetAndReturn(&decode_cb_).Run(kOk, video_frame); +} + +bool VpuVideoDecoder::VpuDecode(const scoped_refptr<DecoderBuffer>& buffer, + scoped_refptr<VideoFrame>* video_frame) { + DCHECK(video_frame); + DCHECK(!buffer->end_of_stream()); + + int buffer_ret_code; + VpuBufferNode in_data; + VpuDecRetCode ret; + + memset(&in_data, 0, sizeof(in_data)); + in_data.pVirAddr = (unsigned char *)(buffer->data()); + in_data.nSize = buffer->data_size(); + + ret = VPU_DecDecodeBuf(internal->handle, &in_data, &buffer_ret_code); + if (ret != VPU_DEC_RET_SUCCESS) { + LOG(ERROR) << "Failed to decode frame: " << VpuStrerror(ret); + return false; + } + + VLOG(1) << "VPU_DecDecodeBuf buffer ret code is 0x" << std::hex << buffer_ret_code << std::dec; + + if (buffer_ret_code & VPU_DEC_INIT_OK) { + ret = VPU_DecGetInitialInfo(internal->handle, &(internal->init_info)); + if (ret != VPU_DEC_RET_SUCCESS) { + LOG(ERROR) << "Could not get init info: " << VpuStrerror(ret); + return false; + } + internal->framebuffers.init(internal->handle, internal->init_info); + } + + if (buffer_ret_code & VPU_DEC_FLUSH) { + ret = VPU_DecFlushAll(internal->handle); + if (ret != VPU_DEC_RET_SUCCESS) { + LOG(ERROR) << "Flushing VPU failed: " << VpuStrerror(ret); + return false; + } + + *video_frame = NULL; + + return true; + } + + if (buffer_ret_code & VPU_DEC_NO_ENOUGH_INBUF) { + LOG(INFO) << "Need more input"; + return true; + } + + if (buffer_ret_code & VPU_DEC_ONE_FRM_CONSUMED) { + VpuDecFrameLengthInfo dec_framelen_info; + + ret = VPU_DecGetConsumedFrameInfo(internal->handle, &dec_framelen_info); + if (ret != VPU_DEC_RET_SUCCESS) { + LOG(ERROR) << "Could not get information about consumed frame: " << VpuStrerror(ret); + } else { + LOG(INFO) << "One frame got consumed:" + << " framebuffer addr: 0x" << std::hex << uintptr_t(dec_framelen_info.pFrame) << std::dec + << " stuff length: " << dec_framelen_info.nStuffLength + << " frame length: " << dec_framelen_info.nFrameLength + ; + } + } + + if (buffer_ret_code & VPU_DEC_OUTPUT_DIS) { + VpuDecOutFrameInfo out_frame_info; + int64 timestamp = buffer->timestamp().InMicroseconds(); + + ret = VPU_DecGetOutputFrame(internal->handle, &out_frame_info); + if (ret != VPU_DEC_RET_SUCCESS) { + LOG(ERROR) << "Could not get decoded output frame: " << VpuStrerror(ret); + return false; + } + + LOG(INFO) << "Output frame:" + << " pic width: " << internal->init_info.nPicWidth + << " pic height: " << internal->init_info.nPicHeight + << " pic type: " << out_frame_info.ePicType + << " Y stride: " << out_frame_info.pDisplayFrameBuf->nStrideY + << " CbCr stride: " << out_frame_info.pDisplayFrameBuf->nStrideC + ; + + CopyVpuFramebufferTo(out_frame_info.pDisplayFrameBuf, video_frame, internal->init_info, config_); + (*video_frame)->SetTimestamp(base::TimeDelta::FromMicroseconds(timestamp)); + + ret = VPU_DecOutFrameDisplayed(internal->handle, out_frame_info.pDisplayFrameBuf); + if (ret != VPU_DEC_RET_SUCCESS) + LOG(ERROR) << "Clearing display framebuffer failed: " << VpuStrerror(ret); + } + else + *video_frame = NULL; + + return true; +} + +void VpuVideoDecoder::DoReset() { + DCHECK(decode_cb_.is_null()); + + state_ = kNormal; + reset_cb_.Run(); + reset_cb_.Reset(); +} + +void CopyVpuFramebufferTo(VpuFrameBuffer *framebuffer, scoped_refptr<VideoFrame>* video_frame, VpuDecInitInfo &init_info, const VideoDecoderConfig& config) { + CHECK(framebuffer); + + gfx::Size size(init_info.nPicWidth, init_info.nPicHeight); + + *video_frame = VideoFrame::CreateFrame( + config.format(), + size, + gfx::Rect(size), + config.natural_size(), + kNoTimestamp()); + + CopyYPlane(framebuffer->pbufVirtY, + framebuffer->nStrideY, + init_info.nPicHeight, + video_frame->get()); + if (config.format() == VideoFrame::I420) { + CopyUPlane(framebuffer->pbufVirtCb, + framebuffer->nStrideC, + init_info.nPicHeight / 2, + video_frame->get()); + CopyVPlane(framebuffer->pbufVirtCr, + framebuffer->nStrideC, + init_info.nPicHeight / 2, + video_frame->get()); + } else { /* YV12 and YV12A */ + /* U and V swapped */ + CopyUPlane(framebuffer->pbufVirtCb, + framebuffer->nStrideC, + init_info.nPicHeight / 2, + video_frame->get()); + CopyVPlane(framebuffer->pbufVirtCr, + framebuffer->nStrideC, + init_info.nPicHeight / 2, + video_frame->get()); + + if (config.format() == VideoFrame::YV12A) { + MakeOpaqueAPlane(framebuffer->nStrideY, + init_info.nPicHeight, + video_frame->get()); + } + } +} + + +} // namespace media diff --git a/media/filters/vpu_video_decoder.h b/media/filters/vpu_video_decoder.h new file mode 100644 index 0000000..d7016aa --- /dev/null +++ b/media/filters/vpu_video_decoder.h @@ -0,0 +1,74 @@ +#ifndef MEDIA_FILTERS_VPU_VIDEO_DECODER_H_ +#define MEDIA_FILTERS_VPU_VIDEO_DECODER_H_ + +#include "base/callback.h" +#include "base/memory/weak_ptr.h" +#include "media/base/demuxer_stream.h" +#include "media/base/video_decoder.h" +#include "media/base/video_decoder_config.h" +#include "media/base/video_frame.h" + +namespace base { +class MessageLoopProxy; +} + +namespace media { + +class MEDIA_EXPORT VpuVideoDecoder : public VideoDecoder { + public: + explicit VpuVideoDecoder( + const scoped_refptr<base::MessageLoopProxy>& message_loop); + virtual ~VpuVideoDecoder(); + + // VideoDecoder implementation. + virtual void Initialize(const VideoDecoderConfig& config, + const PipelineStatusCB& status_cb) OVERRIDE; + virtual void Decode(const scoped_refptr<DecoderBuffer>& buffer, + const DecodeCB& decode_cb) OVERRIDE; + virtual void Reset(const base::Closure& closure) OVERRIDE; + virtual void Stop(const base::Closure& closure) OVERRIDE; + virtual bool HasAlpha() const OVERRIDE; + + private: + enum DecoderState { + kUninitialized, + kNormal, + kFlushCodec, + kDecodeFinished, + kError + }; + + // Handles (re-)initializing the decoder with a (new) config. + // Returns true when initialization was successful. + bool ConfigureDecoder(const VideoDecoderConfig& config); + + bool OpenDecoder(const VideoDecoderConfig& config); + void CloseDecoder(); + + void DecodeBuffer(const scoped_refptr<DecoderBuffer>& buffer); + bool VpuDecode(const scoped_refptr<DecoderBuffer>& buffer, + scoped_refptr<VideoFrame>* video_frame); + + // Reset decoder and call |reset_cb_|. + void DoReset(); + + scoped_refptr<base::MessageLoopProxy> message_loop_; + base::WeakPtrFactory<VpuVideoDecoder> weak_factory_; + base::WeakPtr<VpuVideoDecoder> weak_this_; + + DecoderState state_; + + DecodeCB decode_cb_; + base::Closure reset_cb_; + + VideoDecoderConfig config_; + + struct Internal; + Internal *internal; + + DISALLOW_COPY_AND_ASSIGN(VpuVideoDecoder); +}; + +} // namespace media + +#endif // MEDIA_FILTERS_VPU_VIDEO_DECODER_H_ diff --git a/media/media.gyp b/media/media.gyp index a25571d..b12d386 100644 --- a/media/media.gyp +++ b/media/media.gyp @@ -11,6 +11,7 @@ # (DT_NEEDED) instead of using dlopen. This helps with automated # detection of ABI mismatches and prevents silent errors. 'linux_link_pulseaudio%': 0, + 'media_use_imxvpu%': 1, 'conditions': [ ['OS=="android"', { # Android doesn't use ffmpeg. @@ -377,6 +378,10 @@ 'filters/video_frame_stream.h', 'filters/video_renderer_base.cc', 'filters/video_renderer_base.h', + 'filters/vpu_framebuffers.cc', + 'filters/vpu_framebuffers.h', + 'filters/vpu_video_decoder.cc', + 'filters/vpu_video_decoder.h', 'filters/vpx_video_decoder.cc', 'filters/vpx_video_decoder.h', 'filters/wsola_internals.cc', @@ -592,6 +597,29 @@ 'DISABLE_USER_INPUT_MONITOR', ], }], + ['media_use_imxvpu==1', { + 'cflags': [ + '<!@(<(pkg-config) --cflags libfslvpuwrap)', + ], + 'link_settings': { + 'libraries': [ + '<!@(<(pkg-config) --libs libfslvpuwrap)', + ], + }, + }, { # media_use_imxvpu==0 + 'direct_dependent_settings': { + 'defines': [ + 'MEDIA_DISABLE_IMXVPU', + ], + }, + # Exclude the VPU sources. + 'sources!': [ + 'filters/vpu_framebuffers.cc', + 'filters/vpu_framebuffers.h', + 'filters/vpu_video_decoder.cc', + 'filters/vpu_video_decoder.h', + ], + }], ['use_cras==1', { 'cflags': [ '<!@(<(pkg-config) --cflags libcras)', ^ permalink raw reply related [flat|nested] 37+ messages in thread
* Re: Chromium acceleration 2014-03-20 23:19 ` Carlos Rafael Giani @ 2014-03-21 12:21 ` Dmitriy B. 2014-04-01 19:22 ` Eric Nelson 1 sibling, 0 replies; 37+ messages in thread From: Dmitriy B. @ 2014-03-21 12:21 UTC (permalink / raw) To: meta-freescale [-- Attachment #1: Type: text/plain, Size: 513 bytes --] > > 3. Chromium tried to load libEGL with dlopen() , which caused problems, > because with the Vivante libraries, libEGL also needs libGAL. Usually, > build scripts just add -lEGL -lGAL to the linker line. > Vivante finally fixed that in the latest EGL binaries release so now you dont need to manually add libGAL everytime. libEGL/GLESv1-2/GL now depend on libGAL properly (you can check that with ldd). Looking forward to test Chromium with your imx6 patches soon! Best Regards, Dmitriy Beykun [-- Attachment #2: Type: text/html, Size: 833 bytes --] ^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: Chromium acceleration 2014-03-20 23:19 ` Carlos Rafael Giani 2014-03-21 12:21 ` Dmitriy B. @ 2014-04-01 19:22 ` Eric Nelson 2014-04-02 10:21 ` Carlos Rafael Giani ` (2 more replies) 1 sibling, 3 replies; 37+ messages in thread From: Eric Nelson @ 2014-04-01 19:22 UTC (permalink / raw) To: Carlos Rafael Giani, Christian Betz, meta-freescale [-- Attachment #1: Type: text/plain, Size: 2727 bytes --] Thanks again Carlos, On 03/20/2014 04:19 PM, Carlos Rafael Giani wrote: > > <snip> > > Back then we needed some hw decoding quickly, so we did not look further > into this, since we had spent a lot of time getting the 2D acceleration > stable already. I could only briefly look at the exynos accelerator > code, but it does look like the right direction, although the VPU uses > physical addresses directly instead of dmabuf FDs. I am currently > writing a frontend for the libfslvpuwrap, which takes care of certain > complexities (like being able to pass userdata pointers to frames, to > make it possible to associate input and output frames, which is > essential for correct timestamping, especially when things like h264 > frame reordering are active). This frontend will hide these things in a > future gstreamer-imx release to make the decoder code clearer and easier > to maintain, and is intended to be reusable, for example for Chromium > integration, or XBMC. Beyond that, my patches are probably not that > helpful anymore, since they were based on the vpx decoder way of > decoding, and I agree that the exynos code is a better starting point. > Nevertheless, I attached the patch. Keep in mind that it is very basic, > old, and wasn't further developed on because it was "good enough" for > the project. > > But here are some additional notes from our efforts to accelerate > Chromium on imx6 (keep in mind these apply to version 32.0.1664.3 ) : > > 1. We started the google-chrome binary with these switches: > --ignore-gpu-blacklist --enable-gpu --use-gl=egl > --enable-accelerated-2d-canvas > > 2. To make building Chromium easier, we switched to component build (by > default, it is all linked into one enormous binary). I attached a patch > that was necessary to fix some minor issues. Perhaps it is not necessary > anymore. > > 3. Chromium tried to load libEGL with dlopen() , which caused problems, > because with the Vivante libraries, libEGL also needs libGAL. Usually, > build scripts just add -lEGL -lGAL to the linker line. With dlopen() > this wasn't possible of course. We patched the gyp scripts to link > against this libraries during building instead. I attached this patch. > It is really a hack, because it circumvents the sandboxing process (this > is why Chromium loads EGL and GLESv2 with dlopen() ). > Mahyar updated these patches to apply against the chromium-35.0.1883.0 build currently in meta-browser. Additional notes to follow, but this appears to achieve HTML5 video against Webm/Ogg videos when chromium is started with these command line arguments: --ignore-gpu-blacklist --enable-gpu --usegl-egl Regards, Eric [-- Attachment #2: 0001-Modified-gl.gyp-to-link-libEGL-and-libGAL-at-build-t.patch --] [-- Type: text/x-diff, Size: 1025 bytes --] From 03924737a9378db934da9355bb38c916b5e3fa45 Mon Sep 17 00:00:00 2001 From: Eric Nelson <eric.nelson@boundarydevices.com> Date: Sun, 23 Mar 2014 07:10:36 -0700 Subject: [PATCH 1/3] Modified gl.gyp to link libEGL and libGAL at build time Signed-off-by: Eric Nelson <eric.nelson@boundarydevices.com> --- ui/gl/gl.gyp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/ui/gl/gl.gyp b/ui/gl/gl.gyp index 2ec6d76..f7ee1a4 100644 --- a/ui/gl/gl.gyp +++ b/ui/gl/gl.gyp @@ -123,6 +123,12 @@ '<(gl_binding_output_dir)/gl_bindings_autogen_osmesa.cc', '<(gl_binding_output_dir)/gl_bindings_autogen_osmesa.h', ], + 'link_settings': { + 'libraries': [ + '-lEGL', + '-lGAL', + ], + }, # hard_dependency is necessary for this target because it has actions # that generate header files included by dependent targets. The header # files must be generated before the dependents are compiled. The usual -- 1.8.3.2 [-- Attachment #3: 0002-Added-hardware-accelerated-decoding-with-the-i.MX-VP.patch --] [-- Type: text/x-diff, Size: 29768 bytes --] From 44ccb7f8a920389897e60e30e3f0ee3319f7bf7d Mon Sep 17 00:00:00 2001 From: Eric Nelson <eric.nelson@boundarydevices.com> Date: Sun, 23 Mar 2014 07:17:08 -0700 Subject: [PATCH 2/3] Added hardware accelerated decoding with the i.MX VPU --- content/renderer/media/webmediaplayer_impl.cc | 5 + media/filters/vpu_framebuffers.cc | 106 +++++ media/filters/vpu_framebuffers.h | 36 ++ media/filters/vpu_video_decoder.cc | 614 ++++++++++++++++++++++++++ media/filters/vpu_video_decoder.h | 74 ++++ media/media.gyp | 28 ++ 6 files changed, 863 insertions(+) create mode 100644 media/filters/vpu_framebuffers.cc create mode 100644 media/filters/vpu_framebuffers.h create mode 100644 media/filters/vpu_video_decoder.cc create mode 100644 media/filters/vpu_video_decoder.h diff --git a/content/renderer/media/webmediaplayer_impl.cc b/content/renderer/media/webmediaplayer_impl.cc index b7094f6..7ac7318 100644 --- a/content/renderer/media/webmediaplayer_impl.cc +++ b/content/renderer/media/webmediaplayer_impl.cc @@ -57,6 +57,7 @@ #include "media/filters/opus_audio_decoder.h" #include "media/filters/video_renderer_impl.h" #include "media/filters/vpx_video_decoder.h" +#include "media/filters/vpu_video_decoder.h" #include "third_party/WebKit/public/platform/WebContentDecryptionModule.h" #include "third_party/WebKit/public/platform/WebMediaSource.h" #include "third_party/WebKit/public/platform/WebRect.h" @@ -1187,6 +1188,10 @@ void WebMediaPlayerImpl::StartPipeline() { new media::GpuVideoDecoder(gpu_factories_, media_log_)); } +#if !defined(MEDIA_DISABLE_IMXVPU) + video_decoders.push_back(new media::VpuVideoDecoder(media_loop_)); +#endif // !defined(MEDIA_DISABLE_IMXVPU) + #if !defined(MEDIA_DISABLE_LIBVPX) video_decoders.push_back(new media::VpxVideoDecoder(media_loop_)); #endif // !defined(MEDIA_DISABLE_LIBVPX) diff --git a/media/filters/vpu_framebuffers.cc b/media/filters/vpu_framebuffers.cc new file mode 100644 index 0000000..fce43fc --- /dev/null +++ b/media/filters/vpu_framebuffers.cc @@ -0,0 +1,106 @@ +#include <string.h> +#include <stdint.h> +#include "vpu_framebuffers.h" +#include "base/logging.h" + + +#define ALIGN_VAL_TO(LENGTH, ALIGN_SIZE) ( ((uintptr_t)((LENGTH) + (ALIGN_SIZE) - 1) / (ALIGN_SIZE)) * (ALIGN_SIZE) ) +#define FRAME_ALIGN 16 + + +namespace media { + + +VPUFramebuffers::VPUFramebuffers() { +} + + +void VPUFramebuffers::init(VpuDecHandle handle, VpuDecInitInfo const &init_info) { + framebuffers.resize(init_info.nMinFrameBufferCount); + + y_stride = ALIGN_VAL_TO(init_info.nPicWidth, FRAME_ALIGN); + if (init_info.nInterlace) + y_size = y_stride * ALIGN_VAL_TO(init_info.nPicHeight, (2 * FRAME_ALIGN)); + else + y_size = y_stride * ALIGN_VAL_TO(init_info.nPicHeight, FRAME_ALIGN); + + uv_stride = y_stride / 2; + u_size = v_size = mv_size = y_size / 4; + + int alignment = init_info.nAddressAlignment; + if (alignment > 1) + { + y_size = ALIGN_VAL_TO(y_size, alignment); + u_size = ALIGN_VAL_TO(u_size, alignment); + v_size = ALIGN_VAL_TO(v_size, alignment); + mv_size = ALIGN_VAL_TO(mv_size, alignment); + } + + pic_width = init_info.nPicWidth; + pic_height = init_info.nPicHeight; + + total_size = y_size + u_size + v_size + mv_size + alignment; + + LOG(INFO) << "Num VPU framebuffers: " << framebuffers.size(); + LOG(INFO) << "VPU framebuffer memory block size:" + << " total: " << total_size + << " Y " << y_size + << " U: " << u_size + << " V: " << v_size + << " Mv: " << mv_size + << " alignment: " << alignment + ; + + for (Framebuffers::iterator iter = framebuffers.begin(); iter != framebuffers.end(); ++iter) { + unsigned char *virt_ptr, *phys_ptr; + + VpuFrameBuffer &framebuffer = *iter; + + VpuMemDesc mem_desc; + memset(&mem_desc, 0, sizeof(VpuMemDesc)); + mem_desc.nSize = total_size; + VPU_DecGetMem(&mem_desc); + phys_mem_blocks.push_back(mem_desc); + + virt_ptr = (unsigned char*)(mem_desc.nVirtAddr); + phys_ptr = (unsigned char*)(mem_desc.nPhyAddr); + + if (alignment > 1) { + phys_ptr = (unsigned char*)ALIGN_VAL_TO(phys_ptr, alignment); + virt_ptr = (unsigned char*)ALIGN_VAL_TO(virt_ptr, alignment); + } + + framebuffer.nStrideY = y_stride; + framebuffer.nStrideC = uv_stride; + + /* fill phy addr*/ + framebuffer.pbufY = phys_ptr; + framebuffer.pbufCb = phys_ptr + y_size; + framebuffer.pbufCr = phys_ptr + y_size + u_size; + framebuffer.pbufMvCol = phys_ptr + y_size + u_size + v_size; + + /* fill virt addr */ + framebuffer.pbufVirtY = virt_ptr; + framebuffer.pbufVirtCb = virt_ptr + y_size; + framebuffer.pbufVirtCr = virt_ptr + y_size + u_size; + framebuffer.pbufVirtMvCol = virt_ptr + y_size + u_size + v_size; + + framebuffer.pbufY_tilebot = 0; + framebuffer.pbufCb_tilebot = 0; + framebuffer.pbufVirtY_tilebot = 0; + framebuffer.pbufVirtCb_tilebot = 0; + } + + VPU_DecRegisterFrameBuffer(handle, &(framebuffers[0]), framebuffers.size()); +} + + +VPUFramebuffers::~VPUFramebuffers() { + LOG(INFO) << "Freeing VPU framebuffer memory"; + for (PhysMemBlocks::iterator iter = phys_mem_blocks.begin(); iter != phys_mem_blocks.end(); ++iter) + VPU_DecFreeMem(&(*iter)); +} + + +} + diff --git a/media/filters/vpu_framebuffers.h b/media/filters/vpu_framebuffers.h new file mode 100644 index 0000000..bb9b021 --- /dev/null +++ b/media/filters/vpu_framebuffers.h @@ -0,0 +1,36 @@ +#ifndef MEDIA_FILTERS_VPU_FRAMEBUFFERS_H_ +#define MEDIA_FILTERS_VPU_FRAMEBUFFERS_H_ + +#include <list> +#include <vector> +#include <vpu_wrapper.h> + + +namespace media { + + +class VPUFramebuffers +{ +public: + explicit VPUFramebuffers(); + ~VPUFramebuffers(); + + void init(VpuDecHandle handle, VpuDecInitInfo const &init_info); + +private: + typedef std::vector < VpuFrameBuffer > Framebuffers; + typedef std::list < VpuMemDesc > PhysMemBlocks; + + PhysMemBlocks phys_mem_blocks; + Framebuffers framebuffers; + int y_stride, uv_stride; + int y_size, u_size, v_size, mv_size; + int total_size; + unsigned int pic_width, pic_height; +}; + + +} + + +#endif diff --git a/media/filters/vpu_video_decoder.cc b/media/filters/vpu_video_decoder.cc new file mode 100644 index 0000000..396d4f1 --- /dev/null +++ b/media/filters/vpu_video_decoder.cc @@ -0,0 +1,614 @@ +#include <list> +#include <vector> +#include <stddef.h> +#include <stdint.h> +#include <algorithm> +#include <string> + +#include <string.h> + +#include "media/filters/vpu_video_decoder.h" + +#include "base/bind.h" +#include "base/callback_helpers.h" +#include "base/command_line.h" +#include "base/location.h" +#include "base/logging.h" +#include "base/synchronization/lock.h" +#include "base/message_loop/message_loop_proxy.h" +#include "base/strings/string_number_conversions.h" +#include "base/sys_byteorder.h" +#include "media/base/bind_to_loop.h" +#include "media/base/decoder_buffer.h" +#include "media/base/demuxer_stream.h" +#include "media/base/media_switches.h" +#include "media/base/pipeline.h" +#include "media/base/video_decoder_config.h" +#include "media/base/video_frame.h" +#include "media/base/video_util.h" + +#include "media/filters/vpu_framebuffers.h" + +#include <vpu_wrapper.h> + + +#define ALIGN_VAL_TO(LENGTH, ALIGN_SIZE) ( ((uintptr_t)((LENGTH) + (ALIGN_SIZE) - 1) / (ALIGN_SIZE)) * (ALIGN_SIZE) ) + + + +namespace media { + + +namespace { + + +char const *VpuStrerror(VpuDecRetCode const code) { + switch (code) { + case VPU_DEC_RET_SUCCESS: return "success"; + case VPU_DEC_RET_FAILURE: return "failure"; + case VPU_DEC_RET_INVALID_PARAM: return "invalid param"; + case VPU_DEC_RET_INVALID_HANDLE: return "invalid handle"; + case VPU_DEC_RET_INVALID_FRAME_BUFFER: return "invalid frame buffer"; + case VPU_DEC_RET_INSUFFICIENT_FRAME_BUFFERS: return "insufficient frame buffers"; + case VPU_DEC_RET_INVALID_STRIDE: return "invalid stride"; + case VPU_DEC_RET_WRONG_CALL_SEQUENCE: return "wrong call sequence"; + case VPU_DEC_RET_FAILURE_TIMEOUT: return "failure timeout"; + default: + return NULL; + } +} + + +long inst_count = 0; +base::Lock vpu_load_lock; + + +void LoadDecoder() { + VpuDecRetCode ret; + + base::AutoLock alock(vpu_load_lock); + + if (inst_count == 0) { + ret = VPU_DecLoad(); + if (ret != VPU_DEC_RET_SUCCESS) { + LOG(ERROR) << "VPU loading failed: " << VpuStrerror(ret); + return; + } + + } + + ++inst_count; + + if (inst_count == 1) { + VpuVersionInfo version; + VpuWrapperVersionInfo wrapper_version; + + ret = VPU_DecGetVersionInfo(&version); + if (ret != VPU_DEC_RET_SUCCESS) { + LOG(ERROR) << "Getting version info failed: " << VpuStrerror(ret); + return; + } + + ret = VPU_DecGetWrapperVersionInfo(&wrapper_version); + if (ret != VPU_DEC_RET_SUCCESS) { + LOG(ERROR) << "Getting wrapper version info failed: " << VpuStrerror(ret); + return; + } + + LOG(INFO) << "VPU Loaded"; + LOG(INFO) << "VPU firmware version " << version.nFwMajor << "." << version.nFwMinor << "." << version.nFwRelease << "_r" << version.nFwCode; + LOG(INFO) << "VPU library version " << version.nLibMajor << "." << version.nLibMinor << "." << version.nLibRelease; + LOG(INFO) << "VPU wrapper version " << wrapper_version.nMajor << "." << wrapper_version.nMinor << "." << wrapper_version.nRelease << " " << wrapper_version.pBinary; + } +} + + +void UnloadDecoder() { + base::AutoLock alock(vpu_load_lock); + + if (inst_count == 0) + return; + + --inst_count; + + if (inst_count == 0) + VPU_DecUnLoad(); +} + + +} + + +struct VpuVideoDecoder::Internal +{ + typedef std::vector < uint8_t > VirtMemBlock; + typedef std::list < VirtMemBlock > VirtMemBlocks; + + typedef std::list < VpuMemDesc > PhysMemBlocks; + + VpuDecHandle handle; + + VpuDecInitInfo init_info; + VpuMemInfo mem_info; + + bool vpu_opened; + + VirtMemBlocks virt_mem_blocks; + PhysMemBlocks phys_mem_blocks; + + VPUFramebuffers framebuffers; + + Internal() + : vpu_opened(false) + { + } + + ~Internal() + { + FreeMemBlocks(); + } + + bool AllocMemBlocks() + { + VpuDecRetCode ret; + + memset(&mem_info, 0, sizeof(VpuMemInfo)); + ret = VPU_DecQueryMem(&mem_info); + if (ret != VPU_DEC_RET_SUCCESS) { + LOG(ERROR) << "Could not get VPU memory information: " << VpuStrerror(ret); + return false; + } + + for (int i = 0; i < mem_info.nSubBlockNum; ++i) + { + int size = mem_info.MemSubBlock[i].nAlignment + mem_info.MemSubBlock[i].nSize; + + LOG(INFO) << "Sub block " << i << " type: " << ((mem_info.MemSubBlock[i].MemType == VPU_MEM_VIRT) ? "virtual" : "phys") << " size: " << size; + + if (mem_info.MemSubBlock[i].MemType == VPU_MEM_VIRT) + { + unsigned char *virt_ptr; + virt_mem_blocks.push_back(VirtMemBlock()); + VirtMemBlock &blk = virt_mem_blocks.back(); + blk.resize(size); + virt_ptr = reinterpret_cast < unsigned char* > (&blk[0]); + + mem_info.MemSubBlock[i].pVirtAddr = (unsigned char *)ALIGN_VAL_TO(virt_ptr, mem_info.MemSubBlock[i].nAlignment); + } + else if (mem_info.MemSubBlock[i].MemType == VPU_MEM_PHY) + { + VpuMemDesc mem_desc; + memset(&mem_desc, 0, sizeof(VpuMemDesc)); + mem_desc.nSize = size; + if (VPU_DecGetMem(&mem_desc) != VPU_DEC_RET_SUCCESS) { + LOG(ERROR) << "Unable to allocate " << size << " bytes of physical memory"; + return false; + } + + phys_mem_blocks.push_back(mem_desc); + + mem_info.MemSubBlock[i].pVirtAddr = (unsigned char *)ALIGN_VAL_TO((unsigned char*)(mem_desc.nVirtAddr), mem_info.MemSubBlock[i].nAlignment); + mem_info.MemSubBlock[i].pPhyAddr = (unsigned char *)ALIGN_VAL_TO((unsigned char*)(mem_desc.nPhyAddr), mem_info.MemSubBlock[i].nAlignment); + } + else + LOG(WARNING) << "Sub block " << i << " type is unknown - skipping"; + } + + LOG(INFO) << "VPU memory blocks allocated"; + + return true; + } + + void FreeMemBlocks() + { + LOG(INFO) << "Freeing VPU memory blocks"; + + for (PhysMemBlocks::iterator iter = phys_mem_blocks.begin(); iter != phys_mem_blocks.end(); ++iter) + VPU_DecFreeMem(&(*iter)); + } +}; + + + +void CopyVpuFramebufferTo(VpuFrameBuffer *framebuffer, scoped_refptr<VideoFrame>* video_frame, VpuDecInitInfo &init_info, const VideoDecoderConfig& config); + + + + +VpuVideoDecoder::VpuVideoDecoder( + const scoped_refptr<base::MessageLoopProxy>& message_loop) + : message_loop_(message_loop), + weak_factory_(this), + state_(kUninitialized) { + LoadDecoder(); + internal = new Internal; +} + +VpuVideoDecoder::~VpuVideoDecoder() { + DCHECK_EQ(kUninitialized, state_); + CloseDecoder(); + delete internal; + UnloadDecoder(); +} + +void VpuVideoDecoder::Initialize(const VideoDecoderConfig& config, + const PipelineStatusCB& status_cb) { + DCHECK(message_loop_->BelongsToCurrentThread()); + DCHECK(config.IsValidConfig()); + DCHECK(!config.is_encrypted()); + DCHECK(decode_cb_.is_null()); + DCHECK(reset_cb_.is_null()); + + weak_this_ = weak_factory_.GetWeakPtr(); + + if (!internal->AllocMemBlocks()) { + status_cb.Run(PIPELINE_ERROR_INITIALIZATION_FAILED); + return; + } + + if (!ConfigureDecoder(config)) { + status_cb.Run(DECODER_ERROR_NOT_SUPPORTED); + return; + } + + // Success! + LOG(INFO) << "VPU decoder initialization succeeded"; + config_ = config; + state_ = kNormal; + status_cb.Run(PIPELINE_OK); +} + +bool VpuVideoDecoder::ConfigureDecoder(const VideoDecoderConfig& config) { + bool can_handle = false; + + if ((config.format() == VideoFrame::YV12) || (config.format() == VideoFrame::YV12A) || (config.format() == VideoFrame::I420)) { + switch (config.codec()) { + case kCodecH264: + case kCodecVC1: + case kCodecMPEG2: + case kCodecMPEG4: + case kCodecVP8: + can_handle = true; + default: + break; + } + } + + if (!can_handle) { + LOG(INFO) << "Cannot handle video config: " << config.AsHumanReadableString(); + return false; + } + + CloseDecoder(); + return OpenDecoder(config); +} + +bool VpuVideoDecoder::OpenDecoder(const VideoDecoderConfig& config) { + if (internal->vpu_opened) + return true; + + VpuDecOpenParam open_param; + VpuDecRetCode ret; + + memset(&open_param, 0, sizeof(open_param)); + + switch (config.codec()) + { + case kCodecH264: + open_param.CodecFormat = VPU_V_AVC; + open_param.nReorderEnable = 1; + LOG(INFO) << "Setting h.264 as stream format"; + break; + case kCodecVC1: + open_param.CodecFormat = VPU_V_VC1_AP; + LOG(INFO) << "Setting VC1 as stream format"; + break; + case kCodecMPEG2: + open_param.CodecFormat = VPU_V_MPEG2; + LOG(INFO) << "Setting MPEG-2 as stream format"; + break; + case kCodecMPEG4: + open_param.CodecFormat = VPU_V_MPEG4; + LOG(INFO) << "Setting MPEG-4 as stream format"; + break; + case kCodecVP8: + open_param.CodecFormat = VPU_V_VP8; + LOG(INFO) << "Setting VP8 as stream format"; + break; + default: + LOG(ERROR) << "Could not set unknown stream format"; + break; + } + + open_param.nChromaInterleave = 0; + open_param.nMapType = 0; + open_param.nTiled2LinearEnable = 0; + open_param.nEnableFileMode = 0; + open_param.nPicWidth = config.coded_size().width(); + open_param.nPicHeight = config.coded_size().height(); + + ret = VPU_DecOpen(&(internal->handle), &open_param, &(internal->mem_info)); + if (ret != VPU_DEC_RET_SUCCESS) { + LOG(ERROR) << "Opening new VPU handle failed: " << VpuStrerror(ret); + return false; + } + + int config_param; + + config_param = VPU_DEC_SKIPNONE; + ret = VPU_DecConfig(internal->handle, VPU_DEC_CONF_SKIPMODE, &config_param); + if (ret != VPU_DEC_RET_SUCCESS) { + LOG(ERROR) << "Could not configure skip mode: " << VpuStrerror(ret); + return false; + } + + config_param = 0; + ret = VPU_DecConfig(internal->handle, VPU_DEC_CONF_BUFDELAY, &config_param); + if (ret != VPU_DEC_RET_SUCCESS) { + LOG(ERROR) << "Could not configure buffer delay: " << VpuStrerror(ret); + return false; + } + + config_param = VPU_DEC_IN_NORMAL; + ret = VPU_DecConfig(internal->handle, VPU_DEC_CONF_INPUTTYPE, &config_param); + if (ret != VPU_DEC_RET_SUCCESS) { + LOG(ERROR) << "Could not configure input type: " << VpuStrerror(ret); + return false; + } + + internal->vpu_opened = true; + + return true; +} + +void VpuVideoDecoder::CloseDecoder() { + VpuDecRetCode ret; + + if (!(internal->vpu_opened)) + return; + + ret = VPU_DecFlushAll(internal->handle); + if (ret != VPU_DEC_RET_SUCCESS) + LOG(ERROR) << "Flushing decoder failed: " << VpuStrerror(ret); + VPU_DecClose(internal->handle); + if (ret != VPU_DEC_RET_SUCCESS) + LOG(ERROR) << "Closing decoder failed: " << VpuStrerror(ret); + + internal->vpu_opened = false; +} + +void VpuVideoDecoder::Decode(const scoped_refptr<DecoderBuffer>& buffer, + const DecodeCB& decode_cb) { + DCHECK(message_loop_->BelongsToCurrentThread()); + DCHECK(!decode_cb.is_null()); + CHECK_NE(state_, kUninitialized); + CHECK(decode_cb_.is_null()) << "Overlapping decodes are not supported."; + + decode_cb_ = BindToCurrentLoop(decode_cb); + + if (state_ == kError) { + base::ResetAndReturn(&decode_cb_).Run(kDecodeError, NULL); + return; + } + + // Return empty frames if decoding has finished. + if (state_ == kDecodeFinished) { + base::ResetAndReturn(&decode_cb_).Run(kOk, VideoFrame::CreateEmptyFrame()); + return; + } + + DecodeBuffer(buffer); +} + +void VpuVideoDecoder::Reset(const base::Closure& closure) { + DCHECK(message_loop_->BelongsToCurrentThread()); + DCHECK(reset_cb_.is_null()); + reset_cb_ = BindToCurrentLoop(closure); + + // Defer the reset if a decode is pending. + if (!decode_cb_.is_null()) + return; + + DoReset(); +} + +void VpuVideoDecoder::Stop(const base::Closure& closure) { + DCHECK(message_loop_->BelongsToCurrentThread()); + base::ScopedClosureRunner runner(BindToCurrentLoop(closure)); + + if (state_ == kUninitialized) + return; + + if (!decode_cb_.is_null()) { + base::ResetAndReturn(&decode_cb_).Run(kOk, NULL); + // Reset is pending only when decode is pending. + if (!reset_cb_.is_null()) + base::ResetAndReturn(&reset_cb_).Run(); + } + + state_ = kUninitialized; +} + +bool VpuVideoDecoder::HasAlpha() const { + return false; +} + +void VpuVideoDecoder::DecodeBuffer(const scoped_refptr<DecoderBuffer>& buffer) { + DCHECK(message_loop_->BelongsToCurrentThread()); + DCHECK_NE(state_, kUninitialized); + DCHECK_NE(state_, kDecodeFinished); + DCHECK_NE(state_, kError); + DCHECK(reset_cb_.is_null()); + DCHECK(!decode_cb_.is_null()); + DCHECK(buffer); + + // Transition to kDecodeFinished on the first end of stream buffer. + if (state_ == kNormal && buffer->end_of_stream()) { + state_ = kDecodeFinished; + base::ResetAndReturn(&decode_cb_).Run(kOk, VideoFrame::CreateEmptyFrame()); + return; + } + + scoped_refptr<VideoFrame> video_frame; + if (!VpuDecode(buffer, &video_frame)) { + state_ = kError; + base::ResetAndReturn(&decode_cb_).Run(kDecodeError, NULL); + return; + } + + // If we didn't get a frame we need more data. + if (!video_frame.get()) { + base::ResetAndReturn(&decode_cb_).Run(kNotEnoughData, NULL); + return; + } + + base::ResetAndReturn(&decode_cb_).Run(kOk, video_frame); +} + +bool VpuVideoDecoder::VpuDecode(const scoped_refptr<DecoderBuffer>& buffer, + scoped_refptr<VideoFrame>* video_frame) { + DCHECK(video_frame); + DCHECK(!buffer->end_of_stream()); + + int buffer_ret_code; + VpuBufferNode in_data; + VpuDecRetCode ret; + + memset(&in_data, 0, sizeof(in_data)); + in_data.pVirAddr = (unsigned char *)(buffer->data()); + in_data.nSize = buffer->data_size(); + + ret = VPU_DecDecodeBuf(internal->handle, &in_data, &buffer_ret_code); + if (ret != VPU_DEC_RET_SUCCESS) { + LOG(ERROR) << "Failed to decode frame: " << VpuStrerror(ret); + return false; + } + + VLOG(1) << "VPU_DecDecodeBuf buffer ret code is 0x" << std::hex << buffer_ret_code << std::dec; + + if (buffer_ret_code & VPU_DEC_INIT_OK) { + ret = VPU_DecGetInitialInfo(internal->handle, &(internal->init_info)); + if (ret != VPU_DEC_RET_SUCCESS) { + LOG(ERROR) << "Could not get init info: " << VpuStrerror(ret); + return false; + } + internal->framebuffers.init(internal->handle, internal->init_info); + } + + if (buffer_ret_code & VPU_DEC_FLUSH) { + ret = VPU_DecFlushAll(internal->handle); + if (ret != VPU_DEC_RET_SUCCESS) { + LOG(ERROR) << "Flushing VPU failed: " << VpuStrerror(ret); + return false; + } + + *video_frame = NULL; + + return true; + } + + if (buffer_ret_code & VPU_DEC_NO_ENOUGH_INBUF) { + LOG(INFO) << "Need more input"; + return true; + } + + if (buffer_ret_code & VPU_DEC_ONE_FRM_CONSUMED) { + VpuDecFrameLengthInfo dec_framelen_info; + + ret = VPU_DecGetConsumedFrameInfo(internal->handle, &dec_framelen_info); + if (ret != VPU_DEC_RET_SUCCESS) { + LOG(ERROR) << "Could not get information about consumed frame: " << VpuStrerror(ret); + } else { + LOG(INFO) << "One frame got consumed:" + << " framebuffer addr: 0x" << std::hex << uintptr_t(dec_framelen_info.pFrame) << std::dec + << " stuff length: " << dec_framelen_info.nStuffLength + << " frame length: " << dec_framelen_info.nFrameLength + ; + } + } + + if (buffer_ret_code & VPU_DEC_OUTPUT_DIS) { + VpuDecOutFrameInfo out_frame_info; + int64 timestamp = buffer->timestamp().InMicroseconds(); + + ret = VPU_DecGetOutputFrame(internal->handle, &out_frame_info); + if (ret != VPU_DEC_RET_SUCCESS) { + LOG(ERROR) << "Could not get decoded output frame: " << VpuStrerror(ret); + return false; + } + + LOG(INFO) << "Output frame:" + << " pic width: " << internal->init_info.nPicWidth + << " pic height: " << internal->init_info.nPicHeight + << " pic type: " << out_frame_info.ePicType + << " Y stride: " << out_frame_info.pDisplayFrameBuf->nStrideY + << " CbCr stride: " << out_frame_info.pDisplayFrameBuf->nStrideC + ; + + CopyVpuFramebufferTo(out_frame_info.pDisplayFrameBuf, video_frame, internal->init_info, config_); + (*video_frame)->SetTimestamp(base::TimeDelta::FromMicroseconds(timestamp)); + + ret = VPU_DecOutFrameDisplayed(internal->handle, out_frame_info.pDisplayFrameBuf); + if (ret != VPU_DEC_RET_SUCCESS) + LOG(ERROR) << "Clearing display framebuffer failed: " << VpuStrerror(ret); + } + else + *video_frame = NULL; + + return true; +} + +void VpuVideoDecoder::DoReset() { + DCHECK(decode_cb_.is_null()); + + state_ = kNormal; + reset_cb_.Run(); + reset_cb_.Reset(); +} + +void CopyVpuFramebufferTo(VpuFrameBuffer *framebuffer, scoped_refptr<VideoFrame>* video_frame, VpuDecInitInfo &init_info, const VideoDecoderConfig& config) { + CHECK(framebuffer); + + gfx::Size size(init_info.nPicWidth, init_info.nPicHeight); + + *video_frame = VideoFrame::CreateFrame( + config.format(), + size, + gfx::Rect(size), + config.natural_size(), + kNoTimestamp()); + + CopyYPlane(framebuffer->pbufVirtY, + framebuffer->nStrideY, + init_info.nPicHeight, + video_frame->get()); + if (config.format() == VideoFrame::I420) { + CopyUPlane(framebuffer->pbufVirtCb, + framebuffer->nStrideC, + init_info.nPicHeight / 2, + video_frame->get()); + CopyVPlane(framebuffer->pbufVirtCr, + framebuffer->nStrideC, + init_info.nPicHeight / 2, + video_frame->get()); + } else { /* YV12 and YV12A */ + /* U and V swapped */ + CopyUPlane(framebuffer->pbufVirtCb, + framebuffer->nStrideC, + init_info.nPicHeight / 2, + video_frame->get()); + CopyVPlane(framebuffer->pbufVirtCr, + framebuffer->nStrideC, + init_info.nPicHeight / 2, + video_frame->get()); + + if (config.format() == VideoFrame::YV12A) { + MakeOpaqueAPlane(framebuffer->nStrideY, + init_info.nPicHeight, + video_frame->get()); + } + } +} + + +} // namespace media diff --git a/media/filters/vpu_video_decoder.h b/media/filters/vpu_video_decoder.h new file mode 100644 index 0000000..d7016aa --- /dev/null +++ b/media/filters/vpu_video_decoder.h @@ -0,0 +1,74 @@ +#ifndef MEDIA_FILTERS_VPU_VIDEO_DECODER_H_ +#define MEDIA_FILTERS_VPU_VIDEO_DECODER_H_ + +#include "base/callback.h" +#include "base/memory/weak_ptr.h" +#include "media/base/demuxer_stream.h" +#include "media/base/video_decoder.h" +#include "media/base/video_decoder_config.h" +#include "media/base/video_frame.h" + +namespace base { +class MessageLoopProxy; +} + +namespace media { + +class MEDIA_EXPORT VpuVideoDecoder : public VideoDecoder { + public: + explicit VpuVideoDecoder( + const scoped_refptr<base::MessageLoopProxy>& message_loop); + virtual ~VpuVideoDecoder(); + + // VideoDecoder implementation. + virtual void Initialize(const VideoDecoderConfig& config, + const PipelineStatusCB& status_cb) OVERRIDE; + virtual void Decode(const scoped_refptr<DecoderBuffer>& buffer, + const DecodeCB& decode_cb) OVERRIDE; + virtual void Reset(const base::Closure& closure) OVERRIDE; + virtual void Stop(const base::Closure& closure) OVERRIDE; + virtual bool HasAlpha() const OVERRIDE; + + private: + enum DecoderState { + kUninitialized, + kNormal, + kFlushCodec, + kDecodeFinished, + kError + }; + + // Handles (re-)initializing the decoder with a (new) config. + // Returns true when initialization was successful. + bool ConfigureDecoder(const VideoDecoderConfig& config); + + bool OpenDecoder(const VideoDecoderConfig& config); + void CloseDecoder(); + + void DecodeBuffer(const scoped_refptr<DecoderBuffer>& buffer); + bool VpuDecode(const scoped_refptr<DecoderBuffer>& buffer, + scoped_refptr<VideoFrame>* video_frame); + + // Reset decoder and call |reset_cb_|. + void DoReset(); + + scoped_refptr<base::MessageLoopProxy> message_loop_; + base::WeakPtrFactory<VpuVideoDecoder> weak_factory_; + base::WeakPtr<VpuVideoDecoder> weak_this_; + + DecoderState state_; + + DecodeCB decode_cb_; + base::Closure reset_cb_; + + VideoDecoderConfig config_; + + struct Internal; + Internal *internal; + + DISALLOW_COPY_AND_ASSIGN(VpuVideoDecoder); +}; + +} // namespace media + +#endif // MEDIA_FILTERS_VPU_VIDEO_DECODER_H_ diff --git a/media/media.gyp b/media/media.gyp index 4782741..ec53626 100644 --- a/media/media.gyp +++ b/media/media.gyp @@ -11,6 +11,7 @@ # (DT_NEEDED) instead of using dlopen. This helps with automated # detection of ABI mismatches and prevents silent errors. 'linux_link_pulseaudio%': 0, + 'media_use_imxvpu%': 1, 'conditions': [ ['OS=="android"', { # Android doesn't use ffmpeg. @@ -404,6 +405,10 @@ 'filters/video_frame_painter.h', 'filters/video_renderer_impl.cc', 'filters/video_renderer_impl.h', + 'filters/vpu_framebuffers.cc', + 'filters/vpu_framebuffers.h', + 'filters/vpu_video_decoder.cc', + 'filters/vpu_video_decoder.h', 'filters/vpx_video_decoder.cc', 'filters/vpx_video_decoder.h', 'filters/webvtt_util.h', @@ -658,6 +663,29 @@ 'DISABLE_USER_INPUT_MONITOR', ], }], + ['media_use_imxvpu==1', { + 'cflags': [ + '<!@(<(pkg-config) --cflags libfslvpuwrap)', + ], + 'link_settings': { + 'libraries': [ + '<!@(<(pkg-config) --libs libfslvpuwrap)', + ], + }, + }, { # media_use_imxvpu==0 + 'direct_dependent_settings': { + 'defines': [ + 'MEDIA_DISABLE_IMXVPU', + ], + }, + # Exclude the VPU sources. + 'sources!': [ + 'filters/vpu_framebuffers.cc', + 'filters/vpu_framebuffers.h', + 'filters/vpu_video_decoder.cc', + 'filters/vpu_video_decoder.h', + ], + }], ['use_cras==1', { 'cflags': [ '<!@(<(pkg-config) --cflags libcras)', -- 1.8.3.2 [-- Attachment #4: 0003-Update-vpu_video_decoder.cc-to-match-chromium-35.0.1883.patch --] [-- Type: text/x-diff, Size: 1813 bytes --] From f059d6501b17ab8aed618f53f7e4255cf8d8326b Mon Sep 17 00:00:00 2001 From: Mahyar Yaghmaee <mahyar@boundarydevices.com> Date: Fri, 28 Mar 2014 14:06:40 -0700 Subject: [PATCH 3/3] Update vpu_video_decoder.cc to match chromium-35.0.1883 Signed-off-by: Mahyar Yaghmaee <mahyar@boundarydevices.com> --- media/filters/vpu_video_decoder.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/media/filters/vpu_video_decoder.cc b/media/filters/vpu_video_decoder.cc index 396d4f1..9024484 100644 --- a/media/filters/vpu_video_decoder.cc +++ b/media/filters/vpu_video_decoder.cc @@ -18,7 +18,7 @@ #include "base/message_loop/message_loop_proxy.h" #include "base/strings/string_number_conversions.h" #include "base/sys_byteorder.h" -#include "media/base/bind_to_loop.h" +#include "media/base/bind_to_current_loop.h" #include "media/base/decoder_buffer.h" #include "media/base/demuxer_stream.h" #include "media/base/media_switches.h" @@ -393,7 +393,7 @@ void VpuVideoDecoder::Decode(const scoped_refptr<DecoderBuffer>& buffer, // Return empty frames if decoding has finished. if (state_ == kDecodeFinished) { - base::ResetAndReturn(&decode_cb_).Run(kOk, VideoFrame::CreateEmptyFrame()); + base::ResetAndReturn(&decode_cb_).Run(kOk, VideoFrame::CreateEOSFrame()); return; } @@ -445,7 +445,7 @@ void VpuVideoDecoder::DecodeBuffer(const scoped_refptr<DecoderBuffer>& buffer) { // Transition to kDecodeFinished on the first end of stream buffer. if (state_ == kNormal && buffer->end_of_stream()) { state_ = kDecodeFinished; - base::ResetAndReturn(&decode_cb_).Run(kOk, VideoFrame::CreateEmptyFrame()); + base::ResetAndReturn(&decode_cb_).Run(kOk, VideoFrame::CreateEOSFrame()); return; } -- 1.8.3.2 ^ permalink raw reply related [flat|nested] 37+ messages in thread
* Re: Chromium acceleration 2014-04-01 19:22 ` Eric Nelson @ 2014-04-02 10:21 ` Carlos Rafael Giani 2014-04-02 10:28 ` Gary Thomas [not found] ` <533BE4A3.7040301@pr.hu> 2014-04-02 10:29 ` Boszormenyi Zoltan 2 siblings, 1 reply; 37+ messages in thread From: Carlos Rafael Giani @ 2014-04-02 10:21 UTC (permalink / raw) To: Eric Nelson, Christian Betz, meta-freescale Keep in mind what I wrote. This version of VPU acceleration is very basic (it will copy frames with the CPU), and fulfilled the customer's immediate needs back then, but can be done much better. I am currently looking into a better approach. On 2014-04-01 21:22, Eric Nelson wrote: > Thanks again Carlos, > > On 03/20/2014 04:19 PM, Carlos Rafael Giani wrote: > > > > <snip> >> >> Back then we needed some hw decoding quickly, so we did not look further >> into this, since we had spent a lot of time getting the 2D acceleration >> stable already. I could only briefly look at the exynos accelerator >> code, but it does look like the right direction, although the VPU uses >> physical addresses directly instead of dmabuf FDs. I am currently >> writing a frontend for the libfslvpuwrap, which takes care of certain >> complexities (like being able to pass userdata pointers to frames, to >> make it possible to associate input and output frames, which is >> essential for correct timestamping, especially when things like h264 >> frame reordering are active). This frontend will hide these things in a >> future gstreamer-imx release to make the decoder code clearer and easier >> to maintain, and is intended to be reusable, for example for Chromium >> integration, or XBMC. Beyond that, my patches are probably not that >> helpful anymore, since they were based on the vpx decoder way of >> decoding, and I agree that the exynos code is a better starting point. >> Nevertheless, I attached the patch. Keep in mind that it is very basic, >> old, and wasn't further developed on because it was "good enough" for >> the project. >> >> But here are some additional notes from our efforts to accelerate >> Chromium on imx6 (keep in mind these apply to version 32.0.1664.3 ) : >> >> 1. We started the google-chrome binary with these switches: >> --ignore-gpu-blacklist --enable-gpu --use-gl=egl >> --enable-accelerated-2d-canvas >> >> 2. To make building Chromium easier, we switched to component build (by >> default, it is all linked into one enormous binary). I attached a patch >> that was necessary to fix some minor issues. Perhaps it is not necessary >> anymore. >> >> 3. Chromium tried to load libEGL with dlopen() , which caused problems, >> because with the Vivante libraries, libEGL also needs libGAL. Usually, >> build scripts just add -lEGL -lGAL to the linker line. With dlopen() >> this wasn't possible of course. We patched the gyp scripts to link >> against this libraries during building instead. I attached this patch. >> It is really a hack, because it circumvents the sandboxing process (this >> is why Chromium loads EGL and GLESv2 with dlopen() ). >> > > Mahyar updated these patches to apply against the chromium-35.0.1883.0 > build currently in meta-browser. > > Additional notes to follow, but this appears to achieve HTML5 video > against Webm/Ogg videos when chromium is started with these command > line arguments: > --ignore-gpu-blacklist --enable-gpu --usegl-egl > > Regards, > > > Eric > ^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: Chromium acceleration 2014-04-02 10:21 ` Carlos Rafael Giani @ 2014-04-02 10:28 ` Gary Thomas 2014-04-02 10:33 ` Carlos Rafael Giani 0 siblings, 1 reply; 37+ messages in thread From: Gary Thomas @ 2014-04-02 10:28 UTC (permalink / raw) To: meta-freescale On 2014-04-02 04:21, Carlos Rafael Giani wrote: > Keep in mind what I wrote. This version of VPU acceleration is very basic (it will copy frames with the CPU), and fulfilled the customer's immediate needs back then, but can be > done much better. I am currently looking into a better approach. > > On 2014-04-01 21:22, Eric Nelson wrote: >> Thanks again Carlos, >> >> On 03/20/2014 04:19 PM, Carlos Rafael Giani wrote: >> > >> > <snip> >>> >>> Back then we needed some hw decoding quickly, so we did not look further >>> into this, since we had spent a lot of time getting the 2D acceleration >>> stable already. I could only briefly look at the exynos accelerator >>> code, but it does look like the right direction, although the VPU uses >>> physical addresses directly instead of dmabuf FDs. I am currently >>> writing a frontend for the libfslvpuwrap, which takes care of certain >>> complexities (like being able to pass userdata pointers to frames, to >>> make it possible to associate input and output frames, which is >>> essential for correct timestamping, especially when things like h264 >>> frame reordering are active). This frontend will hide these things in a >>> future gstreamer-imx release to make the decoder code clearer and easier >>> to maintain, and is intended to be reusable, for example for Chromium >>> integration, or XBMC. Beyond that, my patches are probably not that >>> helpful anymore, since they were based on the vpx decoder way of >>> decoding, and I agree that the exynos code is a better starting point. >>> Nevertheless, I attached the patch. Keep in mind that it is very basic, >>> old, and wasn't further developed on because it was "good enough" for >>> the project. >>> >>> But here are some additional notes from our efforts to accelerate >>> Chromium on imx6 (keep in mind these apply to version 32.0.1664.3 ) : >>> >>> 1. We started the google-chrome binary with these switches: >>> --ignore-gpu-blacklist --enable-gpu --use-gl=egl >>> --enable-accelerated-2d-canvas >>> >>> 2. To make building Chromium easier, we switched to component build (by >>> default, it is all linked into one enormous binary). I attached a patch >>> that was necessary to fix some minor issues. Perhaps it is not necessary >>> anymore. >>> >>> 3. Chromium tried to load libEGL with dlopen() , which caused problems, >>> because with the Vivante libraries, libEGL also needs libGAL. Usually, >>> build scripts just add -lEGL -lGAL to the linker line. With dlopen() >>> this wasn't possible of course. We patched the gyp scripts to link >>> against this libraries during building instead. I attached this patch. >>> It is really a hack, because it circumvents the sandboxing process (this >>> is why Chromium loads EGL and GLESv2 with dlopen() ). >>> >> >> Mahyar updated these patches to apply against the chromium-35.0.1883.0 >> build currently in meta-browser. Are these patches available somewhere? >> Additional notes to follow, but this appears to achieve HTML5 video >> against Webm/Ogg videos when chromium is started with these command >> line arguments: >> --ignore-gpu-blacklist --enable-gpu --usegl-egl -- ------------------------------------------------------------ Gary Thomas | Consulting for the MLB Associates | Embedded world ------------------------------------------------------------ ^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: Chromium acceleration 2014-04-02 10:28 ` Gary Thomas @ 2014-04-02 10:33 ` Carlos Rafael Giani 0 siblings, 0 replies; 37+ messages in thread From: Carlos Rafael Giani @ 2014-04-02 10:33 UTC (permalink / raw) To: meta-freescale On 2014-04-02 12:28, Gary Thomas wrote: > On 2014-04-02 04:21, Carlos Rafael Giani wrote: >> Keep in mind what I wrote. This version of VPU acceleration is very basic (it will copy frames with the CPU), and fulfilled the customer's immediate needs back then, but can be >> done much better. I am currently looking into a better approach. > Are these patches available somewhere? No, not yet, there is no finished code at the moment. If I am right, the necessary changes are not big though. The actual bottleneck here is time :) ^ permalink raw reply [flat|nested] 37+ messages in thread
[parent not found: <533BE4A3.7040301@pr.hu>]
* Re: Chromium acceleration [not found] ` <533BE4A3.7040301@pr.hu> @ 2014-04-02 10:23 ` Carlos Rafael Giani 2014-04-02 11:12 ` Boszormenyi Zoltan 2014-04-02 12:02 ` Christian Betz 0 siblings, 2 replies; 37+ messages in thread From: Carlos Rafael Giani @ 2014-04-02 10:23 UTC (permalink / raw) To: Boszormenyi Zoltan, Eric Nelson, Christian Betz, meta-freescale On 2014-04-02 12:21, Boszormenyi Zoltan wrote: > Hi, > > 2014-04-01 21:22 keltezéssel, Eric Nelson írta: >> >> Mahyar updated these patches to apply against the chromium-35.0.1883.0 >> build currently in meta-browser. >> >> Additional notes to follow, but this appears to achieve HTML5 video >> against Webm/Ogg videos when chromium is started with these command >> line arguments: >> --ignore-gpu-blacklist --enable-gpu --usegl-egl > > you meant "--use-gl=egl". > > I have rebuilt Chromium with these patches. The result cannot play a > short MP4 video from a file:// URL. > The console output is very suspicious, libGAL complains about a > missing ID file that actually exists. > The image about the console is attached. > > Best regards, > Zoltán Böszörményi > The VPU part could be because of missing firmware. Check if the vpu files are present in /lib/firmware. As for MP4, this is a known problem. You are building Chromium, not Chrome. MP4 support is part of the restricted feature set, which is included in Chrome but not Chromium. Try a WebM file for example. ^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: Chromium acceleration 2014-04-02 10:23 ` Carlos Rafael Giani @ 2014-04-02 11:12 ` Boszormenyi Zoltan 2014-04-02 12:02 ` Christian Betz 1 sibling, 0 replies; 37+ messages in thread From: Boszormenyi Zoltan @ 2014-04-02 11:12 UTC (permalink / raw) To: Carlos Rafael Giani, Eric Nelson, Christian Betz, meta-freescale 2014-04-02 12:23 keltezéssel, Carlos Rafael Giani írta: > On 2014-04-02 12:21, Boszormenyi Zoltan wrote: >> Hi, >> >> 2014-04-01 21:22 keltezéssel, Eric Nelson írta: >>> >>> Mahyar updated these patches to apply against the chromium-35.0.1883.0 >>> build currently in meta-browser. >>> >>> Additional notes to follow, but this appears to achieve HTML5 video >>> against Webm/Ogg videos when chromium is started with these command >>> line arguments: >>> --ignore-gpu-blacklist --enable-gpu --usegl-egl >> >> you meant "--use-gl=egl". >> >> I have rebuilt Chromium with these patches. The result cannot play a short MP4 video >> from a file:// URL. >> The console output is very suspicious, libGAL complains about a missing ID file that >> actually exists. >> The image about the console is attached. >> >> Best regards, >> Zoltán Böszörményi >> > > The VPU part could be because of missing firmware. Check if the vpu files are present in > /lib/firmware. I have /lib/firmware/vpu/vpu_fw_imxq6.bin, size 253968, the last 6 digits of md5sum is e8debf. > As for MP4, this is a known problem. You are building Chromium, not Chrome. MP4 support > is part of the restricted feature set, which is included in Chrome but not Chromium. Try > a WebM file for example. I tried these: 1. http://www.webmfiles.org/demo-files/ The webm examples play nicely, even scaled to full screen. 2. http://devfiles.myopera.com/articles/1891/custom-controls-webm-720p.html It's the same "Elephants Dream" as one of the examples in (1) but at 720p. It pays nicely in the browser control but it's a slideshow as full screen. On the other hand, gstreamer 0.10 with gst-fsl-plugin and its gst-fsl-plugin-gplay subpackage, gplay plays a 720p and a 1080p H.264 test file very well without tearing. Best regards, Zoltán Böszörményi ^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: Chromium acceleration 2014-04-02 10:23 ` Carlos Rafael Giani 2014-04-02 11:12 ` Boszormenyi Zoltan @ 2014-04-02 12:02 ` Christian Betz 2014-04-02 12:28 ` Carlos Rafael Giani 1 sibling, 1 reply; 37+ messages in thread From: Christian Betz @ 2014-04-02 12:02 UTC (permalink / raw) To: Carlos Rafael Giani; +Cc: meta-freescale [-- Attachment #1: Type: text/plain, Size: 758 bytes --] > > The VPU part could be because of missing firmware. Check if the vpu files >> are present in /lib/firmware. >> > As for MP4, this is a known problem. You are building Chromium, not > Chrome. MP4 support is part of the restricted feature set, which is > included in Chrome but not Chromium. Try a WebM file for example. > this apparently can be worked around with gyp options: "proprietary_codecs=1 ffmpeg_branding=Chrome branding=Chrome to allow Chrome to play h.264 content, which is the only codec VAVDA knows about today." this is described on a wiki page setting up hw video decode on **intel** processors: https://code.google.com/p/chromium/wiki/LinuxHWVideoDecode note: i haven't actually tried this! (but i would like to) [-- Attachment #2: Type: text/html, Size: 1408 bytes --] ^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: Chromium acceleration 2014-04-02 12:02 ` Christian Betz @ 2014-04-02 12:28 ` Carlos Rafael Giani 2014-04-04 9:28 ` Boszormenyi Zoltan 0 siblings, 1 reply; 37+ messages in thread From: Carlos Rafael Giani @ 2014-04-02 12:28 UTC (permalink / raw) To: Christian Betz; +Cc: meta-freescale [-- Attachment #1: Type: text/plain, Size: 1060 bytes --] On 2014-04-02 14:02, Christian Betz wrote: > > The VPU part could be because of missing firmware. Check if > the vpu files are present in /lib/firmware. > > As for MP4, this is a known problem. You are building Chromium, > not Chrome. MP4 support is part of the restricted feature set, > which is included in Chrome but not Chromium. Try a WebM file for > example. > > > this apparently can be worked around with gyp options: > > "proprietary_codecs=1 ffmpeg_branding=Chrome branding=Chrome to allow > Chrome to play h.264 content, which is the only codec VAVDA knows > about today." > > this is described on a wiki page setting up hw video decode on > **intel** processors: > > https://code.google.com/p/chromium/wiki/LinuxHWVideoDecode > > note: i haven't actually tried this! (but i would like to) We tried that back then. The Chrome branding enabled a million other things , which caused all sorts of difficulties. Also note that enabling the Chrome branding might have legal repercussions. [-- Attachment #2: Type: text/html, Size: 2597 bytes --] ^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: Chromium acceleration 2014-04-02 12:28 ` Carlos Rafael Giani @ 2014-04-04 9:28 ` Boszormenyi Zoltan 0 siblings, 0 replies; 37+ messages in thread From: Boszormenyi Zoltan @ 2014-04-04 9:28 UTC (permalink / raw) To: Carlos Rafael Giani, Christian Betz; +Cc: meta-freescale [-- Attachment #1: Type: text/plain, Size: 1796 bytes --] 2014-04-02 14:28 keltezéssel, Carlos Rafael Giani írta: > On 2014-04-02 14:02, Christian Betz wrote: >> >> The VPU part could be because of missing firmware. Check if the vpu files are >> present in /lib/firmware. >> >> As for MP4, this is a known problem. You are building Chromium, not Chrome. MP4 >> support is part of the restricted feature set, which is included in Chrome but not >> Chromium. Try a WebM file for example. >> >> >> this apparently can be worked around with gyp options: >> >> "proprietary_codecs=1 ffmpeg_branding=Chrome branding=Chrome to allow Chrome to play >> h.264 content, which is the only codec VAVDA knows about today." >> >> this is described on a wiki page setting up hw video decode on **intel** processors: >> >> https://code.google.com/p/chromium/wiki/LinuxHWVideoDecode >> >> note: i haven't actually tried this! (but i would like to) > > We tried that back then. The Chrome branding enabled a million other things , which > caused all sorts of difficulties. Also note that enabling the Chrome branding might have > legal repercussions. A comment on that page says to use these flags (Chrome branding is not needed, only chromeos=1): export GYP_DEFINES="chromeos=1 proprietary_codecs=1 ffmpeg_branding=Chrome" do_configure succeeds but do_compile fails with "brlapi.h" missing. A google search gave me this: https://groups.google.com/a/chromium.org/forum/#!topic/chromium-dev/StpTzFnf8ok Supposedly, running "build/install-build-deps.sh" fixes it but it turned out it only fixes things for building Chromium for the host and the script wants an Ubuntu host OS. Is there a ready to use recipe for brlapi/brltty somewhere or should I make one? Thanks in advance, Zoltán Böszörményi [-- Attachment #2: Type: text/html, Size: 3956 bytes --] ^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: Chromium acceleration 2014-04-01 19:22 ` Eric Nelson 2014-04-02 10:21 ` Carlos Rafael Giani [not found] ` <533BE4A3.7040301@pr.hu> @ 2014-04-02 10:29 ` Boszormenyi Zoltan 2014-04-02 14:16 ` Eric Nelson 2 siblings, 1 reply; 37+ messages in thread From: Boszormenyi Zoltan @ 2014-04-02 10:29 UTC (permalink / raw) To: Eric Nelson, Carlos Rafael Giani, Christian Betz, meta-freescale [-- Attachment #1: Type: text/plain, Size: 877 bytes --] Hi, 2014-04-01 21:22 keltezéssel, Eric Nelson írta: > > Mahyar updated these patches to apply against the chromium-35.0.1883.0 > build currently in meta-browser. > > Additional notes to follow, but this appears to achieve HTML5 video > against Webm/Ogg videos when chromium is started with these command > line arguments: > --ignore-gpu-blacklist --enable-gpu --usegl-egl you meant "--use-gl=egl". I have rebuilt Chromium with these patches. The result cannot play a short MP4 video from a file:// URL. The console output is very suspicious, libGAL complains about a missing ID file that actually exists. The image about the console is attached. This is a copy of the original message, I cancelled waiting for moderation. The original image exceeded the list limits so I reduced it to 16-color greyscale. Best regards, Zoltán Böszörményi [-- Attachment #2: 20140402_121516_800x600.png --] [-- Type: image/png, Size: 113651 bytes --] ^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: Chromium acceleration 2014-04-02 10:29 ` Boszormenyi Zoltan @ 2014-04-02 14:16 ` Eric Nelson 0 siblings, 0 replies; 37+ messages in thread From: Eric Nelson @ 2014-04-02 14:16 UTC (permalink / raw) To: Boszormenyi Zoltan, Carlos Rafael Giani, Christian Betz, meta-freescale Hi Zoltan, On 04/02/2014 03:29 AM, Boszormenyi Zoltan wrote: > Hi, > > 2014-04-01 21:22 keltezéssel, Eric Nelson írta: >> >> Mahyar updated these patches to apply against the chromium-35.0.1883.0 >> build currently in meta-browser. >> >> Additional notes to follow, but this appears to achieve HTML5 video >> against Webm/Ogg videos when chromium is started with these command >> line arguments: >> --ignore-gpu-blacklist --enable-gpu --usegl-egl > > you meant "--use-gl=egl". > Probably right. > I have rebuilt Chromium with these patches. The result cannot play a > short MP4 video from a file:// URL. > The console output is very suspicious, libGAL complains about a missing > ID file that actually exists. > The image about the console is attached. > > This is a copy of the original message, I cancelled waiting for moderation. > The original image exceeded the list limits so I reduced it to 16-color > greyscale. > There's a lesson here that you should be putting console output either directly into your e-mail (trimmed to important points). Putting the output into an image makes it slow to read and tedious to quote. From what I can tell, you aren't running on an image that otherwise supports GPU or VPU acceleration. That's a pre-requisite for this, and I recommend using fsl-image-gui or some other known good starting point. Also note that we sent these patches not to imply that they're fully functional, but to allow others to have a working example for exploring the code. Regards, Eric ^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: Chromium acceleration 2014-03-19 20:49 Chromium acceleration Eric Nelson 2014-03-19 21:00 ` Carlos Rafael Giani @ 2014-03-20 12:47 ` Lauren Post 2014-03-20 14:25 ` Eric Nelson 1 sibling, 1 reply; 37+ messages in thread From: Lauren Post @ 2014-03-20 12:47 UTC (permalink / raw) To: Eric Nelson, meta-freescale My original statement about acceleration was for webGL in the browser. ffmpeg-mt is not hardware accelerated with the VPU although it is possible to update it to integrate with VPU. As other emails have mentioned removing data movement and the CSC conversion is the key to improving performance with ffmpeg with vpu acceleration. It is not something we have in our upcoming release. Lauren -----Original Message----- From: Eric Nelson [mailto:eric.nelson@boundarydevices.com] Sent: Wednesday, March 19, 2014 3:50 PM To: Post Lauren-RAA013; meta-freescale@yoctoproject.org Subject: Chromium acceleration Hi Lauren, A while back, you mentioned that 3.10.17-ga would help provide support for "Chromium acceleration" but didn't provide details. Did you mean WebGL support (i.e. GPU acceleration), or video acceleration (VPU support)? My understanding is that Chromium is using ffmpeg-mt as the basis for accelerated video: http://www.chromium.org/developers/design-documents/video Is anyone currently working on support for ffmpeg-mt and i.MX video? Is anyone interested? Please advise, Eric ^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: Chromium acceleration 2014-03-20 12:47 ` Lauren Post @ 2014-03-20 14:25 ` Eric Nelson 2014-03-20 14:27 ` Lauren Post 0 siblings, 1 reply; 37+ messages in thread From: Eric Nelson @ 2014-03-20 14:25 UTC (permalink / raw) To: Lauren Post, meta-freescale Thanks Lauren, On 03/20/2014 05:47 AM, Lauren Post wrote: > My original statement about acceleration was for webGL in the browser. > Are you working in the context of OSSystems/meta-browser (i.e. Otavio's push of Chromium 35)? ^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: Chromium acceleration 2014-03-20 14:25 ` Eric Nelson @ 2014-03-20 14:27 ` Lauren Post 0 siblings, 0 replies; 37+ messages in thread From: Lauren Post @ 2014-03-20 14:27 UTC (permalink / raw) To: Eric Nelson, meta-freescale Yes we are using that version for our chromium. -----Original Message----- From: Eric Nelson [mailto:eric.nelson@boundarydevices.com] Sent: Thursday, March 20, 2014 9:25 AM To: Post Lauren-RAA013; meta-freescale@yoctoproject.org Subject: Re: Chromium acceleration Thanks Lauren, On 03/20/2014 05:47 AM, Lauren Post wrote: > My original statement about acceleration was for webGL in the browser. > Are you working in the context of OSSystems/meta-browser (i.e. Otavio's push of Chromium 35)? ^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: Chromium acceleration @ 2014-03-25 9:32 zboszor 2014-03-25 9:35 ` Eric Bénard 2014-03-25 9:46 ` Marco Trillo 0 siblings, 2 replies; 37+ messages in thread From: zboszor @ 2014-03-25 9:32 UTC (permalink / raw) To: meta-freescale Hi, how can I add the meta-browser tree to the set of recipes? I did: $ cd fsl-community-bsp/sources $ git clone https://github.com/OSSystems/meta-browser.git $ cd .. $ . ./setup-environment build-master-next/ $ bitbake chromium Loading cache: 100% |###########################################################################################################################| ETA: 00:00:00 Loaded 1806 entries from dependency cache. ERROR: Nothing PROVIDES 'chromium' Summary: There was 1 WARNING message shown. Summary: There was 1 ERROR message shown, returning a non-zero exit code. [zozo@localhost build-master-next]$ Where should I move the meta-browser directory from the toplevel "sources"? What else should be done? Thanks in advance, Zoltán Böszörményi ^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: Chromium acceleration 2014-03-25 9:32 zboszor @ 2014-03-25 9:35 ` Eric Bénard 2014-03-25 9:46 ` Marco Trillo 1 sibling, 0 replies; 37+ messages in thread From: Eric Bénard @ 2014-03-25 9:35 UTC (permalink / raw) To: zboszor; +Cc: meta-freescale Hi Zoltán, Le Tue, 25 Mar 2014 10:32:22 +0100, zboszor@pr.hu a écrit : > Hi, > > how can I add the meta-browser tree to the set of recipes? I did: > > $ cd fsl-community-bsp/sources > $ git clone https://github.com/OSSystems/meta-browser.git > $ cd .. > $ . ./setup-environment build-master-next/ > $ bitbake chromium > Loading cache: 100% > |###########################################################################################################################| > ETA: 00:00:00 > Loaded 1806 entries from dependency cache. > ERROR: Nothing PROVIDES 'chromium' > > Summary: There was 1 WARNING message shown. > Summary: There was 1 ERROR message shown, returning a non-zero exit code. > [zozo@localhost build-master-next]$ > > Where should I move the meta-browser directory from the toplevel "sources"? > What else should be done? > http://www.yoctoproject.org/docs/1.5.1/dev-manual/dev-manual.html#enabling-your-layer Eric ^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: Chromium acceleration 2014-03-25 9:32 zboszor 2014-03-25 9:35 ` Eric Bénard @ 2014-03-25 9:46 ` Marco Trillo 2014-03-25 12:58 ` Boszormenyi Zoltan 1 sibling, 1 reply; 37+ messages in thread From: Marco Trillo @ 2014-03-25 9:46 UTC (permalink / raw) To: zboszor; +Cc: meta-freescale Hi, On 03/25/2014 10:32 AM, zboszor@pr.hu wrote: > Hi, > > how can I add the meta-browser tree to the set of recipes? I did: > > $ cd fsl-community-bsp/sources > $ git clone https://github.com/OSSystems/meta-browser.git > $ cd .. > $ . ./setup-environment build-master-next/ > $ bitbake chromium > Loading cache: 100% > |###########################################################################################################################| > ETA: 00:00:00 > Loaded 1806 entries from dependency cache. > ERROR: Nothing PROVIDES 'chromium' > > Summary: There was 1 WARNING message shown. > Summary: There was 1 ERROR message shown, returning a non-zero exit code. > [zozo@localhost build-master-next]$ > > Where should I move the meta-browser directory from the toplevel "sources"? > What else should be done? You need to add the "meta-browser" layer to your bblayers.conf (in build/conf/), like this: BBLAYERS += " ${BSPDIR}/sources/meta-browser " You will probably need other to add other layers such as "meta-gnome". Hope it helps, Marco. ^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: Chromium acceleration 2014-03-25 9:46 ` Marco Trillo @ 2014-03-25 12:58 ` Boszormenyi Zoltan 0 siblings, 0 replies; 37+ messages in thread From: Boszormenyi Zoltan @ 2014-03-25 12:58 UTC (permalink / raw) To: Marco Trillo; +Cc: meta-freescale 2014-03-25 10:46 keltezéssel, Marco Trillo írta: > Hi, > > On 03/25/2014 10:32 AM, zboszor@pr.hu wrote: >> Hi, >> >> how can I add the meta-browser tree to the set of recipes? I did: >> >> $ cd fsl-community-bsp/sources >> $ git clone https://github.com/OSSystems/meta-browser.git >> $ cd .. >> $ . ./setup-environment build-master-next/ >> $ bitbake chromium >> Loading cache: 100% >> |###########################################################################################################################| >> >> ETA: 00:00:00 >> Loaded 1806 entries from dependency cache. >> ERROR: Nothing PROVIDES 'chromium' >> >> Summary: There was 1 WARNING message shown. >> Summary: There was 1 ERROR message shown, returning a non-zero exit code. >> [zozo@localhost build-master-next]$ >> >> Where should I move the meta-browser directory from the toplevel "sources"? >> What else should be done? > > You need to add the "meta-browser" layer to your bblayers.conf (in build/conf/), like this: > > BBLAYERS += " ${BSPDIR}/sources/meta-browser " > > You will probably need other to add other layers such as "meta-gnome". Thanks for the answer. I also added "meta-gnome" to BBLAYERS and I needed these set in local.conf: LICENSE_FLAGS_WHITELIST = "commercial_libav commercial_x264" PREFERRED_PROVIDER_jpeg = "libjpeg" PREFERRED_PROVIDER_jpeg-native = "libjpeg-native" Using libjpeg-turbo fails with: ERROR: Fetcher failure: Fetch command failed with exit code 1, output: svn: E210002: Unable to connect to a repository at URL 'svn://svn.code.sf.net/p/libjpeg-turbo/code/trunk' svn: E210002: Network connection closed unexpectedly ERROR: Function failed: Fetcher failure for URL: 'svn://svn.code.sf.net/p/libjpeg-turbo/code;protocol=svn;module=trunk'. Unable to fetch URL from any source. ERROR: Logfile of failure stored in: /home/zozo/fsl-community-bsp/build-master-next/tmp/work/cortexa9hf-vfp-neon-poky-linux-gnueabi/libjpeg-turbo/8d+1.3.0-r0/temp/log.do_fetch.23323 ERROR: Task 949 (/home/zozo/fsl-community-bsp/sources/meta-openembedded/meta-oe/recipes-core/jpeg/libjpeg-turbo_svn.bb, do_fetch) failed with exit code '1' Best regards, Zoltán Böszörményi ^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: Chromium acceleration @ 2014-11-27 10:14 Becue Paul 2014-12-01 14:34 ` Daiane Angolini 0 siblings, 1 reply; 37+ messages in thread From: Becue Paul @ 2014-11-27 10:14 UTC (permalink / raw) To: meta-freescale [-- Attachment #1: Type: text/plain, Size: 2068 bytes --] Hello I am working on a device with an iMX6 Solo processor for making a kind of web-kiosk with touch interface on Yocto. To learn Yocto I bought your book a month ago. It helped me a lot. Not too long and to the point. Thank you for it. I am building it with Yocto Linux - X11 - chromium.I added the chromium-imx layer from the freescale layer to my build. I builded for daisy and dizzy. But I can't get the hardware acceleration on for chromium. When I look at chrome://gpu I get: Graphics Feature Status Canvas: Software only, hardware acceleration unavailable Flash: Software only, hardware acceleration unavailable Flash Stage3D: Software only, hardware acceleration unavailable Flash Stage3D Baseline profile: Software only, hardware acceleration unavailable Compositing: Software only, hardware acceleration unavailable Rasterization: Software only, hardware acceleration unavailable Threaded Rasterization: Unavailable Video Decode: Software only, hardware acceleration unavailable Video Encode: Software only, hardware acceleration unavailable WebGL: Unavailable and on the command line: ERROR:browser_main_loop.cc(162)] Running without the SUID sandbox! See https://code.google.com/p/chromium/wiki/LinuxSUIDSandboxDevelopment for more information on developing with the sandbox on. ERROR:gl_implementation_x11.cc(86)] glxGetProcAddress not found. ERROR:gpu_child_thread.cc(143)] Exiting GPU process due to errors during initialization ERROR: v4l2 capture: slave not found! ERROR:renderer_main.cc(204)] Running without renderer sandbox ERROR:desktop_window_tree_host_x11.cc(1547)] Not implemented reached in void views::DesktopWindowTreeHostX11::MapWindow(ui::WindowShowState) ERROR:renderer_main.cc(204)] Running without renderer sandbox ERROR:renderer_main.cc(204)] Running without renderer sandbox ERROR:renderer_main.cc(204)] Running without renderer sandbox ERROR:renderer_main.cc(204)] Running without renderer sandbox Did I something wrong or is it simply not possible with the GPU of the iMX6? Thank you in advance. Paul Becue. [-- Attachment #2: Type: text/html, Size: 6114 bytes --] ^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: Chromium acceleration 2014-11-27 10:14 Becue Paul @ 2014-12-01 14:34 ` Daiane Angolini 2014-12-01 15:07 ` Otavio Salvador 0 siblings, 1 reply; 37+ messages in thread From: Daiane Angolini @ 2014-12-01 14:34 UTC (permalink / raw) To: Becue Paul; +Cc: meta-freescale On Thu, Nov 27, 2014 at 8:14 AM, Becue Paul <P.Becue@televic.com> wrote: > Hello > > I am working on a device with an iMX6 Solo processor for making a kind of > web-kiosk with touch interface on Yocto. > To learn Yocto I bought your book a month ago. It helped me a lot. Not too > long and to the point. Thank you for it. Thanks a lot. I'm glad to hear that. > I am building it with Yocto Linux - X11 - chromium.I added the chromium-imx > layer from the freescale layer to my build. I builded for daisy and dizzy. > But I can't get the hardware acceleration on for chromium. When I look at > chrome://gpu I get: > Graphics Feature Status Canvas: Software only, hardware acceleration > unavailable Flash: Software only, hardware acceleration unavailable Flash > Stage3D: Software only, hardware acceleration unavailable Flash Stage3D > Baseline profile: Software only, hardware acceleration unavailable > Compositing: Software only, hardware acceleration unavailable Rasterization: > Software only, hardware acceleration unavailable Threaded Rasterization: > Unavailable Video Decode: Software only, hardware acceleration unavailable > Video Encode: Software only, hardware acceleration unavailable WebGL: > Unavailable > and on the command line: > ERROR:browser_main_loop.cc(162)] Running without the SUID sandbox! See > https://code.google.com/p/chromium/wiki/LinuxSUIDSandboxDevelopment for more > information on developing with the sandbox on. > ERROR:gl_implementation_x11.cc(86)] glxGetProcAddress not found. > ERROR:gpu_child_thread.cc(143)] Exiting GPU process due to errors during > initialization > ERROR: v4l2 capture: slave not found! > ERROR:renderer_main.cc(204)] Running without renderer sandbox > ERROR:desktop_window_tree_host_x11.cc(1547)] Not implemented reached in void > views::DesktopWindowTreeHostX11::MapWindow(ui::WindowShowState) > ERROR:renderer_main.cc(204)] Running without renderer sandbox > ERROR:renderer_main.cc(204)] Running without renderer sandbox > ERROR:renderer_main.cc(204)] Running without renderer sandbox > ERROR:renderer_main.cc(204)] Running without renderer sandbox I tested cromium sometime ago with dizzy and it worked fine, I only used 4.8 for toolchain. > Did I something wrong or is it simply not possible with the GPU of the iMX6? > Thank you in advance. What are you using? Freescale Official Release or FSL Community BSP? Daiane > > > > Paul Becue. > > > > > -- > _______________________________________________ > meta-freescale mailing list > meta-freescale@yoctoproject.org > https://lists.yoctoproject.org/listinfo/meta-freescale > ^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: Chromium acceleration 2014-12-01 14:34 ` Daiane Angolini @ 2014-12-01 15:07 ` Otavio Salvador 0 siblings, 0 replies; 37+ messages in thread From: Otavio Salvador @ 2014-12-01 15:07 UTC (permalink / raw) To: Daiane Angolini; +Cc: meta-freescale, Becue Paul On Mon, Dec 1, 2014 at 12:34 PM, Daiane Angolini <daiane.list@gmail.com> wrote: > On Thu, Nov 27, 2014 at 8:14 AM, Becue Paul <P.Becue@televic.com> wrote: >> I am working on a device with an iMX6 Solo processor for making a kind of >> web-kiosk with touch interface on Yocto. >> To learn Yocto I bought your book a month ago. It helped me a lot. Not too >> long and to the point. Thank you for it. > > Thanks a lot. I'm glad to hear that. Me too :-) >> I am building it with Yocto Linux - X11 - chromium.I added the chromium-imx >> layer from the freescale layer to my build. I builded for daisy and dizzy. >> But I can't get the hardware acceleration on for chromium. When I look at >> chrome://gpu I get: >> Graphics Feature Status Canvas: Software only, hardware acceleration >> unavailable Flash: Software only, hardware acceleration unavailable Flash >> Stage3D: Software only, hardware acceleration unavailable Flash Stage3D >> Baseline profile: Software only, hardware acceleration unavailable >> Compositing: Software only, hardware acceleration unavailable Rasterization: >> Software only, hardware acceleration unavailable Threaded Rasterization: >> Unavailable Video Decode: Software only, hardware acceleration unavailable >> Video Encode: Software only, hardware acceleration unavailable WebGL: >> Unavailable >> and on the command line: >> ERROR:browser_main_loop.cc(162)] Running without the SUID sandbox! See >> https://code.google.com/p/chromium/wiki/LinuxSUIDSandboxDevelopment for more >> information on developing with the sandbox on. >> ERROR:gl_implementation_x11.cc(86)] glxGetProcAddress not found. >> ERROR:gpu_child_thread.cc(143)] Exiting GPU process due to errors during >> initialization >> ERROR: v4l2 capture: slave not found! >> ERROR:renderer_main.cc(204)] Running without renderer sandbox >> ERROR:desktop_window_tree_host_x11.cc(1547)] Not implemented reached in void >> views::DesktopWindowTreeHostX11::MapWindow(ui::WindowShowState) >> ERROR:renderer_main.cc(204)] Running without renderer sandbox >> ERROR:renderer_main.cc(204)] Running without renderer sandbox >> ERROR:renderer_main.cc(204)] Running without renderer sandbox >> ERROR:renderer_main.cc(204)] Running without renderer sandbox > > I tested cromium sometime ago with dizzy and it worked fine, I only > used 4.8 for toolchain. I am using it with several customers (with different levels of customization) with 4.9 toolchain and it is working fine. -- Otavio Salvador O.S. Systems http://www.ossystems.com.br http://code.ossystems.com.br Mobile: +55 (53) 9981-7854 Mobile: +1 (347) 903-9750 ^ permalink raw reply [flat|nested] 37+ messages in thread
end of thread, other threads:[~2014-12-01 15:07 UTC | newest] Thread overview: 37+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2014-03-19 20:49 Chromium acceleration Eric Nelson 2014-03-19 21:00 ` Carlos Rafael Giani 2014-03-19 22:40 ` Eric Nelson 2014-03-20 1:29 ` Christian Betz 2014-03-20 2:50 ` Eric Nelson 2014-03-20 8:30 ` Carlos Rafael Giani 2014-03-20 12:22 ` Otavio Salvador 2014-03-20 14:07 ` Christian Betz 2014-03-20 15:02 ` Otavio Salvador 2014-03-20 14:29 ` Eric Nelson 2014-03-20 14:58 ` Otavio Salvador 2014-03-21 11:49 ` Diego 2014-03-21 14:17 ` Eric Nelson 2014-03-20 13:46 ` Christian Betz 2014-03-20 23:19 ` Carlos Rafael Giani 2014-03-21 12:21 ` Dmitriy B. 2014-04-01 19:22 ` Eric Nelson 2014-04-02 10:21 ` Carlos Rafael Giani 2014-04-02 10:28 ` Gary Thomas 2014-04-02 10:33 ` Carlos Rafael Giani [not found] ` <533BE4A3.7040301@pr.hu> 2014-04-02 10:23 ` Carlos Rafael Giani 2014-04-02 11:12 ` Boszormenyi Zoltan 2014-04-02 12:02 ` Christian Betz 2014-04-02 12:28 ` Carlos Rafael Giani 2014-04-04 9:28 ` Boszormenyi Zoltan 2014-04-02 10:29 ` Boszormenyi Zoltan 2014-04-02 14:16 ` Eric Nelson 2014-03-20 12:47 ` Lauren Post 2014-03-20 14:25 ` Eric Nelson 2014-03-20 14:27 ` Lauren Post 2014-03-25 9:32 zboszor 2014-03-25 9:35 ` Eric Bénard 2014-03-25 9:46 ` Marco Trillo 2014-03-25 12:58 ` Boszormenyi Zoltan 2014-11-27 10:14 Becue Paul 2014-12-01 14:34 ` Daiane Angolini 2014-12-01 15:07 ` Otavio Salvador
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.