• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * This file is part of FFmpeg.
3  *
4  * FFmpeg is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * FFmpeg is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with FFmpeg; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17  */
18 
19 #include "config.h"
20 
21 #include "libavutil/hwcontext.h"
22 #include "libavutil/hwcontext_cuda_internal.h"
23 #include "libavutil/cuda_check.h"
24 
25 #if CONFIG_PTX_COMPRESSION
26 #include <zlib.h>
27 #define CHUNK_SIZE 1024 * 64
28 #endif
29 
30 #include "load_helper.h"
31 
32 #define CHECK_CU(x) FF_CUDA_CHECK_DL(avctx, cu, x)
33 
ff_cuda_load_module(void * avctx,AVCUDADeviceContext * hwctx,CUmodule * cu_module,const unsigned char * data,const unsigned int length)34 int ff_cuda_load_module(void *avctx, AVCUDADeviceContext *hwctx, CUmodule *cu_module,
35                         const unsigned char *data, const unsigned int length)
36 {
37     CudaFunctions *cu = hwctx->internal->cuda_dl;
38 
39 #if CONFIG_PTX_COMPRESSION
40     z_stream stream = { 0 };
41     uint8_t *buf, *tmp;
42     uint64_t buf_size;
43     int ret;
44 
45     if (inflateInit2(&stream, 32 + 15) != Z_OK) {
46         av_log(avctx, AV_LOG_ERROR, "Error during zlib initialisation: %s\n", stream.msg);
47         return AVERROR(ENOSYS);
48     }
49 
50     buf_size = CHUNK_SIZE * 4;
51     buf = av_realloc(NULL, buf_size);
52     if (!buf) {
53         inflateEnd(&stream);
54         return AVERROR(ENOMEM);
55     }
56 
57     stream.next_in = data;
58     stream.avail_in = length;
59 
60     do {
61         stream.avail_out = buf_size - stream.total_out;
62         stream.next_out = buf + stream.total_out;
63 
64         ret = inflate(&stream, Z_FINISH);
65         if (ret != Z_OK && ret != Z_STREAM_END && ret != Z_BUF_ERROR) {
66             av_log(avctx, AV_LOG_ERROR, "zlib inflate error(%d): %s\n", ret, stream.msg);
67             inflateEnd(&stream);
68             av_free(buf);
69             return AVERROR(EINVAL);
70         }
71 
72         if (stream.avail_out == 0) {
73             buf_size += CHUNK_SIZE;
74             tmp = av_realloc(buf, buf_size);
75             if (!tmp) {
76                 inflateEnd(&stream);
77                 av_free(buf);
78                 return AVERROR(ENOMEM);
79             }
80             buf = tmp;
81         }
82     } while (ret != Z_STREAM_END);
83 
84     // NULL-terminate string
85     // there is guaranteed to be space for this, due to condition in loop
86     buf[stream.total_out] = 0;
87 
88     inflateEnd(&stream);
89 
90     ret = CHECK_CU(cu->cuModuleLoadData(cu_module, buf));
91     av_free(buf);
92     return ret;
93 #else
94     return CHECK_CU(cu->cuModuleLoadData(cu_module, data));
95 #endif
96 }
97