Jpeg 庫的解碼OpenCL優化

libJpeg庫解碼OpenCL優化

這兩週在閒暇時基於通用的libjpeg庫重新做了一個opencl解碼實現。重新熟悉下算法。

代碼路徑

https://github.com/jxt1234/platform_external_jpeg
OpenCL文件夾目錄下面的就是所有的修改。
用Xcode開發的,沒興趣去整Makefile了,代碼獨立,移植集成也很方便。

主要特點

1.算法代碼完全獨立,不修改原來庫中的代碼。
2.支持各種YUV格式(411、422、444等等)。
3.霍夫曼解碼仍然由CPU完成,採用OpenCL做idct和顏色轉換,向量化實現,效率很高。(PS:當年移植那個坑爹的libjpeg-opencl時被坑死了)
4.只支持輸出爲rgb的格式,需要擴展的看下代碼自己改,也不麻煩,這部分用simd實現比較好,因此沒怎麼寫。

使用示例

extern "C"
{
#include "jpeglib.h"
};
int main() {
    const char* inputfile = "input.jpg";
    const char* outputfile = "output.jpeg";
    struct jpeg_decompress_struct cinfo;
    FILE* infile;
    int row_stride;
    auto sta = clock();
    if ((infile = fopen(inputfile, "rb")) == NULL)
    {
        return NULL;
    }
    jpeg_create_decompress(&cinfo);
    struct jpeg_error_mgr jerr;
    cinfo.err = jpeg_std_error(&jerr);
    jpeg_stdio_src(&cinfo, infile);
    (void) jpeg_read_header(&cinfo, TRUE);
    /*必須設成float方式,若是cpu解碼,這個會影響性能,但對於gpu來說沒有關係,而且float方式精度最高,幾乎不會造成圖片失真*/
    cinfo.dct_method = JDCT_FLOAT;
    (void) jpeg_start_decompress(&cinfo);
    auto width = cinfo.output_width;
    auto height = cinfo.output_height;

    /*rgb 三個分量*/
    auto pixels = (JSAMPLE*)(malloc(width*height*3));

    /*opencl 解碼的 api*/
    /*pixels 默認爲rgb24位,事先分配好內存*/
    jpeg_decode_by_opencl(&cinfo, pixels);

    //這裏用abort而不是finish,直接中止掉
    (void) jpeg_abort_decompress(&cinfo);
    jpeg_destroy_decompress(&cinfo);
    fclose(infile);
    auto fin = clock();
    printf("Time cost for %d * %d, %lu / %ds\n", width, height, fin-sta, CLOCKS_PER_SEC);

    /*用得到的pixels做一些事情。。。。。。*/


    /*釋放掉pixels*/
    free(pixels);
    return 0;
}

性能數據

MACBook上數據,僅供參考
OpenCL優化後數據:
Time cost for 3200 * 2000, 177757 / 1000000s
MCU is 130001 / 1000000s

原CPU方式數據
Time cost for 3200 * 2000, 363453 / 1000000s

idct和顏色轉換的時間壓縮到可以忽略不計了。幾乎只剩下解霍夫曼編碼的時間,總體性能是提升了100%。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章