4 * This file is part of FFmpeg.
6 * FFmpeg is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * FFmpeg is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with FFmpeg; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 #include "dnn_io_proc.h"
22 #include "libavutil/imgutils.h"
23 #include "libswscale/swscale.h"
24 #include "libavutil/avassert.h"
26 DNNReturnType ff_proc_from_dnn_to_frame(AVFrame *frame, DNNData *output, void *log_ctx)
28 struct SwsContext *sws_ctx;
29 int bytewidth = av_image_get_linesize(frame->format, frame->width, 0);
30 if (output->dt != DNN_FLOAT) {
31 avpriv_report_missing_feature(log_ctx, "data type rather than DNN_FLOAT");
35 switch (frame->format) {
36 case AV_PIX_FMT_RGB24:
37 case AV_PIX_FMT_BGR24:
38 sws_ctx = sws_getContext(frame->width * 3,
46 av_log(log_ctx, AV_LOG_ERROR, "Impossible to create scale context for the conversion "
47 "fmt:%s s:%dx%d -> fmt:%s s:%dx%d\n",
48 av_get_pix_fmt_name(AV_PIX_FMT_GRAYF32), frame->width * 3, frame->height,
49 av_get_pix_fmt_name(AV_PIX_FMT_GRAY8), frame->width * 3, frame->height);
52 sws_scale(sws_ctx, (const uint8_t *[4]){(const uint8_t *)output->data, 0, 0, 0},
53 (const int[4]){frame->width * 3 * sizeof(float), 0, 0, 0}, 0, frame->height,
54 (uint8_t * const*)frame->data, frame->linesize);
55 sws_freeContext(sws_ctx);
57 case AV_PIX_FMT_GRAYF32:
58 av_image_copy_plane(frame->data[0], frame->linesize[0],
59 output->data, bytewidth,
60 bytewidth, frame->height);
62 case AV_PIX_FMT_YUV420P:
63 case AV_PIX_FMT_YUV422P:
64 case AV_PIX_FMT_YUV444P:
65 case AV_PIX_FMT_YUV410P:
66 case AV_PIX_FMT_YUV411P:
67 case AV_PIX_FMT_GRAY8:
69 sws_ctx = sws_getContext(frame->width,
77 av_log(log_ctx, AV_LOG_ERROR, "Impossible to create scale context for the conversion "
78 "fmt:%s s:%dx%d -> fmt:%s s:%dx%d\n",
79 av_get_pix_fmt_name(AV_PIX_FMT_GRAYF32), frame->width, frame->height,
80 av_get_pix_fmt_name(AV_PIX_FMT_GRAY8), frame->width, frame->height);
83 sws_scale(sws_ctx, (const uint8_t *[4]){(const uint8_t *)output->data, 0, 0, 0},
84 (const int[4]){frame->width * sizeof(float), 0, 0, 0}, 0, frame->height,
85 (uint8_t * const*)frame->data, frame->linesize);
86 sws_freeContext(sws_ctx);
89 avpriv_report_missing_feature(log_ctx, "%s", av_get_pix_fmt_name(frame->format));
96 static DNNReturnType proc_from_frame_to_dnn_frameprocessing(AVFrame *frame, DNNData *input, void *log_ctx)
98 struct SwsContext *sws_ctx;
99 int bytewidth = av_image_get_linesize(frame->format, frame->width, 0);
100 if (input->dt != DNN_FLOAT) {
101 avpriv_report_missing_feature(log_ctx, "data type rather than DNN_FLOAT");
105 switch (frame->format) {
106 case AV_PIX_FMT_RGB24:
107 case AV_PIX_FMT_BGR24:
108 sws_ctx = sws_getContext(frame->width * 3,
114 0, NULL, NULL, NULL);
116 av_log(log_ctx, AV_LOG_ERROR, "Impossible to create scale context for the conversion "
117 "fmt:%s s:%dx%d -> fmt:%s s:%dx%d\n",
118 av_get_pix_fmt_name(AV_PIX_FMT_GRAY8), frame->width * 3, frame->height,
119 av_get_pix_fmt_name(AV_PIX_FMT_GRAYF32),frame->width * 3, frame->height);
122 sws_scale(sws_ctx, (const uint8_t **)frame->data,
123 frame->linesize, 0, frame->height,
124 (uint8_t * const*)(&input->data),
125 (const int [4]){frame->width * 3 * sizeof(float), 0, 0, 0});
126 sws_freeContext(sws_ctx);
128 case AV_PIX_FMT_GRAYF32:
129 av_image_copy_plane(input->data, bytewidth,
130 frame->data[0], frame->linesize[0],
131 bytewidth, frame->height);
133 case AV_PIX_FMT_YUV420P:
134 case AV_PIX_FMT_YUV422P:
135 case AV_PIX_FMT_YUV444P:
136 case AV_PIX_FMT_YUV410P:
137 case AV_PIX_FMT_YUV411P:
138 case AV_PIX_FMT_GRAY8:
139 case AV_PIX_FMT_NV12:
140 sws_ctx = sws_getContext(frame->width,
146 0, NULL, NULL, NULL);
148 av_log(log_ctx, AV_LOG_ERROR, "Impossible to create scale context for the conversion "
149 "fmt:%s s:%dx%d -> fmt:%s s:%dx%d\n",
150 av_get_pix_fmt_name(AV_PIX_FMT_GRAY8), frame->width, frame->height,
151 av_get_pix_fmt_name(AV_PIX_FMT_GRAYF32),frame->width, frame->height);
154 sws_scale(sws_ctx, (const uint8_t **)frame->data,
155 frame->linesize, 0, frame->height,
156 (uint8_t * const*)(&input->data),
157 (const int [4]){frame->width * sizeof(float), 0, 0, 0});
158 sws_freeContext(sws_ctx);
161 avpriv_report_missing_feature(log_ctx, "%s", av_get_pix_fmt_name(frame->format));
168 static enum AVPixelFormat get_pixel_format(DNNData *data)
170 if (data->dt == DNN_UINT8 && data->order == DCO_BGR) {
171 return AV_PIX_FMT_BGR24;
174 av_assert0(!"not supported yet.\n");
175 return AV_PIX_FMT_BGR24;
178 static DNNReturnType proc_from_frame_to_dnn_analytics(AVFrame *frame, DNNData *input, void *log_ctx)
180 struct SwsContext *sws_ctx;
182 enum AVPixelFormat fmt = get_pixel_format(input);
183 sws_ctx = sws_getContext(frame->width, frame->height, frame->format,
184 input->width, input->height, fmt,
185 SWS_FAST_BILINEAR, NULL, NULL, NULL);
187 av_log(log_ctx, AV_LOG_ERROR, "Impossible to create scale context for the conversion "
188 "fmt:%s s:%dx%d -> fmt:%s s:%dx%d\n",
189 av_get_pix_fmt_name(frame->format), frame->width, frame->height,
190 av_get_pix_fmt_name(fmt), input->width, input->height);
194 if (av_image_fill_linesizes(linesizes, fmt, input->width) < 0) {
195 av_log(log_ctx, AV_LOG_ERROR, "unable to get linesizes with av_image_fill_linesizes");
196 sws_freeContext(sws_ctx);
200 sws_scale(sws_ctx, (const uint8_t *const *)frame->data, frame->linesize, 0, frame->height,
201 (uint8_t *const *)(&input->data), linesizes);
203 sws_freeContext(sws_ctx);
207 DNNReturnType ff_proc_from_frame_to_dnn(AVFrame *frame, DNNData *input, DNNFunctionType func_type, void *log_ctx)
211 case DFT_PROCESS_FRAME:
212 return proc_from_frame_to_dnn_frameprocessing(frame, input, log_ctx);
213 case DFT_ANALYTICS_DETECT:
214 return proc_from_frame_to_dnn_analytics(frame, input, log_ctx);
216 avpriv_report_missing_feature(log_ctx, "model function type %d", func_type);