sd 图片编解码_硬件编解码和软件编解码 - CSDN
精华内容
参与话题
  • SDWebImage-解码、压缩图像

    千次阅读 2018-03-13 07:13:32
    在我们使用 UIImage 的时候,创建的图片通常不会直接加载到内存,而是在渲染的时候默认在主线程上再进行解码并加载到内存。这就会导致 UIImage 在渲染的时候效率上不是那么高效。为了提高效率所以在SDWebImage中就...

    一、简单介绍

    研究了下SDWebImage的源码,借鉴了别人的一些资料,感觉逐渐的明白的一些原理,现在就来记录下。

    在我们使用 UIImage 的时候,创建的图片通常不会直接加载到内存,而是在渲染的时候默认在主线程上再进行解码并加载到内存。这就会导致 UIImage 在渲染的时候效率上不是那么高效。为了提高效率所以在SDWebImage中就采取在子线程中进行解码图片。

    这里再介绍下为什么创建图像的时候是需要解码的因为一般下载的图片或者是我们手动拖进工程的图片都是PNG 或者JPEG或者是其他格式的图片,这些图片都是经过编码压缩后的图片数据,并不是我们的控件可以直接显示的位图,如果我们直接使用加载渲染图片到手机上的时候,系统默认会在主线程立即进行图片的解码工作,这个过程就是把图片数据解码成可以供给控件直接显示的位图数据,由于这个解码操作比较耗时,并且默认是在主线程进行,所以如果加载过多的图片的话肯定是会发生卡顿现象的。

    二、源码分析

    首先介绍的是根据data来解码成一个UIImage对象的方法

    - (UIImage *)decodedImageWithData:(NSData *)data {
        if (!data) {
            return nil;
        }
        
        UIImage *image = [[UIImage alloc] initWithData:data];
        //如果是MAC端就直接返回image
    #if SD_MAC
        return image;
    #else
        if (!image) {
            return nil;
        }
        //不然的话就要去获取数据中图片的方向
        UIImageOrientation orientation = [[self class] sd_imageOrientationFromImageData:data];
        //如果图片的方向不是默认向上的话就要去根据其图片信息的方向来重新创建图片
        if (orientation != UIImageOrientationUp) {
            image = [[UIImage alloc] initWithCGImage:image.CGImage scale:image.scale orientation:orientation];
        }
        
        return image;
    #endif
    }

    这里再介绍下关于获取图片方向的sd_imageOrientationFromImageData方法,这里面其实就是根据imageData去创建CGImageSourceRef然后去读取其图像的属性

    + (UIImageOrientation)sd_imageOrientationFromImageData:(nonnull NSData *)imageData {
        UIImageOrientation result = UIImageOrientationUp;
        //创建从Core Foundation 数据对象中读取的图像源
        /**
         参数1:
         参数2:指定额外创建option字典。我们可以在options字典中包含的键来创建图像源。
         比如说
         kCGImageSourceTypeIdentifierHint
         kCGImageSourceShouldAllowFloat
         kCGImageSourceShouldCache
         kCGImageSourceCreateThumbnailFromImageIfAbsent
         kCGImageSourceCreateThumbnailFromImageAlways
         kCGImageSourceThumbnailMaxPixelSize
         kCGImageSourceCreateThumbnailWithTransform
         */
        CGImageSourceRef imageSource = CGImageSourceCreateWithData((__bridge CFDataRef)imageData, NULL);
        if (imageSource) {
            
            //调用CGImageSourceCopyPropertiesAtIndex的时候会才去读取图像元数据
            //返回图像源中指定位置的图像的属性。
            /**
             参数1:一个图像的来源
             参数2:你想要获得的属性的索引。该指数是从零开始的。index参数设置获取第几张图像
             参数3:可以用来请求其他选项的字典。
             返回包含与图像相关联的属性的字典。请参见CGImageProperties,以获得可以在字典中使用的属性列表。
             CGImageProperties引用定义了代表图像I/O框架使用的图像特征的常量。
             */
            CFDictionaryRef properties = CGImageSourceCopyPropertiesAtIndex(imageSource, 0, NULL);
           //判断属性存不存在,如果不存在就用默认的UIImageOrientationUp方向
           if (properties) {
                
                //typedef const void *CFTypeRef;
                CFTypeRef val;
                NSInteger exifOrientation;
                
                //返回与给定键关联的值,这里就是返回方向键值所对应的内容
                val = CFDictionaryGetValue(properties, kCGImagePropertyOrientation);
                //如果其存在的话,就去获取
                if (val) {
                    //将CFNumber对象转换为指定类型的值
                    /**
                     参数1:要检查的CFNumber对象。
                     参数2:指定要返回的数据类型的常量。请参阅CFNumberType以获得可能的值列表。
                     参数3:返回的时候包含数字的值
                     */
                    CFNumberGetValue(val, kCFNumberNSIntegerType, &exifOrientation);
                    
                    //转换exif中信息的方向到iOS里面的方向
                    result = [SDWebImageCoderHelper imageOrientationFromEXIFOrientation:exifOrientation];
                } // else - if it's not set it remains at up
                CFRelease((CFTypeRef) properties);
            } else {
                //NSLog(@"NO PROPERTIES, FAIL");
            }
         //释放这个图像源
         CFRelease(imageSource);
        }
      //返回结果  
      return result;
    }

    这里再介绍的介绍下imageOrientationFromEXIFOrientation的方法,这个方法就是转换一个EXIF信息中图像方向到iOS中的方向说白了就是从NSInteger转换为UIImageOrientationUp这样的枚举值。

    // Convert an EXIF image orientation to an iOS one.
    + (UIImageOrientation)imageOrientationFromEXIFOrientation:(NSInteger)exifOrientation {
        // CGImagePropertyOrientation is available on iOS 8 above. Currently kept for compatibility
        UIImageOrientation imageOrientation = UIImageOrientationUp;
        switch (exifOrientation) {
            case 1:
                imageOrientation = UIImageOrientationUp;
                break;
            case 3:
                imageOrientation = UIImageOrientationDown;
                break;
            case 8:
                imageOrientation = UIImageOrientationLeft;
                break;
            case 6:
                imageOrientation = UIImageOrientationRight;
                break;
            case 2:
                imageOrientation = UIImageOrientationUpMirrored;
                break;
            case 4:
                imageOrientation = UIImageOrientationDownMirrored;
                break;
            case 5:
                imageOrientation = UIImageOrientationLeftMirrored;
                break;
            case 7:
                imageOrientation = UIImageOrientationRightMirrored;
                break;
            default:
                break;
        }
        return imageOrientation;
    }

    接下来开始讲下解码图像,在这里面其实刚开始先判断能不能解码图片,这个方法是这样的

    + (BOOL)shouldDecodeImage:(nullable UIImage *)image {
        // Prevent "CGBitmapContextCreateImage: invalid context 0x0" error
        //如果图片都为空,那肯定返回的是NO
        if (image == nil) {
            return NO;
        }
        //不能编码动画图片
        // do not decode animated images
        if (image.images != nil) {
            return NO;
        }
        
        CGImageRef imageRef = image.CGImage;
        
        BOOL hasAlpha = SDCGImageRefContainsAlpha(imageRef);
        //不支持解码含有透明度的图片
        // do not decode images with alpha
        if (hasAlpha) {
            return NO;
        }
        
        return YES;
    }
    

    回到这个方法,其实主要的过程就是CGBitmapContextCreate创建一个位图上下文→CGContextDrawImage绘制原始位图到上下文→CGBitmapContextCreateImage创建解码后的新位图。

    - (nullable UIImage *)sd_decompressedImageWithImage:(nullable UIImage *)image {
        if (![[self class] shouldDecodeImage:image]) {
            return image;
        }
        
        // autorelease the bitmap context and all vars to help system to free memory when there are memory warning.
        // on iOS7, do not forget to call [[SDImageCache sharedImageCache] clearMemory];
        //新建自动释放池,将bitmap context和临时变量都添加到池中在方法末尾自动释放以防止内存警告
        @autoreleasepool{
            
            //获取传入的UIImage对应的CGImageRef(位图)
            CGImageRef imageRef = image.CGImage;
            //获取彩色空间
            CGColorSpaceRef colorspaceRef = [[self class] colorSpaceForImageRef:imageRef];
            
            //获取高和宽
            size_t width = CGImageGetWidth(imageRef);
            size_t height = CGImageGetHeight(imageRef);
            
            // kCGImageAlphaNone is not supported in CGBitmapContextCreate.
            // Since the original image here has no alpha info, use kCGImageAlphaNoneSkipLast
            // to create bitmap graphics contexts without alpha info.
            
            //初始化bitmap graphics context 上下文
            /*
             参数1:指向要呈现绘图的内存中目标的指针。这个内存块的大小至少应该是(bytesPerRow*height)字节。
             如果希望此函数为位图分配内存,则传递NULL。这将使您不必管理自己的内存,从而减少内存泄漏问题。
            参数2:所需宽度,以像素为单位
            参数3:所需高度
            参数4:用于内存中一个像素的每个组件的比特数
            参数5:位图中每一行使用的内存字节数。如果数据参数为NULL,传递值为0,则会自动计算值。
            参数6:颜色空间
            参数7:指定位图是否应该包含一个alpha通道、alpha通道在一个像素中的相对位置,以及关于像素组件是浮点数还是整数值的信息。
                  指定alpha通道信息的常量使用CGImageAlphaInfo类型声明,可以安全地传递给该参数。
                  您还可以传递与CGBitmapInfo类型相关联的其他常量。
                  例如,如何指定颜色空间、每个像素的位元、每个像素的位元以及位图信息,请参阅图形上下文。
             */
            //kCGBitmapByteOrderDefault 是默认模式,对于iPhone 来说,采用的是小端模式
            CGContextRef context = CGBitmapContextCreate(NULL,
                                                         width,
                                                         height,
                                                         kBitsPerComponent,
                                                         0,
                                                         colorspaceRef,
                                                         kCGBitmapByteOrderDefault|kCGImageAlphaNoneSkipLast);
            //如果上下文为NULL,就返回image
            if (context == NULL) {
                return image;
            }
            
            
            // Draw the image into the context and retrieve the new bitmap image without alpha
            /**
            这里创建的contexts是没有透明因素的。在UI渲染的时候,实际上是把多个图层按像素叠加计算的过程,需要对每一个像素进行 RGBA 的叠加计算。
            当某个 layer 的是不透明的,也就是 opaque 为 YES 时,GPU 可以直接忽略掉其下方的图层,这就减少了很多工作量。
            这也是调用 CGBitmapContextCreate 时 bitmapInfo 参数设置为忽略掉 alpha 通道的原因。而且这里主要针对的就是解码图片成位图
            */
         
            //将CGImageRef对象画到上面生成的上下文中,且将alpha通道移除
            CGContextDrawImage(context, CGRectMake(0, 0, width, height), imageRef);
            
            //使用上下文创建位图
            CGImageRef imageRefWithoutAlpha = CGBitmapContextCreateImage(context);
            //从位图创建UIImage对象,返回含有指定的方向和scale的图片
            UIImage *imageWithoutAlpha = [[UIImage alloc] initWithCGImage:imageRefWithoutAlpha scale:image.scale orientation:image.imageOrientation];
            //释放CG对象
            CGContextRelease(context);
            CGImageRelease(imageRefWithoutAlpha);
            
            return imageWithoutAlpha;
        }
    }

    下面再介绍下关于SDWebImage中的图片压缩的算法,其实简单来说就是将图像矩阵按照规则分割成小型子矩阵进行压缩,然后插值拼接,而且这个算法也是借鉴苹果的,官方Demo链接:https://developer.apple.com/library/content/samplecode/LargeImageDownsizing/Introduction/Intro.html  关于这个算法,苹果的定义就是此代码示例演示了一种支持在有限的内存环境中显示超大图像的方法,方法是将磁盘上的大图像转换为内存中较小的图像。这在原始图像太大而无法按照要显示的要求放入内存的情况下很有用 我目前也只能理解个大概,还有些细节方面还没想到,它是怎么进行优化的,代码都有注释。现在先简单的介绍下回用到的宏吧。

    // 每个像素占4个字节大小 共32位
    static const size_t kBytesPerPixel = 4;
    //每个通道由8位组成
    static const size_t kBitsPerComponent = 8;
    
    /*
     * Defines the maximum size in MB of the decoded image when the flag `SDWebImageScaleDownLargeImages` is set
     * Suggested value for iPad1 and iPhone 3GS: 60.
     * Suggested value for iPad2 and iPhone 4: 120.
     * Suggested value for iPhone 3G and iPod 2 and earlier devices: 30.
     该参数用于设置内存占用的最大字节数。默认为60MB,下面给出了一些旧设备的参考数值。如果图片大小大于该值,则将图片以该数值为目标进行压缩。
     */
    static const CGFloat kDestImageSizeMB = 60.0f;
    
    /*
     * Defines the maximum size in MB of a tile used to decode image when the flag `SDWebImageScaleDownLargeImages` is set
     * Suggested value for iPad1 and iPhone 3GS: 20.
     * Suggested value for iPad2 and iPhone 4: 40.
     * Suggested value for iPhone 3G and iPod 2 and earlier devices: 10.
     设置压缩时对于源图像使用到的*块*的最大字节数。原图方块的大小,这个方块将会被用来分割原图,默认设置为20M。
     */
    static const CGFloat kSourceImageTileSizeMB = 20.0f;
    //1M有多少字节
    static const CGFloat kBytesPerMB = 1024.0f * 1024.0f;
    //1M有多少像素 262144个像素
    static const CGFloat kPixelsPerMB = kBytesPerMB / kBytesPerPixel;
    //目标总像素kDestImageSizeMB为60MB
    static const CGFloat kDestTotalPixels = kDestImageSizeMB * kPixelsPerMB;
    //目标图像的像素点个数
    static const CGFloat kTileTotalPixels = kSourceImageTileSizeMB * kPixelsPerMB;
    //目标重叠像素大小
    static const CGFloat kDestSeemOverlap = 2.0f;   // the numbers of pixels to overlap the seems where tiles meet.

    关于算法的描述,位图其实简单可以描述为是由像素组成的矩阵,所以下面其实就是把图像当做一个矩阵(或多个矩阵的组合)来进行处理的。

    - (nullable UIImage *)sd_decompressedAndScaledDownImageWithImage:(nullable UIImage *)image {
        
        //1、判断图片是否支持解码
        if (![[self class] shouldDecodeImage:image]) {
            return image;
        }
        //2、判断图片是否支持缩小也就是压缩,总像素要大于15728640才能压缩,也就是kDestTotalPixels的大小
        if (![[self class] shouldScaleDownImage:image]) {
            return [self sd_decompressedImageWithImage:image];
        }
        
        //声明压缩目标用的上下文
        CGContextRef destContext;
        
        // autorelease the bitmap context and all vars to help system to free memory when there are memory warning.
        // on iOS7, do not forget to call [[SDImageCache sharedImageCache] clearMemory];
        @autoreleasepool {
            //3. 获取源图像位图
            CGImageRef sourceImageRef = image.CGImage;
            //4. 源图像尺寸,存储在CGSize结构体中
            CGSize sourceResolution = CGSizeZero;
            sourceResolution.width = CGImageGetWidth(sourceImageRef);
            sourceResolution.height = CGImageGetHeight(sourceImageRef);
            //5. 计算源图像总的像素点个数
            float sourceTotalPixels = sourceResolution.width * sourceResolution.height;
            
            // Determine the scale ratio to apply to the input image
            // that results in an output image of the defined size.
            // see kDestImageSizeMB, and how it relates to destTotalPixels.
            
            //6. 获取原图像和目标图像的比例(以像素点个数为基准),这里是以60MB的像素点为标准了 60MB的总像素要除以原文件的总像素小于1的
            float imageScale = kDestTotalPixels / sourceTotalPixels;
            
            //7. 使用imagescale计算目标图像的宽高,所以我目标图像的目标就是到60MB
            CGSize destResolution = CGSizeZero;
            destResolution.width = (int)(sourceResolution.width*imageScale);
            destResolution.height = (int)(sourceResolution.height*imageScale);
            
            //8. 进行图像绘制前的准备工作
            // current color space
            CGColorSpaceRef colorspaceRef = [[self class] colorSpaceForImageRef:sourceImageRef];
            
            // kCGImageAlphaNone is not supported in CGBitmapContextCreate.
            // Since the original image here has no alpha info, use kCGImageAlphaNoneSkipLast
            // to create bitmap graphics contexts without alpha info.
            //创建位图上下文
            destContext = CGBitmapContextCreate(NULL,
                                                destResolution.width,
                                                destResolution.height,
                                                kBitsPerComponent,
                                                0,
                                                colorspaceRef,
                                                kCGBitmapByteOrderDefault|kCGImageAlphaNoneSkipLast);
            
            if (destContext == NULL) {
                return image;
            }
            /*9. 设置图像插值的质量为高,设置图形上下文的插值质量水平CGContextSetInterpolationQuality允许上下文以各种保真度水平内插像素。
             在这种情况下,kCGInterpolationHigh通过最佳结果*/
            CGContextSetInterpolationQuality(destContext, kCGInterpolationHigh);
            
            //现在定义矩形的大小,用于增量位块从输入图像到输出图像。
            // Now define the size of the rectangle to be used for the
            // incremental blits from the input image to the output image.
            
            //由于iOS从磁盘检索图像数据的方式,我们使用源图像宽度与源图像的宽度相等
            // we use a source tile width equal to the width of the source
            // image due to the way that iOS retrieves image data from disk.
            
            /*iOS必须在全宽度的“波段”中从磁盘上解码图像,即使当前的图形上下文被剪切到band内的一个subrect中。因此,我们充分利用了所有的像素数据,
            这些数据是由解码操作产生的,通过将我们的平铺大小与输入图像的宽度匹配。
            */
            // iOS must decode an image from disk in full width 'bands', even
            // if current graphics context is clipped to a subrect within that
            // band. Therefore we fully utilize all of the pixel data that results
            // from a decoding opertion by achnoring our tile size to the full
            // width of the input image.
            //10. 定义一个称为*块*的增量矩形(incremental blits,即矩形大小在每一次迭代后都不断增长/减小)用于计算从源图像到目标图像的输出。
            CGRect sourceTile = CGRectZero;
            
            //源块的宽度等于源图像的宽度,宽度要保持一定
            sourceTile.size.width = sourceResolution.width;
            
            //  块的高度是动态的,我们前面指定了源tile的值,也就是kTileTotalPixels目标图像的像素点个数 根据宽度计算动态的高度
            // The source tile height is dynamic. Since we specified the size
            // of the source tile in MB, see how many rows of pixels high it
            // can be given the input image width.
            sourceTile.size.height = (int)(kTileTotalPixels / sourceTile.size.width );
            
            // *块*的起始x值总是为0
            sourceTile.origin.x = 0.0f;
            //输出的tile与输入的tile比例相同,但图像按比例缩放。图像按比例缩放就要用到插值运算了
            // The output tile is the same proportions as the input tile, but
            // scaled to image scale.
            
            //同样的方式初始化目标图像的块
            CGRect destTile;
            //宽度 = 目标图像的宽度
            destTile.size.width = destResolution.width;
            //高度 = 源图像块的高度 * 缩放比例
            destTile.size.height = sourceTile.size.height * imageScale;
            
            destTile.origin.x = 0.0f;
            // The source seem overlap is proportionate to the destination seem overlap.
            // this is the amount of pixels to overlap each tile as we assemble the ouput image.
            //11、计算源图像与压缩后目标图像重叠的像素大小。这里就是按照sourceResolution.height和destResolution.height进行相比
            float sourceSeemOverlap = (int)((kDestSeemOverlap/destResolution.height)*sourceResolution.height);
            
            CGImageRef sourceTileImageRef;
            //计算组装输出图像所需的读/写操作数
            // calculate the number of read/write operations required to assemble the
            // output image.
            //源图像的高度除以分割源图像的方块的高度得出源图像被分割成多少个方块并赋值给 iterations,再做取余运算取得分割的最大的整数
            int iterations = (int)( sourceResolution.height / sourceTile.size.height );
            
            //12、如果tile height不均匀地分割图像高度,则添加另一个迭代来解释剩余的像素。
            // If tile height doesn't divide the image height evenly, add another iteration
            // to account for the remaining pixels.
            int remainder = (int)sourceResolution.height % (int)sourceTile.size.height;
            if(remainder) {
                iterations++;
            }
            // Add seem overlaps to the tiles, but save the original tile height for y coordinate calculations.
            
            //定义一个 float 变量 sourceTitleHeightMinusOverlap 存放那个用来分割源图像,大小为 20 MB 的方块的高度。
            float sourceTileHeightMinusOverlap = sourceTile.size.height;
            
             //用于切割源图像大小为 20 MB 的方块的高度加上源图像与源图像分割方块的像素重叠数
            sourceTile.size.height += sourceSeemOverlap;
            
            //destTile.size.height = sourceTile.size.height * imageScale;
            //目标图像的分割方块的高度加上 kDestSeemOverlap(像素重叠数赋值为 2)
            destTile.size.height += kDestSeemOverlap;
            
            //13、进行for 循环,y 从0开始,到小于源图像被分割的块数
            for( int y = 0; y < iterations; ++y ) {
                @autoreleasepool {
                    //sourceTile 和 destTile 都是宽度和高度固定的,x 值为 0,只有 y  值随着循环的 y  值在变化,sourceTile 的 y 值在递增,destTile 的 y 值在递减,只有最最后一次循环中,如果有余数那么size就会发生变化,这是因为最后一次中去取源图像的高度其实
                    
                    //sourceTileHeightMinusOverlap = sourceTile.size.height;
                    sourceTile.origin.y = y * sourceTileHeightMinusOverlap + sourceSeemOverlap;
                    destTile.origin.y = destResolution.height - (( y + 1 ) * sourceTileHeightMinusOverlap * imageScale + kDestSeemOverlap);
                    /*14、在用到在一张图片中截取某一部分图片中,用到CGImageRef类中的CGImageCreateWithImageInRect函数
                    然后循环的从源图像的 sourceImageRef 根据大小为 20 MB 的分割块的不同 CGRect 的矩形区域内获取 sourceTileImageRef,这里sourceTile的高度是根据kTileTotalPixels / sourceTile.size.width
                     */
                    sourceTileImageRef = CGImageCreateWithImageInRect(sourceImageRef, sourceTile);
                    
                    //计算剩余的像素,所采用的方法
                    if( y == iterations - 1 && remainder ) {
                    //destTile.size.height = sourceTile.size.height * imageScale;
                        float dify = destTile.size.height;
                      
                        destTile.size.height = CGImageGetHeight( sourceTileImageRef ) * imageScale;
                        dify -= destTile.size.height;
                        destTile.origin.y += dify;
                    }
                    //15、绘制图像到图形上下文指定的destTile范围中
                    CGContextDrawImage( destContext, destTile, sourceTileImageRef );
                    CGImageRelease( sourceTileImageRef );
                }
            }
            
            CGImageRef destImageRef = CGBitmapContextCreateImage(destContext);
            CGContextRelease(destContext);
            if (destImageRef == NULL) {
                return image;
            }
        //16、输出图像
        UIImage *destImage = [[UIImage alloc] initWithCGImage:destImageRef scale:image.scale orientation:image.imageOrientation];
            CGImageRelease(destImageRef);
            if (destImage == nil) {
                return image;
            }
            return destImage;
        }
    }

    压缩过程简单流程


    参考文章:SDWebImage源码解读_之SDWebImageDecoder

                   SDWebImage源码解析之编解码

                   SDWebImage源码解析(三)——SDWebImage图片解码/压缩模块

    展开全文
  • 基于STM32的多功能MP3设计 毕业设计(论文)文献综述

    中国计量学院

    毕业设计(论文)文献综述

     

     

    学生姓名:   卢   杰   学 号:  xxxxxxxxx 

    专    业:        电子科学与技术            

    班    级:          10电子1                

    设计(论文)题目:

          基于STM32的多功能MP3设计       

    指导教师:          叶有祥老师               

    二级学院:       光学与电子科技学院          

     

     

     

     

     

     

     

     

     

     

    2014 年 03 月 17 日

     

     

     

    前言

    MP3全称是MPEG Layer 3,狭义的讲就是以MPEG Layer 3标准压缩编码的一种音频文件格式,是一种高质量音乐压缩标准,给音频产业带来了具大的冲击,采用MP3压缩的数据量可以缩小到1/12,音质却没有多少损失,近乎于CD的音质。我们都知道传统音乐文件在网络上传播时,主要用Winamp等播放软件进行播放,使MP3音乐无法脱离计算机进行播放,给音乐欣赏带来不便,而由于人们对MP3音乐的较小数据量和高质量的播放效果所吸引,开始想办法将MP3音乐播放功能单独分离出来,这样就产生了MP3播放器。它的记录媒介是芯片或SD卡,无需转动部件,彻底摆脱了磁带和光碟的束缚,因而抗震和节电性能更好。随着MP3播放器技术的发展,人们对MP3播放器的要求也越来越高,制造商在MP3播放器的选型设计开发和功能等领域等方面做了很多努力,便携式多功能MP3播放器的应用也越来越具有实际应用价值和潜在的市场要求,各大公司纷纷推出了自己的MP3播放器产品,IC供应商也提供了众多的MP3解码芯片及其解决方案,这使得MP3播放器的研制与生产变得更加容易,成本也大大降低,市场更加广阔。以前的MP3播放器大部分都是基于ARM公司最新Cortex-M3内核的STM32系列微控制器,利用该处理器内置的SPI接口对SD存储卡进行控制,并对MP3音频文件进行硬解码或者软解码实现MP3的播放,并使用LCD显示歌词、调节音量等,还有的扩展了USB连接,使MP3播放器可以直接从PC上拷贝音频文件等。

     

    主题

    1、常用模块

    MP3播放器一般设计方案是以微控制器为主控芯片,比如STM32,从SD卡中读取音乐文件的数据,送音频解码芯片进行解码,通过数模转换器将解出来的数字信号转换成模拟信号,再把转换后的模拟音频放大,低通滤波后送到耳机。有的还加入了USB连接,PC机可通过USB接口直接对SD卡进行读写操作,以方便拷贝音频文件。下面先来介绍一下几个常用模块。

    1.1、STM32微处理器

    Cortex M3是ARM公司最新推出的基于ARM v7体系架构的处理器核, 具有高性能、低成本、低功耗的特点,专门为嵌入式应用领域设计。ARM v7架构采用了Thumb 2技术,它是在ARM的Thumb代码压缩技术的基础上发展起来的, 并且保持了对现存ARM解决方案完整的代码兼容性。Thumb 2技术比纯ARM代码少使用31%的内存, 减小了系统开销, 同时能够提供比Thumb技术高出38%的性能。在中断处理方面,Cortex M3集成了嵌套向量中断控制器NVIC ( Nested Vectored Interrupt Controller )。NVIC是Cortex M3处理器的一个紧耦合部分,可以配置1~240个带有256个优先级、8级抢占优先权的物理中断,为处理器提供出色的异常处理能力。同时,抢占、尾链、迟到技术的使用,大大缩短了异常事件的响应时间。Cortex M3异常处理过程中有硬件自动保存和恢复处理器状态,进一步缩短了中断响应时间,降低了软件设计的复杂性。此外Cortex M3还具备高度集成化的特点,大大减小了芯片面积,内部集成了许多紧耦合系统外设,合理利用了芯片空间, 使系统满足下一代产品的控制需求。STM 32系列是基于Cortex M3核的微控制器,它在Cortex M3内核的基础上扩展了高性能的外围设备。

    1.2、音频编解码器

    现在的MP3播放器有采用VS1053音频编解码芯片作为音频文件的硬件解码方案,VS1053能解码MP3、WMA、WAV等格式的音频文件,并且还能进行ADPCM编码,包含一个低功耗,高性能的DSP处理器,VS1053采用SPI的通信方式,通过判断DREQ来控制数据传输,如果此引脚为高电平则发送数据,如果为低电平则停止发送数据,因为音频编解码芯片自带立体DAC输出,如果解码成功,可以用示波器从LEFT和RIGHT引脚测得波形,并能够直接驱动耳机。当然也有使用VS1003音频编解码芯片的,它内部包含1个高性能、低功耗的DSP处理核,1个工作内存,1片可供用户程序使用的5. 5KB RAM,1个串行SPI总线接口,1个高质量的采样频率可调的过采样DAC以及1个16位的采样ADC。无论是选择VS1003还是VS1053,MP3播放过程是STM32通过SPI接口将数据从SD卡中取出, 然后通过SPI接口送至解码芯片VS1003/VS1053解码播放。

    1.3、TFT液晶显示模块

    一般传统的显示屏都是使用LCD1602或LCD12864,由于它们像素和图片显示效果不佳,后来MP3播放器都采用了TFT-LCD,它的显示驱动芯片一般采用ILI9320,其有320*240的分辨率,供电电压2.5~3.3V,16位数据接口,高的对比,高亮度,低功耗模拟电阻式触摸屏。

    1.4、SD卡模块

    一般MP3播放器系统需要大容量的存储器来保存音乐、图片、汉字字库等文件,而EEPROM的容量不足以满足MP3播放器系统的需求,所以在MP3播放器设计中需要添加一个SD卡模块。SD卡即安全数码卡,是一种基于半导体快闪记忆器的新一代记忆设备,如今己在各种嵌入式设备上得到了广泛的应用,它具有外观小巧安全性高数据传输率快存储容量大等优点。

    2、系统硬件设计

    MP3播放器的主要功能是播放常见的所有音频文件,如MP3、WMA、WAV文件,可控制音量增减,通过LCD显示歌曲名字和播放状态等,有的实现了读卡器功能,PC机可通过USB接口直接对SD卡进行读写操作,以方便拷贝音频文件,当MP3播放器插入到USB接口时,系统执行USB通讯功能。下面分别介绍传统MP3播放器系统的存储模块SD卡、解码芯片VS1003/VS1053与ST M 32的硬件连接情况。

    2.1、SD卡与STM32的连接

    一般使用STM32内部接口SPI与SD卡进行通信,具体的硬件引脚连接情况如下:

    一个普通IO口,低电平有效,连接到 SD卡的片选引脚CD/DATA3。SPI在和SD卡进行通信时,需要将这个普通IO口拉低才能对SD卡进行操作。

    STM32内部接口SPI的主输出从输入(MOSI)信号线。这里STM32是主设备, SD卡是从设备。数据流的传输方向是从STM32传输给SD卡。该信号线用于传输一些控制命令来完成SD卡的操作,如读、写等。

    STM32内部接口SPI的时钟(SCLK )信号线。可设置SPI的时钟频率来调整读取SD卡数据的快慢。

    STM32内部接口SPI的主输入从输出(MISO)信号线。数据的传输方向是从SD卡传输给STM32,主要返回SD卡的一些状态、内部寄存器值等。

    另一个普通IO口,用于检测SD卡是否完全插入。当SD卡完全插入时,这个IO口为低电平, 否则为高电平。

    2.2、音频编解码芯片与STM32的连接

    常规的设计是使用STM32内部接口SPI与音频编解码芯片进行通信,这里的音频编解码芯片可以是VS1003或者VS1053等,下面以这两款芯片来介绍其引脚连接情况。VS1003或者VS1053的中断请求引脚。当VS1003/VS1053内部数据已处理完毕,需要新的数据时,DREQ拉高。STM32根据这个信号来给VS1003/VS1053发送新的数据流。SCLK连接到STM32内部接口 SPI的时钟(SCLK)信号线。SO连接到STM32内部接口SPI的主输入从输出( MISO)信号线。这里STM32是主设备,音频编解码芯片是从设备。数据流的传输方向是从音频编解码芯片传输给 STM32。主要用于读取音频编解码芯片的一些状态和内部寄存器值,比如寄存器测试返回的内部寄存器的值。SI连接到STM32内部接口SPI的主输出从输入(MOSI)信号线。这里STM32是主设备,音频编解码芯片是从设备。数据流方向是从STM32传输给音频编解码芯片,主要传输给音频编解码芯片一些控制命令、MP3/WMA数据流等。音频编解码芯片的片选CS是低电平有效,如果拉低该引脚,那么通过SPI传输的是控制信号。控制信号包括读写音频编解码芯片的内部寄存器、对音频编解码芯片进行初始化、设置左右声道音量等。DCS也是低电平有效,如果拉低该引脚,那么通过SPI传输的是数据信号。比如在向音频编解码芯片传输MP3/WMA的数据流时需要拉低该引脚。RESET引脚是低电平有效, 拉低该引脚则硬件复位音频编解码芯片。

    3、系统软件设计

    采用STM32为控制器方案的软件由集成开发工具MDK专业版开发,它具有强大的编译、 链接和调试功能。基本工作过程大致为是STM32通过一个SPI从SD卡中读取MP3/WMA文件,将所读取的数据流通过另一个SPI发送到音频编解码芯片中解码播放,如果有USB通信功能,PC机可通过USB总线读写SD卡的内容,传送MP3/WMA等文件,LCD显示屏用于显示MP3的文件名、 播放状态。由于STM32的一个SPI读取SD卡文件的速度远超过音频编解码芯片播放数据流的速度,因此音频编解码芯片在播放来自STM32的另一个SPI的数据流期间, 这个SPI能从SD卡中读取下次播放所需的数据,不会产生声音不连续的情况。由于使用了2个SPI接口,相互之间无干扰,且提高了文件系统的效率, 因此本系统能得到非常高品质的音乐。

    开机后首先检测硬件资源及软件资源,实现系统自检,自检完成后,自动加载功能菜单,并在触摸屏上显示,然后再根据用户在触摸屏上的选择,进行相应的操作。MP3播放器的核心功能是实现音频播放,这需要获得相应的音乐文件数据,根据文件的存储格式并结合SD卡读取驱动,得到相应的文件数据,每次读取多少个字节,当已经初始化完成并等待接收数据,DREQ引脚为高电平时,将读到的数据以每次32字节的速度送入到音频编解码芯片的RAM中,音频编解码芯片会自动去处理这些数据并得到模拟音频信号。

     

    总结

    上面介绍了一种基于STM32利用SPI读取SD卡里面的音频文件,在送音频编解码芯片硬解码,播放MP3音乐。但是这些设计只是做到了一个最基本的MP3播放器,主要功能有播放解码芯片支持的所有音频文件,如MP3、WMA、WAV文件,控制音量增减,通过LCD显示歌曲名字和播放状态等。现在音乐手机、PAD大行其道,他们都具备MP3播放功能,如果MP3播放器不改进,肯定是要被淘汰的。基于以上分析,MP3播放器最好设计成一个多功能的,比如是集音乐播放﹑电子图书、计算器、数码相框、照相机、FC游戏机、收音机、记事本、3D效果、手写画笔、录音机、USB连接和TOM猫等众多功能为一体的MP3播放器,实现触摸控制,良好的用户界面,让用户有更多功能可以体验。

     

    参考文献

    [1] 邹捷,唐荣年等.基于嵌入式系统的MP3播放器设计[J].海南大学学报(中国水运(下半月)), 2013,13 (2):1-2.

    [2] 周兆丰,侯向锋,鲁池梅,李莲英等.uC/OS-II在STM32F103上移植的新方法[J].湖北师范学院学报(自然科学版), 2013,33 (2):1-5.

    [3] 马义德,周炜超,文芳,李柏年,李庚. 基于SPCE061A的声控MP3播放器设计[J]. 微计算机信息,2009,1(8) :301-303.

    [4] 程磊.基于STM32的MP3播放器的设计[J].苏州工业职业技术学院(内江科技), 2011,1(12):1-2.

    [5] 李宁,熊刚,徐良平等.基于 Cortex M3的MP3播放器设计[J].武汉理工大学(自然科学版), 2009,1 (2):1-5.

    [6] 颜锐,谭周文.基于STM32的多功能MP3设计[J].湖南人文科技学院(自然科学版), 2013,1 (4):1-4.

    [7] 高云红,刘志群.基于STM32的多功能音频播放器的设计[J].山东行政学院(自然科学版), 2012,1 (12):1-3.

    [8] 张学慧,朱爱珍.基于STM32的嵌入式MP3播放器的研究[J].山东科技大学(电子技术版), 2012,1 (4):1-3.

    [9] 熊锦玲,陈湘萍.基于STM32的音频解码器[J].贵州大学(自然科学版), 2013,1 (2):1-5.

    [10] 颜秋男,胡毅.STM32F103VB的SD卡在应用编程设计[J].合肥工业大学(自然科学版), 2012,2 (2):1-4.

    展开全文
  • 一、MP4播放器的概念 顾名思义,MP4播放器是一个能够播放MPEG4文件的设备,它可以叫做PVP...现在对MP4播放器的功能没有具体界定,它除了看视频的基本功能外还支持音乐播放、浏览图片,甚至部分产品还可以上网。 

     

    一、MP4播放器的概念

     

     


        顾名思义,MP4播放器是一个能够播放MPEG4文件的设备,它可以叫做PVP(Persomal Video Player,个人视频播放器),也可以叫做PMP(Portable Media Player,便携式媒体播放器)。现在对MP4播放器的功能没有具体界定,它除了看视频的基本功能外还支持音乐播放、浏览图片,甚至部分产品还可以上网。

     

        MP4播放器产品范围比较广,根据是否采用液晶屏来看,有带液晶屏幕的MP4播放器,也有不带屏幕的MP4播放器,这种不带屏幕的MP4播放器同样支持VOB、DAT、AVI和MPEG4格式的文件播放,由于没有液晶屏幕,用户必须将它和电视连接才能看视频影像,通常这种不带液晶屏幕的MP4播放器也称为多媒体硬盘,这种设备通常都具有数码伴侣功能。根据采用的存储介质来分,可分为闪存型MP4播放器和硬盘型MP4播放器,闪存型MP4播放器采用闪存芯片作为存储介质,具有功耗低、价格便宜的优点。

     

        目前视频MP3播放器也开始火起来了,也许你会问,视频MP3播放器也可用来看视频,那它和MP4播放器有什么不同呢?其实视频MP3播放器和MP4播放器最大的区别除了采用的芯片方案不同外,支持的视频格式也是不一样的,或者说文件的压缩方式不一样。但低端的闪存MP4播放器和高端的视频MP3播放器的区别不很明显,一些厂商也因此把屏幕较大的视频MP3播放器称为MP4播放器,让人弄不明白。根据习惯,对有屏幕的MP4播放器来说,它们和视频MP3播放器最直观的区别就是MP4播放器的屏幕较大,一般在2英寸以上,而视频MP3播放器的屏幕一般在2英寸以下。

     

     

     

    二、MP4的硬件架构


        与MP3播放器相比,MP4播放器的结构要复杂得多,因为MP4播放器需要性能强大的CPU或DSP、MCU芯片,以便进行视频的解码编码处理,并对LCD及USB接口等周边组件提供支持。目前,推出MP4解决方案的半导体供应商多达十几家,这些解决方案大致可分为四类:一类是以德州仪器(Ti)、飞利浦为代表的基于CPU+DSP(Digital Signal Processor,数字信号处理器)芯片的解决方案;一类则是以Intel和AMD为代表的基于通用CPU的解决方案;第三种则是以飞思卡尔(Freescale)及深圳安凯为代表的基于MCU(Micro Control Unit,微控制器)芯片的解决方案;第四种是基于双CPU的解决方案。

     

    1.基于CPU+DSP的硬件架构


        提供这类解决方案的厂商主要有SigmaDesigns、Ti和飞利浦等,这类方案中DSP芯片主要负责视频及音频的解码和编码工作,而CPU则负责档案的管理和存取、系统支持,以及对使用接口、周边组件等的控制。在这类方案中,DSP加CPU是MP4播放器的主要部件,它们要负责处理的部件包括硬盘、记忆卡及LCD显示器、外部USB接口、操控按钮等组件。基于CPU+DSP的解决方案能够支持更高复杂度的视频编解码器,如H.264,而且,它还能够通过软件升级来支持新的媒体编解码器。

     

        在CPU+DSP的解决方案中,CPU和DSP有整合式和分离式两种,整合式就是采用双核单芯片设计,DSP和CPU被整合到一块芯片中,比如Gini400采用的TMS320DM270就是双内核处理器;而分离式则意味着CPU和DSP是独立的两块芯片。

     

    2.基于通用CPU的硬件架构


        Intel和AMD提供的是以通用处理器为核心的解决方案,如Intel Xscale PXA255和Intel Xscale PXA270,AMD的Alchemy AU1200。这种架构的嵌入式处理器性能强大,如PXA270最高主频达到了624MHz,AU1200的主频达到500MHz,它们可以为媒体解码提供强大的动力。正由于采用了软解码方式,这种架构对媒体的支持最为丰富,而且扩展性强,设计者可根据需要增加软件编解码器。不过,由于使用的是通用CPU,其解码效率相对不高,通常只支持QVGA(320×240)和D1(720×576)分辨率的视频解码,要支持720P和1080i这类高清格式几乎是不可能的。另外,这类方案的还有一个缺点就是耗电量高。

     

    3.基于MCU的硬件架构


        以上两类方案中,其音视频的编解码工作均需要软件的帮助才可实现,而基于MCU的方案是由硬件实现音视频的编解码,如飞思卡尔(Freescale)的i.MX31和i.MX31L处理器,它基于ARM11,并集成了eMMA多媒体加速器;而安凯的AK3220M芯片内部集成了专用于视频的硬件解码器和用于音频的音频处理器。由于是基于硬件解码,所以这类方案支持的音视频格式种类受到了限制,例如飞思卡尔的方案能够支持MPEG4、H.263的编解码,但不支持MPEG-2。和这种情况类似,夏普的方案是基于ARM9的单颗32位MCU,支持的媒体格式也比较少。不过,采用这类方案的MP4成本最低,目前很多低档MP4播放器都是采用这类方案。

     

    4.基于双CPU的硬件架构


        从整体配合上来讲,采用双CPU芯片的MP4解决方案是最合适的,一颗CPU支持OS,一颗CPU进行解码,两颗CPU相互配合,这是目前业内最完美的解决方案。但目前还没有正式的特别稳定的这类芯片发布,业内还在持观望态度。

     

     

     

    三、MP4的底层平台


        MP4播放器所使用的嵌入式操作系统有Windows CE、Linux和厂商自行开发的操作系统,也有MP4播放器不使用任何操作系统的。

     

        目前,使用英特尔解决方案的MP4播放器基本上使用的都是WinCE平台,PMC(Portable Media Center)操作系统就是在Windows CE.NET基础上设计的,它使用了为便携式媒体中心特别提供的Windows Mobile软件,内置了Windows Media Player播放器,采用了Windows Media 9 技术:包括Windows Media Audio 9、Windows Media Video 9 和 MP3编解码器,并采用了Windows DRM(Digital rights management,数字版权管理)技术。基本上说PMC是Pocket PC的简化版,它采用了开放式架构,在应用软件上可另行扩展,只须安装第三方软件便可以实现不同的功能,如个人事务管理、网络浏览、电子书等。事实上,英特尔的解决方案支持微软WinCE 5.0和PMC操作系统,同时也可支持Linux。同样,AMD和TI的解决方案也支持WinCE和Linux。

     

        事实上,在MP4领域,Linux的阵营要比PMC阵营更为强大,采用了Linux的MP4品牌包括爱可视、Thompson RCA、Digital Cube、DM Technology、RIFA及国内的众多MP4品牌,而像艾利和这样的厂商则“脚踏两支船”,同时推出了采用PMC和Linux操作系统的MP4产品。Linux在媒体格式的支持方面比PMC要开放得多,由于Linux的开放性,使得很大一部分软件可以免费进行移植修改,这样可以节约大量的授权费用。厂商也可以为产品开发出非常丰富的应用,如网络浏览、电子邮件、游戏、个人事务处理甚至GPS电子地图。

     

        除了以上两种操作系统之外,BSD、Symbian等嵌入式操作系统也可以作为MP4播放器的操作系统使用,还有些实力较强的厂商开发了自己专用的操作系统,如飞利浦和安凯等方案提供商向MP4生产商提供了占用内存空间非常小的免费实时操作系统。操作系统的不同也让MP4产品呈现出千姿百态的景象,这种情况和手机非常类似。

     

    四、常见的MP4解决方案


         目前,推出MP4处理器和解决方案的半导体供应商多达十几家,除了以上提到的英特尔、AMD、Ti、Freescale、飞利浦、深圳安凯之外,还有SigmaDesigns、意法半导体(ST)、中国台湾凌阳等厂商。这些厂商提供的解决方案由于架构不同,所以在性能、接口、功能、功耗等方面差别很大,从而造成了目前MP4播放器产品的差异。目前MP4厂商主要采用以下一些MP4解决方案。

     

    1.Ti DSP+ARM的解决方案


        Ti的解决方案(图1)采用的是CPU搭配DSP的方式,它利用DM320/270 DSP芯片进行音视频编解码处理,而ARM处理器负责系统处理及支持外围设备接口。它所支持的媒体类型非常丰富,包括MPEG4 SP/ASP、DivX、MPEG1/2、WMV、WMA、QuickTime 6、H.264、AAC-LC、MP3等格式。除了H.264格式外,均可以实现D1分辨率(720×576)视频的实时解码(30fps),而H.264的解码分辨率也可达到CIF(352×288)水平。本方案还拥有超强的编码能力,DM320方案录制MPEG4 SP视频可达到D1的质量(30fps),而DM270可录制VGA(640×480)质量的视频。Ti方案均可支持USB2.0 OTG接口。由于此方案必须使用ARM处理器,因而它在成本上并不占优势,而且有功耗大的缺点。

     

        Ti通过与Ingenient合作,提供了最成熟的MP4设计方案。早在2002年,爱可视即率先采用Ingenient的方案推出了世界上第一款MP4产品——Jukebox。目前,包括爱可视、索尼、RCA、艾利和、微星、奥林巴斯等众多著名厂商都采用了Ingenient的方案。

     

     

     

     

     

    2.Intel PMC解决方案


        英特尔携手微软推出的PMC架构(图2)是基于通用CPU的解决方案,PMC和Wintel联盟推出的Pocket PC非常类似,它同样也是采用Intel Xscale PXA255/270处理器,软件平台也是和Pocket PC类似的微软Portable Media Centers。其中,基于PXA255的方案有功耗低、支持媒体格式多的优点,但它不能支持分辨率较高的视频文件的编解码(仅能支持320×240的QVGA)。而PXA270由于主频高达624MHz,并且拥有2700G多媒体加速芯片的支持,在编解码高分辨率视频文件方面要更胜一筹。PXA270扩展接口非常丰富,可支持SD/MMC/CF/ MS/MSPRO等读卡器,也可支持PCMCIA、USB1.1、OTG、LAN、SIM、IDE等接口,还能支持CMOS/CCD摄像头和外挂键盘等。

     

        PMC架构目前得到了创新、三星、艾利和、索尼、东芝等厂商的支持,它们均已推出了自己的PMC产品。

    3.SigmaDesigns EM851X方案


        SigmaDesigns EM851X处理器(图3)是目前性能最强、最全面的专业解码芯片系列,如EM8510就采用了双核单芯片设计,将200MHz 32位RISC处理器和媒体解码器集成于单个芯片中,可在无需其它外围芯片支持的情况下,完成系统所需各种接口的提供、系统处理等工作,并可以流畅地进行WMV、DivX、MPEG4、MPEG1/2等视频的解码,对于MPEG4和DivX格式的视频,它可支持对D1分辨率的视频进行实时解码。采用SigmaDesigns EM8510处理器的MP4具备有视频播放效果好,功耗低的优势。目前,采用这种方案的MP4产品还不多,韩国现代最新推出的HY-T28 MP4播放器中使用了EM8510芯片。

     

     

    4.AMD Alchemy解决方案


        Alchemy AU1200(图4)是AMD于今年1月推出的MP4专用处理器。这是一个低功耗、高性能的系统解决方案,它采用MIPS内核的处理器,主频可达500MHz,它针对MP4播放器进行了专门的优化,可支持的媒体格式包括MPEG1/2、MPEG4、WMV9、H.263、DivX、Xvid、MP3、WMA、WAV、ASF、 AVI、JPEG等。AU1200处理器的功耗极低,在播放D1质量(720×480)视频时功耗低于400mW,它可以支持大型显示屏(1024×768),支持DDR1和DDR2 内存,集成了媒体加速引擎,不需要外部DSP。另外,它还可支持USB 2.0 及OTG技术,具备LCD控制器、摄像头接口和互联网接入外设。Alchemy AU1200可支持Windows CE 5.0、Linux 2.6等操作系统。事实上,AMD Alchemy AU1200要比Intel的解决方案更具优势,性能更强、成本更低,但由于上市的时间较晚,目前在国内市场上还看不到采用这种方案的MP4产品。

     

     

     

     

     

    5.飞思卡尔i.MX31/L解决方案


        飞思卡尔(FreeScale)的前身是摩托罗拉的半导体部门,主要致力于手机芯片的研发,其i.MX31和i.MX31L处理器基于ARM11平台,主频高达532 MHz,它支持MPEG4和H.263视频的编解码,视频分辨率可达CIF(352×288)、QVGA(320×240),帧率可达30fps,它支持PacketVideo、RealNetworks 和Windows Media Player,除了显示控制器外,i.MX31和i.MX31L处理器还集成了高速USB OTG端口,支持MMC卡和SD卡接口,i.MX31处理器采用了领先的电源管理、安全和数字版权管理、图像处理技术。不过,i.MX31芯片本来是为智能手机设计的,虽然支持的接口类型比较丰富,但音视频处理能力一般,播放MPEG4时不够流畅,并且无法处理MPEG2视频。基于本方案的MP4产品在国内市场上也不少见,如深圳泰嘉乐的TechnoPMP等。

     

        除了以上几种MP4解决方案外,还有诸如飞利浦解决方案、Zoran解决方案、Ittiam解决方案、安凯解决方案和我国台湾的凌阳SPCA536解决方案等等,这些方案都有各自的特色,附表是几种芯片方案的成本和参数比较。在目前的MP4市场上,Ti和英特尔的解决方案占据了高端产品的大部分市场,但随着时间推移,SigmaDesigns和AMD的芯片方案必将崭露头角,成为市场的主流。

     

     

     

    展开全文
  • AVS2 有点令人不敢相信

    万次阅读 2018-08-07 10:47:24
    王荣刚:建立中国自主视频技术生态 文 / 王荣刚 整理 / LiveVideoStack 直播回放: ...amp;session_id=201807260&amp;token=PsTmsjVpbRht681rrJ0J_Xl0fbNahfHFmF1doYNdca...

    王荣刚:建立中国自主视频技术生态

    文 / 王荣刚

    整理 / LiveVideoStack

    直播回放:

    https://www.baijiayun.com/web/playback/index?classid=18072579438145&session_id=201807260&token=PsTmsjVpbRht681rrJ0J_Xl0fbNahfHFmF1doYNdca5XBFzghyiw19mnJwk0S3tXOBORUT217bsKp0fXMnVKLQ

     

     

    大家做视频技术的都知道,视频跟其他的数据不太一样,因为它需要一个生态。由于视频的数据量特别大,它无法通过原始格式在网上传输,因此在这里就涉及到压缩,压缩就涉及到压缩算法的问题。压缩算法需要满足大家可以互联互通,这里涉及到要有一个共同的标准或者规范。在过去的差不多30多年,视频技术的发展一直都是靠视频编码标准推动的。

     

    今天的内容主要围绕下面几个方面:

     

     640?wx_fmt=png

     

    行业背景

     

    1、超高清视频发展趋势

     

     640?wx_fmt=png

     

    在行业背景方面,视频的技术发展是朝着超高清方向来发展的,就是不断的向现实逼近,我们过去都是标清,后来又到高清3D,最近的是4K,包括还有VR,如上面所列的一些大的事件,这些大的事件都是推动了4K或者超高清视频技术的使用或应用,这里面比较有代表性的就是世界杯采用了4K的直播技术,而8K和VR也是近几年马上就要推行的事情。

     

    2、视频编码挑战依旧

     

     640?wx_fmt=png

     

    对视频压缩技术的挑战还是依旧的,这里面列了从高清到4K的压缩码率的情况。现在以4K为例,如果要保证一个非常高的质量,像广播电视领域,它用的这个带宽还是非常高的。差不多传4K的视频要40M左右的码率,到后面8K,VR所需的带宽就会更高,对视频压缩技术的需求依然是存在的。

     

    3、国际视频编码标准演进

     

     640?wx_fmt=png

     

    我们看一下国际视频编码标准演进的情况,一般认为第一代标准是MPEG2,MPEG2的典型应用就是标清视频,比如说DVD,传统的广播电视都是MPEG2,到第二代标准就是以H264为代表的,那它的应用是高清视频的传输,到现在是第三代标准,那就是以H.265为代表的,它的目标是传输超高清的视频。在后面我会讲,H.265面临一个授权成本过高或者风险过高的问题,由于这样的背景,现在出现了几个新的挑战者,包括Google主导的AV1,也包括我们国家制订的AVS2的标准,这个是第三代标准。现在国际上MPEG和ITO正在联合制订第四代,叫H.266/VVC,实际上国内的AVS工作组也在制订下一代的标准AVS3。

     

    4、HEVC/H.265标准专利收费乱局

     

    现在的视频大部分的压缩格式采用的还是H.264标准,H.265或者其他格式所占的流量还是很少的,这里面有个主要的原因就是H.265的知识产权的政策跟H.264有很大的不同,这张图给出了目前已经知道的H.265的专利权所有者:

     

    640?wx_fmt=png

     

    这个里面有三个圈,这三个圈代表三个不同的专利池,所谓的专利池就是说大家组团收专利费的意思。在MPEG2和H.264时代没有这么多专利池,只有一个MPEG LA的专利池,专利池的好处就是对一个标准的使用者来说,它交这个专利费,只要符合专利池的政策,按照专利池的政策收费标准来缴费就可以了,他不用去跟每个专利权人单独去谈。但是到了H.265这个标准以后就有一个很大的变化,有一些专利权人不再对MPEG LA制订的收费政策感到那么满意了,他们想再搞一套自己的收费政策,所以就出现了HEVC Advance,Velos Media两个新的专利池。除了这两个专利池以外,还有大概15家公司不在这三个专利池里,他们试图单独的来授权,但是在这么多专利拥有者中,只有MPEG  LA,和HEVC  Advance目前公开了他们的收费政策,Velos Media和另外15家公司始终是没有公开他们的收费政策的。从MPEG LA和HEVC Advance公开的收费政策看,他们的收费价格已经比H264基本上高一倍了,剩下的还没有公布如何收费的,不知道应该交多少钱,也就造成了H.265专利收费的乱局,这在国际上引起了广泛的忧虑。

     

    AVS2标准

     

    1、AVS工作组

     

    AVS工作组是数字音视频编解码技术标准工作组的简称,由国家工信部于2002年6月批准成立。工作组的任务是向我国的信息产业需求,联合国内企业和科研机构,制(修)订数字音视频的压缩、解压缩、处理和表示等共性技术标准。目前有近100家会员单位。这里面包括华为,中兴,腾讯,还有一些学校,北大、清华,浙大和上海交大等等,工作组除了制订视频标准以外,还制订音频标准,系统层的标准。最近,这个工作组还在往人工智能方向扩展,新成立了一个基于AI的工作组,这个AI工作组里面,也会做一些人工智能方面的一些基础共性的标准。

     

    640?wx_fmt=png

     

    2、AVS标准授权政策

     

    AVS标准的一大创新是在标准制定之前先确立许可模式,有效避免类似HEVC收费乱局,凡是向AVS工作组提交技术和提案的单位都需要对其专利许可意向做出承诺,允许“免费使用”或者“加入AVS专利池”。 AVS专利池管理委员会出台《关于AVS2专利池许可的建议性规定》,在规定中指出,AVS2的专利授权采用一站式许可模式,只对设备象征性收费,不对内容服务收费,对互联网上的软件服务免收专利费。

     

    3、AVS视频标准演进过程及技术框架

     

    640?wx_fmt=png

     

    AVS标准的演进过程,实际上主要是有两代标准:第一代叫AVS1标准,于2006年发布成了国标,它的主要应用场景是地面电视,到了2012年,AVS1做了一些小的改进,发布成了一个新的广电的行标叫AVS+,这个主要在高清卫星上面应用,现在大家看到的央视上带星的高清节目,都是用的AVS+标准,第二代叫AVS2标准,是面向超高清的视频应用的,于2016年12月份发布成了国标。

     

     640?wx_fmt=png

     

    AVS2技术的基本框架和MPEG2及H.264是类似的,依旧是变换加预测的混合架构,这里面在每一个模块上都做了一些技术上的革新,大概在性能上就比上一代H.264,或者AVS1,AVS+提升了一倍以上。

     

    640?wx_fmt=png

     

    4、AVS2编码效率优于HEVC

     

    与HEVC做对比,在PSNR相同的情况下,码率相对低就是负值,码率高就是正值,在这个表里负值就表示AVS2好,正值就表示HEVC好。从不同的应用场景来综合评估下来,AVS2总体上的编码效率优于HEVC。

     

    640?wx_fmt=png

     

    国家广播电影电视总局广播电视计量检测中心做了一个主观测试,这个主观测试是针对了8个4K、10bit的视频序列,目标平均码率为36Mbps,在这个码率条件下,AVS2和HEVC用的都是参考软件来压缩的,参考软件基本上可以达到的最优的性能。

     

    640?wx_fmt=png

     

    从这个主观测试的结果来看,AVS2略优。

     

    5、国际化:AVS2被UHD Forum采纳

     

    2018.年3月,UHD Forum经过长时间的调研和分析论证,最终一致认为AVS2性能优异、产业链成熟、专利授权政策优惠,最终决定把AVS2列为和H.265并列的超高清编码标准,推荐给全球的TV和视频业务运营商使用。

     

    AVS2实现

     

    1、AVS2解码芯片

     

    1)AVS2 4K量产芯片厂商:华为海思,Hi3796MV200,AVS2 全4K解码芯片

    MStar, MSO9385,AVS2 全4K解码芯片

     

    2)年内将推出AVS2芯片的厂商:中兴微、Amlogic、全志、瑞芯微

     

    2、AVS2广播级全4K编码器

     

    AVS2 4K/50P/10bit 实时编码器厂商:目前至少有柯维新(东华广信),数码视讯,算通,当虹科技,上海国贸等, 现在有一些质量比较好的编码器主观质量损失低于8%的,广播级要求是平均低于12%,低于8%是一个不错的质量。

     

    640?wx_fmt=png

     

    3、AVS2开源编码器——xAVS2

     

    2018 年 1 月 31 日,北京大学数字视频编解码技术国家工程实验室开源了 AVS2 高清实时编码器 xAVS2。

     

     640?wx_fmt=png

     

    这两张图是xAVS2和X265性能的对比,这里面横坐标代表的是编码效率的损失,纵坐标是编码速度,横坐标就是横轴值越小越好,纵轴是值越大越好,针对UHD来说二者是相当的,针对HD来说,xAVS2在相同的编码效率条件下比x265速度快,或者反过来说相同速度条件下比它的编码效率高。

     

    4、AVS2全平台商用编解码内核-uAVS2

     

    2017 年 10 月,北京大学深圳研究生院数字媒体研究中心推出多平台AVS2编解码内核-uAVS2,它的特点如下:

     

    • 编码速度是x265的3~10倍

    • 解码速度是openHEVC的3倍

    • 支持Linux/Windows/Android/iOS多平台

    • 支持4K/50P/10bit 实时编码

     

    1)uAVS2编码器

     

    下面的两张图给的就是uAVS2和x265的一个对比情况,这里面的红的实线和蓝的实线是uAVS2,虚线是x265,上面是单线程的,下面是多线程的,同样这个横轴是编码效率的损失,纵轴是编码速度,横轴的值越小越好,纵轴的值越大越好。编码效率损失是说这个编码器跟参考软件相比来说,编码效率的损失,因为参考软件是代表了最优的客观性能。但是由于参考软件的最大的问题是速度特别慢,没有办法做实时应用,做实时编码器的时候必然会牺牲一些编码效率来提升编码速度。在这两张图,很明显可以看出来,当编码速度类似时,uAVS2大概比X265的编码效率高10%到30%,如果编码效率类似, uAVS2比x265会快3到10倍。

     

    640?wx_fmt=png

     

    2)uAVS2移动编解码器

     

    在移动平台解码速度比openHEVC快2倍,华为P20手机可以实现4K/30P视频实时解码,720P实时编码。对于1080P/3Mbps实时解码, CPU使用率不足10%。

     

    640?wx_fmt=png

     

    上面表格就是我们做的解码器跟OpenHEVC解码器的速度的对比,值得一提的是在手机上面做软件的解码跟硬解码的功耗水平实际上都开始接近了,下面这两张表是我们最近测的一个结果,我们在手机端去测试视频播放的时候,比较软解和硬解功耗的差异,第一张表是给的是一组720P的视频,各种典型的场景都有的,对比了这个四种不同的手机的机器,分别是三星的S3,iPhone6,iPhone6S,iPhone8,三星S3和 iPhone 6比较老的手机了,iPhone8是目前比较新的,我们可以看出在线播放720P视频的时候功耗的水平以及H.264的硬解和软解,在三星S3上是差异是比较大的,但是在iPhone6,iPhone6S,iPhone8差异并没有那么大,只有百分之十几。那我们看下面第二张表,就是AVS2的软解和H.264硬解之间的功耗的差别,这个我们对比了三组不同的分辨率的视频,分别是480P,720P和1080P,我们看在480P,AVS2的软解和H.264的硬解基本上没有太大差异,只有1%的功耗差,在720P上面二者差异也很小,只有8%的功耗差,当峰值到了1080P,二者也只差了11%,当然这个是在iPhone8上测的,现在大家都知道手机上面能够支持的视频的服务最高的分辨率也就是1080P,这张表已经说明,在手机上面,软解就够用了。就是对大多数的应用场景来说,即使AVS2在手机上没有芯片硬解的支持,软解也是完全可以上线了。

     

    640?wx_fmt=png

     

    640?wx_fmt=png

     

    3)全4K视频编码器:uAVS2-4K

     

    基于uAVS2的全4K视频编码器有两个配置,一个配置用来做离线转码,它的编码速度达不到实时,但是编码性能调的比较优,我们把这个最优的配置和HEVC的参考软件做了一个对比,针对全4K的视频系列平均比这个HEVC的参考软件编码效率高7.4%,速度大概是HEVC编码器的参考软件的几百倍。

     

     640?wx_fmt=png

     

    另外一个配置就是快速配置,这个快速配置就是可以来做全4K视频实时编码的配置,与X265类似的配置去对比,比它的编码效率高30%,同时编码速度还比它快40%,这个目前是可用的。目前uAVS2-4K已经被集成到多款商用AVS2 4K编码器中。

     

     640?wx_fmt=png

     

    4)监控视频编解码内核:uAVS2-S

     

    监控视频编解码内核uAVS2-S比HEVC/H.265编码效率高30%以上,能大幅节约监控视频传输带宽和存储成本。

     

     640?wx_fmt=png

     

    5)图像编解码内核: uAVS2-I

     

    与腾讯合作,基于uAVS2-I推出新一代图像压缩格式TPG,比JPG高 47%, 比PNG高60%,比GIF高85%,比WebP高25%。

     

     640?wx_fmt=png

     

    6)AVS2云转码服务

     

    AVS2云转码服务支持H.264、H.265和AVS2标准互转,支持JPEG、PNG、GIF等格式和TPG互转,支持AI去噪、超分辨率、超帧率等画质增强功能,并且是和华为云合作推广,计算资源弹性可调、可在私有云和公有云等平台部署。

     

     640?wx_fmt=png

     

    AVS2应用

     

    1、4K电视广播

     

            2017年11月,国家广电总局发文规范4K超高清电视发展,明确要求统一采用AVS2 标准;2018年初,广东省正式上线AVS2 4K直播频道和IPTV点播专区,要求在10月以后新上线4K节目支持AVS2标准;2018年5月,央视联通端到端AVS2 4K系统,计划10月1日开通AVS2 4K频道。

     

    2、IPTV/OTT

     

            2018年3月30日,由中关村视听产业技术创新联盟会同中国智慧家庭产业联盟、中国视频体验联盟、广东4K生态产业联盟及众多相关企业等编写的《IPTV 业务系统AVS2实施指南(2018年)》正式发布。

     

    3、互联网视频

     

            支持互联网和移动平台视频/游戏直播、点播、实时通信等应用,与华为云合作推广,近期上线。

     

     640?wx_fmt=png

     

    4、AI画质增强

     

    基于AI技术实现老电影/电视剧/动画修复,压缩噪声去除,超分辨率/超帧率/色域提升/SD转HDR。

     

     640?wx_fmt=png

     

    5、互联网图像

     

            在互联网图像方面,我们与腾讯合作一起推行一个叫TPG的标准,目前这个TPG 标准,已经在腾讯的九大产品线部署了,包括手机QQ,QQ空间,手机管家,QQ浏览器,腾讯视频的客户端,新闻,腾讯体育动漫等等,另外也在腾讯云上面部署了TPG,而且腾讯浏览器的内核,X5内核也完成了TPG的支持,现在还有游戏的引擎的厂商接入了TPG的格式,这个TPG它的优势在于:一呢,省流量、省存储,二是让页面或者图片的加载速度大幅度提升,大概提升到30%以上。

     

    6、监控视频

     

    在参与雪亮工程和平安城市建设的过程中,发现监控视频有对转码的需求,就是前端摄像头产生的视频流码率依然很高(H.264 4Mbps/H.265 2Mbps),要做一次二次的压缩,然后在一些这个带宽受限的网络上进行传输,再传到后台,这个是前端转码;还有一个应用是后端转码,就是监控摄像头下面的数据在后台通过服务器来转码,这样是为了节省存储空间。AVS2由于采用了背景帧技术可以大幅度提升二次压缩效率。

     

    总结

     

    1,AVS2标准性能优异、授权政策优惠可控

    2,AVS2产业链已经成熟,开始在4K、监控、移动互联网视频/图像等领域应用

    3,  期待与产业界密切合作共建中国自主视频技术生态

     

    Q&A

     

    Q1: TPG网页加载的优化什么原理?

     

    A: 这个原理很简单,就是因为TPG同样的图片的质量,它压缩以后的图片尺寸比原来减少了50%,网页加载的速度自然就会变快了。

     

    Q2: AVS的学习资料去哪里找?

     

    A: 大家可以上AVS工作组的网站,有一个AVS2的专栏(http://www.avs.org.cn/avs2/index.asp)上面有一些AVS2的大概的介绍。另外就是关注我们的公众号【智媒之音】,上面有关于AVS2标准的每一项编码工具的一些比较详细的介绍。

     

    Q3: 解释一下AVS标准国际化,以及和MPEG合作推广?

     

    A: 现在也有一些公司希望在国际,国外来推广AVS2的标准,那比如其实我刚才PPT也在讲, UHD Forum实际上它就是一个国际的组织,跟超高清这个产业有关的国际上最主流的公司都在里面。现在它实际上把AVS2作为一个推荐性的国际标准已经纳入进去了,是跟HEVC并列的一个标准。至于说AVS标准和MPEG合作的问题呢,其实这个比较难操作,就是因为两边的商业模式是不一样的,MPEG那边成员更多,难协调,它要改它的商业模式,这是基本上不可能实现的任务。在技术上MPEG和AVS有很方便的沟通渠道,很多AVS标准的参与者同时参与MPEG标准制定,MPEG视频组的组长虞露老师就是AVS工作组视频组的前任组长。

     

    Q4: TPG和HEIF的对比?

     

    A:HEIF的编码内核是HEVC的帧内编码,所以理论上来说它的性能和TPG在图像编码上是类似的。但是因为具体不同公司编解码器优化的水平不一样,所以这个就在产品级很难比。这方面实际上在腾讯内部做过一些对比,他们对比原来他们尝试用HEVC实现的内核,至少和那个内核对比,TPG无论是编码质量和速度都是有优势的。

     

    640?wx_fmt=jpeg

    展开全文
  • 一个决定,入手idea6410

    千次阅读 2009-09-08 20:36:00
    嘿嘿,今天拿出仅有的一点积蓄买了个idea6410,我觉得这个处理器很经典,性价比蛮高的,以后会更火,嘿嘿,接个项目,这板子钱就回来了。以后我会多写些文档上来,和大家一起学习。 idea6410是一款高端ARM11处理器...
  • WinCE6.0软件资源软件特性: ·CPU主频稳定工作于667MHz ·视频硬件编码、解码支持MPEG-4/H263/H264/VC-1 ... ·支持SD卡+USB2.0升级系统 ·支持TCPMP播放器完美硬件解码,MPE
  • 编解码学习笔记(一):基本概念媒体业务是网络的主要业务之间。尤其移动互联网业务的兴起,在运营商和应用开发商中,媒体业务份量极重,其中媒体的编解码服务涉及需求分析、应用开发、释放license收费等等。最近...
  • Hi3798M V310 是用于 IPTV/OTT 机顶盒市场的支持 4KP60 解码的超高清高性能 SOC芯片。集成 4 核 64 位高性能 Cortex A53 处理器和多核高性能 2D/3D 加速引擎;支持H.265/AVS2 4Kx2K@P60 10bit 超高清视频解码,高...
  • 各种音视频编解码学习详解

    万次阅读 2012-03-05 16:29:17
    编解码学习笔记(一):基本概念 媒体业务是网络的主要业务之间。尤其移动互联网业务的兴起,在运营商和应用开发商中,媒体业务份量极重,其中媒体的编解码服务涉及需求分析、应用开发、释放license收费等等。...
  • Android底层开发工作小结

    万次阅读 2013-01-12 10:48:36
    2010 - 微博元年,智能手机元年,2011 - 平板电脑元年,2012 - 智能电视元年。 又到年末,是时候梳理下Android...负责模块 Camera, Sound, SD, USB, G-sensor, TP 软件平台 Android 1.6/2.2/2.3 硬件平台 Mavell PX
  • 各种音频视频编解码详细介绍

    万次阅读 2016-11-24 16:17:20
    各种音视频编解码学习详解  编解码学习笔记(一):基本概念   媒体业务是网络的主要业务之间。尤其移动互联网业务的兴起,在运营商和应用开发商中,媒体业务份量极重,其中媒体的编解码服务涉及需求分析、...
  • 编解码学习笔记二codec类型编解码学习笔记三Mpeg系列Mpeg 1和Mpeg 2编解码学习笔记四Mpeg系列Mpeg 4编解码学习笔记五Mpeg系列AAC音频编解码学习笔记六H26x系列编解码学习笔记七微软Windows Media系列编解码学习笔记...
  • MPEG4 IP Camera方案

    千次阅读 2008-09-24 11:45:00
    原文地址:http://www.cps.com.cn/ebook/ly.asp?id=212MPEG4 IP Camera方案■张克非 陈宏铭一、前言——IP Camera监控系统介绍随着数字化和Internet时代的到来,越来越多的设备都在进行数字化和网络化的革命。...
  • 又一篇关于各种音视频编码的

    万次阅读 2012-04-17 23:49:44
    编解码学习笔记(一):基本概念 媒体业务是网络的主要业务之间。尤其移动互联网业务的兴起,在运营商和应用开发商中,媒体业务份量极重,其中媒体的编解码服务涉及需求分析、应用开发、释放license收费等等。...
  • Android 图片文件读取

    万次阅读 2017-02-08 11:03:22
    介绍图片文件读取所涉及到的各项技术点
  • 1主要视频压缩技术在中国内地市场发展分析 --------孟冰 晶门科技 一,视频压缩技术背景及主要压缩技术发展 视频处理技术是伴随着视频从模拟到数字化转变的过程中得到蓬勃发展的.随着人们对视频图像的清晰度,流畅度,...
  • 各种音频视频编码方法

    万次阅读 2014-08-10 17:54:25
    编解码学习笔记(一):基本概念 媒体业务是网络的主要业务之间。尤其移动互联网业务的兴起,在运营商和应用开发商中,媒体业务份量极重,其中媒体的编解码服务涉及需求分析、应用开发、释放license收费等等...
  • 店主:嵌入式系统工程师 联系方式: QQ:1141256841/774295611  技术qq群: 40605090 大连嵌入式商城群 121393599 android6410(一)群 16667174  android6410(二)群 ...
1 2 3 4 5 ... 20
收藏数 1,651
精华内容 660
关键字:

sd 图片编解码