Android 4.0 gallery2 生成video thumbnail的过程

齐高阳
2023-12-01


通过print callstack得知gallery里面获得thumbnail 是通过LocalVideo.requestImage往下调用的:

 

com.android.gallery3d.data.LocalVideo.requestImage(LocalVideo.java:143)

com.android.gallery3d.ui.AlbumSlidingWindow$AlbumDisplayItem.startLoadBitmap(AlbumSlidingWindow.java:372)

com.android.gallery3d.ui.AbstractDisplayItem.requestImage(AbstractDisplayItem.java:81)

 

在LocalVideo.java里面直接调用return LocalVideoRequest对象:

所以简单的说thumbnail就是LocalVideoRequest得到的,细节就要往下看了。

@Override                                                                 
public Job<Bitmap> requestImage(int type) {
    return new LocalVideoRequest(mApplication, getPath(), type, filePath);
}                                                                         

  • LocalVideoRequest直接调用ImageCacheRequest的实现

  • LocalVideoRequest里面override了onDecodeOriginal方法

    public static class LocalVideoRequest extends ImageCacheRequest {
        private String mLocalFilePath;
    
        LocalVideoRequest(GalleryApp application, Path path, int type,
                String localFilePath) {
            super(application, path, type, LocalImage.getTargetSize(type));
            mLocalFilePath = localFilePath;
        }
    
        @Override
        public Bitmap onDecodeOriginal(JobContext jc, int type) {
            Bitmap bitmap = BitmapUtils.createVideoThumbnail(mLocalFilePath);
            if (bitmap == null || jc.isCancelled()) return null;             
            return bitmap;                                                   
        }                                                                    
    }                                                                        

ImageCacheRequest:

1.     首先创建ImageCacheService对象[在ImageCacheRequest::run()]

ImageCacheService cacheService = mApplication.getImageCacheService();
2.     通过CacheService.getImageData获取ImageData

ImageData data = cacheService.getImageData(mPath, mType);

3.     如果data不为null,对data进行decode,然后return,

如果data为空就调用上面说到的onDecodeOriginal创建新的thumbnail

再把经过处理的bitmap写进文件里面(cacheService.putImageData)

if (data != null) {                                                  
    BitmapFactory.Options options = new BitmapFactory.Options();     
    options.inPreferredConfig = Bitmap.Config.ARGB_8888;
    Bitmap bitmap = DecodeUtils.requestDecode(jc, data.mData,        
            data.mOffset, data.mData.length - data.mOffset, options);
    if (bitmap == null && !jc.isCancelled()) {                       
        Log.w(TAG, "decode cached failed " + debugTag);              
    }
    return bitmap;
} else {
    Bitmap bitmap = onDecodeOriginal(jc, mType);
    if (jc.isCancelled()) return null;

    if (bitmap == null) {
        Log.w(TAG, "decode orig failed " + debugTag);
        return null;
    }

    if (mType == MediaItem.TYPE_MICROTHUMBNAIL) {
        bitmap = BitmapUtils.resizeDownAndCropCenter(bitmap,
                mTargetSize, true);
    } else {
        bitmap = BitmapUtils.resizeDownBySideLength(bitmap,
                mTargetSize, true);
    }
    if (jc.isCancelled()) return null;

    byte[] array = BitmapUtils.compressBitmap(bitmap);
    if (jc.isCancelled()) return null;

    cacheService.putImageData(mPath, mType, array);
    return bitmap;
}

ImageCacheService的实现:


有一个private对象: private BlobCache mCache;

通过在BlobCache.java增加log,BlobCache的路径为:

/mnt/sdcard/Android/data/com.android.gallery3d/cache/imgcache

// Creates the cache. Three files will be created:
// path + ".idx", path + ".0", and path + ".1"
// The ".0" file and the ".1" file each stores data for a region. Each of
// them can grow to the size specified by maxBytes. The maxEntries parameter
// specifies the maximum number of entries each region can have. If the
// "reset" parameter is true, the cache will be cleared before use.
public BlobCache(String path, int maxEntries, int maxBytes, boolean reset)
        throws IOException {
    this(path, maxEntries, maxBytes, reset, 0);
}

public BlobCache(String path, int maxEntries, int maxBytes, boolean reset,
        int version) throws IOException {
    mIndexFile = new RandomAccessFile(path + ".idx", "rw");
    mDataFile0 = new RandomAccessFile(path + ".0", "rw");
    mDataFile1 = new RandomAccessFile(path + ".1", "rw");
    mVersion = version;


Gallery的cache目录:

/mnt/sdcard/Android/data/com.android.gallery3d/cache/

imgcache.0

imgcache.1

imgcache.idx

 

BlobCache的描述(BlobCache.java): 

// This is an on-disk cache which maps a 64-bits key to a byte array.
//
// It consists of three files: one index file and two data files. One of the
// data files is "active", and the other is "inactive". New entries are
// appended into the active region until it reaches the size limit. At that
// point the active file and the inactive file are swapped, and the new active
// file is truncated to empty (and the index for that file is also cleared).
// The index is a hash table with linear probing. When the load factor reaches
// 0.5, it does the same thing like when the size limit is reached.
//
// The index file format: (all numbers are stored in little-endian)
// [0]  Magic number: 0xB3273030
// [4]  MaxEntries: Max number of hash entries per region.
// [8]  MaxBytes: Max number of data bytes per region (including header).
// [12] ActiveRegion: The active growing region: 0 or 1.
// [16] ActiveEntries: The number of hash entries used in the active region.
// [20] ActiveBytes: The number of data bytes used in the active region.
// [24] Version number.
// [28] Checksum of [0..28).
// [32] Hash entries for region 0. The size is X = (12 * MaxEntries bytes).
// [32 + X] Hash entries for region 1. The size is also X.
//
// Each hash entry is 12 bytes: 8 bytes key and 4 bytes offset into the data
// file. The offset is 0 when the slot is free. Note that 0 is a valid value
// for key. The keys are used directly as index into a hash table, so they
// should be suitably distributed.
//
// Each data file stores data for one region. The data file is concatenated
// blobs followed by the magic number 0xBD248510.
//
// The blob format:
// [0]  Key of this blob
// [8]  Checksum of this blob
// [12] Offset of this blob
// [16] Length of this blob (not including header)
// [20] Blob
//
// Below are the interface for BlobCache. The instance of this class does not
// support concurrent use by multiple threads.
//
// public BlobCache(String path, int maxEntries, int maxBytes, boolean reset) throws IOException;
// public void insert(long key, byte[] data) throws IOException;
// public byte[] lookup(long key) throws IOException;
// public void lookup(LookupRequest req) throws IOException;
// public void close();
// public void syncIndex();
// public void syncAll();
// public static void deleteFiles(String path);




 类似资料: