应用程序在本机4k中显示其图像内容的机制

时间:2014-04-03 10:10:43

标签: android android-ndk android-videoview google-tv smart-tv

据我所知,目前UHD视频内容主要使用4kHEVC codec电视上播放。

我想了解具有超高清图像内容的应用如何以原生4K显示其图像内容?

我正在寻找的是渲染4k(3840*2060) jpeg图像。我的显示器支持4k渲染,SOC甚至可以输出4k。我正在寻找框架中的修改,以便所有具有4k图像的应用程序可以在我的设备上呈现它们而不降低缩放。

实际上我正试图提出其他人可以使用的API集。但我的主要困惑是:对于jpeg图像,我创建了一个4k表面,但它们也是其他表面(按钮等)。它们由表面抛光器渲染,渲染在1280*720

现在用这些其他表面组合我的4k表面的最佳方法是什么?我应该在哪里升级这些表面以及在哪里组成它们?

1 个答案:

答案 0 :(得分:15)

要明确一件重要的事情是你要考虑什么样的发展。如果您只是希望在您的应用程序中显示视频流,则应该使用主要活动的用户界面,该主要活动将仅包含VideoView类的实例。 VideoView类可以调用各种方法来管理视频的播放。

使用要播放的视频路径配置VideoView,然后开始播放。然后选择VideoPlayerActivity.java文件并修改OnCreate()方法,如下面的清单所示:

package com.example.videoplayer;

import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.widget.VideoView;

public class VideoPlayerActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_video_player);

        final VideoView videoView = 
               (VideoView) findViewById(R.id.videoView1);

           videoView.setVideoPath(
               "http://www.ebookfrenzy.com/android_book/movie.mp4");

        videoView.start();
    }
.
.
.
}

基本上你所拥有的是用户界面的Android SDK,这意味着你可以使用不同的选择在UI层下面实际呈现视频streaming

将您的already existing App从平板电脑或手机迁移到智能电视也是可以顺利实现的。有些事情需要调整 - 例如通常用于智能电视的触摸屏可能不是一种选择。

enter image description here

相反,您应该将onkeyDown视为为您的应用输入互动的更可靠的方法:

@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {

    switch (keyCode) {
        case KeyEvent.KEYCODE_MEDIA_PLAY:{
            if (!mPlaying) {
                startSlideShow();
            }
            mPlaying = true;
            break;
        }
        case KeyEvent.KEYCODE_MEDIA_PAUSE:{
            mPlaying = false;
            showStatusToast(R.string.slideshow_paused);
        }
    }
    return super.onKeyDown(keyCode, event);
}

作为Android Smart Google TV API的一部分,您还可以对更大的屏幕分辨率进行必要的调整:

   // Get the source image's dimensions
   BitmapFactory.Options options = new BitmapFactory.Options();
   options.inJustDecodeBounds = true; // this does not download the actual image, just downloads headers.
   BitmapFactory.decodeFile(IMAGE_FILE_URL, options);

   int srcWidth = options.outWidth;  // actual width of the image.
   int srcHeight = options.outHeight;  // actual height of the image.

   // Only scale if the source is big enough. This code is just trying to fit a image into a certain width.
   if(desiredWidth > srcWidth)
     desiredWidth = srcWidth;

   // Calculate the correct inSampleSize/scale value. This helps reduce memory use. It should be a power of 2.
   int inSampleSize = 1;
   while(srcWidth / 2 > desiredWidth){
     srcWidth /= 2;
     srcHeight /= 2;
     inSampleSize *= 2;
   }

   float desiredScale = (float) desiredWidth / srcWidth;

   // Decode with inSampleSize
   options.inJustDecodeBounds = false;  // now download the actual image.
   options.inDither = false;
   options.inSampleSize = inSampleSize;
   options.inScaled = false;
   options.inPreferredConfig = Bitmap.Config.ARGB_8888;  // ensures the image stays as a 32-bit ARGB_8888 image. 
                                                         // This preserves image quality.
   Bitmap sampledSrcBitmap = BitmapFactory.decodeFile(IMAGE_FILE_URL, options);

   // Resize
   Matrix matrix = new Matrix();
   matrix.postScale(desiredScale, desiredScale);
   Bitmap scaledBitmap = Bitmap.createBitmap(sampledSrcBitmap, 0, 0,
       sampledSrcBitmap.getWidth(), sampledSrcBitmap.getHeight(), matrix, true);
   sampledSrcBitmap = null;

   // Save
   FileOutputStream out = new FileOutputStream(LOCAL_PATH_TO_STORE_IMAGE);
   scaledBitmap.compress(Bitmap.CompressFormat.JPEG, 100, out);
   scaledBitmap = null;

您还可以轻松地将液晶电视转换为智能电视,并开始播放和测试您的谷歌电视应用程序的行为方式。为此,您只需要将手放在adaptor kit

事实上,联想正在发布一款28英寸4K显示器(ThinkVision 28),它也运行Android,允许您运行所有常用的媒体流应用程序,Kogan正在执行相同。

enter image description here

在使用小工具时进一步黑客攻击,您甚至可以在电视上使用MHL HDMI来移动手机或将其用作computer

enter image description here

因此,使用MHL 3.0 does 4K video输出的Android是一个现实,好的开发人员已经可以根据所使用的设备对其应用程序进行必要的分辨率和输入调整。

如果您主要关注的是提升效果并优化视频流,您可以考虑以下选项:

  • NDK:您决定采用一些库或实现您自己的实际用C ++编写的程序来优化video streaming
  • RenderScript:它使用C99语法和最终编译为native code的新API。虽然这种语法众所周知,但使用该系统存在学习曲线,因为API不是。
  • OpenCL:用于图形加速,并提供许多用于3D渲染和视频流高performance的工具。

http://developer-static.se-mc.com/wp-content/blogs.dir/1/files/2013/10/OpenCL_final.jpg

实际上,OpenCL中的代码类似于C / C ++:

    for (int yy=-filterWidth; yy<=filterWidth; ++yy)
    {
      for (int xx=-filterWidth; xx<=filterWidth; ++xx)
       {
          int thisIndex = (y + yy) * width + (x + xx);
          float4 currentPixel = oneover255 *convert_float4(srcBuffer[thisIndex]);
          float domainDistance = fast_distance((float)(xx), (float)(yy));
          float domainWeight = exp(-0.5f * pow((domainDistance/sigmaDomain),2.0f));

          float rangeDistance = fast_distance(currentPixel.xyz, centerPixel.xyz);
          float rangeWeight = exp(-0.5f * pow((rangeDistance/sigmaRange),2.0f));

          float totalWeight = domainWeight * rangeWeight ;
          normalizeCoeff += totalWeight;

          sum4 += totalWeight * currentPixel;
       }
    }

就ARM微处理器功能而言,值得一提的是适用于Android机顶盒的Sigma Designs SMP8756 ARM,旨在实现完整的高效视频编码(HEVC)功能。

  • 双线性过滤

要调整图片/视频的大小,您需要的是应用bilinear filtering。双线性插值是使用隔行扫描视频帧中的每个中间场来生成全尺寸目标图像的过程。字段are used上的所有奇数或所有偶数行。然后在线之间和相邻像素之间执行插值,以产生用于逐行扫描输出的整个非隔行扫描帧。

enter image description here

要实现针对所需大小正确调整图像,可以使用大量可用于此目的的良好算法,例如image scaling的一些OpenCL功能,同样适用于本机C ++其他功能选项也是available