1
/* $Id: converter_libswscale.c 4076 2012-04-24 09:40:35Z bennylp $ */
3
* Copyright (C) 2010-2011 Teluu Inc. (http://www.teluu.com)
5
* This program is free software; you can redistribute it and/or modify
6
* it under the terms of the GNU General Public License as published by
7
* the Free Software Foundation; either version 2 of the License, or
8
* (at your option) any later version.
10
* This program is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
15
* You should have received a copy of the GNU General Public License
16
* along with this program; if not, write to the Free Software
17
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
#include <pjmedia/converter.h>
22
#if PJMEDIA_HAS_LIBSWSCALE && PJMEDIA_HAS_LIBAVUTIL
24
#include "ffmpeg_util.h"
25
#include <libswscale/swscale.h>
27
static pj_status_t factory_create_converter(pjmedia_converter_factory *cf,
29
const pjmedia_conversion_param*prm,
30
pjmedia_converter **p_cv);
31
static void factory_destroy_factory(pjmedia_converter_factory *cf);
32
static pj_status_t libswscale_conv_convert(pjmedia_converter *converter,
33
pjmedia_frame *src_frame,
34
pjmedia_frame *dst_frame);
35
static void libswscale_conv_destroy(pjmedia_converter *converter);
40
const pjmedia_video_format_info *fmt_info;
41
pjmedia_video_apply_fmt_param apply_param;
44
struct ffmpeg_converter
46
pjmedia_converter base;
47
struct SwsContext *sws_ctx;
52
static pjmedia_converter_factory_op libswscale_factory_op =
54
&factory_create_converter,
55
&factory_destroy_factory
58
static pjmedia_converter_op liswscale_converter_op =
60
&libswscale_conv_convert,
61
&libswscale_conv_destroy
64
static pj_status_t factory_create_converter(pjmedia_converter_factory *cf,
66
const pjmedia_conversion_param *prm,
67
pjmedia_converter **p_cv)
69
enum PixelFormat srcFormat, dstFormat;
70
const pjmedia_video_format_detail *src_detail, *dst_detail;
71
const pjmedia_video_format_info *src_fmt_info, *dst_fmt_info;
72
struct SwsContext *sws_ctx;
73
struct ffmpeg_converter *fcv;
78
/* Only supports video */
79
if (prm->src.type != PJMEDIA_TYPE_VIDEO ||
80
prm->dst.type != prm->src.type ||
81
prm->src.detail_type != PJMEDIA_FORMAT_DETAIL_VIDEO ||
82
prm->dst.detail_type != prm->src.detail_type)
87
/* lookup source format info */
88
src_fmt_info = pjmedia_get_video_format_info(
89
pjmedia_video_format_mgr_instance(),
94
/* lookup destination format info */
95
dst_fmt_info = pjmedia_get_video_format_info(
96
pjmedia_video_format_mgr_instance(),
101
src_detail = pjmedia_format_get_video_format_detail(&prm->src, PJ_TRUE);
102
dst_detail = pjmedia_format_get_video_format_detail(&prm->dst, PJ_TRUE);
104
status = pjmedia_format_id_to_PixelFormat(prm->src.id, &srcFormat);
105
if (status != PJ_SUCCESS)
108
status = pjmedia_format_id_to_PixelFormat(prm->dst.id, &dstFormat);
109
if (status != PJ_SUCCESS)
112
sws_ctx = sws_getContext(src_detail->size.w, src_detail->size.h, srcFormat,
113
dst_detail->size.w, dst_detail->size.h, dstFormat,
119
fcv = PJ_POOL_ZALLOC_T(pool, struct ffmpeg_converter);
120
fcv->base.op = &liswscale_converter_op;
121
fcv->sws_ctx = sws_ctx;
122
fcv->src.apply_param.size = src_detail->size;
123
fcv->src.fmt_info = src_fmt_info;
124
fcv->dst.apply_param.size = dst_detail->size;
125
fcv->dst.fmt_info = dst_fmt_info;
132
static void factory_destroy_factory(pjmedia_converter_factory *cf)
137
static pj_status_t libswscale_conv_convert(pjmedia_converter *converter,
138
pjmedia_frame *src_frame,
139
pjmedia_frame *dst_frame)
141
struct ffmpeg_converter *fcv = (struct ffmpeg_converter*)converter;
142
struct fmt_info *src = &fcv->src,
146
src->apply_param.buffer = src_frame->buf;
147
(*src->fmt_info->apply_fmt)(src->fmt_info, &src->apply_param);
149
dst->apply_param.buffer = dst_frame->buf;
150
(*dst->fmt_info->apply_fmt)(dst->fmt_info, &dst->apply_param);
152
h = sws_scale(fcv->sws_ctx,
153
(const uint8_t* const *)src->apply_param.planes,
154
src->apply_param.strides,
155
0, src->apply_param.size.h,
156
dst->apply_param.planes, dst->apply_param.strides);
158
//sws_scale() return value can't be trusted? There are cases when
159
//sws_scale() returns zero but conversion seems to work okay.
160
//return h==(int)dst->apply_param.size.h ? PJ_SUCCESS : PJ_EUNKNOWN;
166
static void libswscale_conv_destroy(pjmedia_converter *converter)
168
struct ffmpeg_converter *fcv = (struct ffmpeg_converter*)converter;
170
struct SwsContext *tmp = fcv->sws_ctx;
172
sws_freeContext(tmp);
176
static pjmedia_converter_factory libswscale_factory =
178
NULL, NULL, /* list */
179
"libswscale", /* name */
180
PJMEDIA_CONVERTER_PRIORITY_NORMAL+1, /* priority */
181
NULL /* op will be init-ed later */
185
pjmedia_libswscale_converter_init(pjmedia_converter_mgr *mgr)
187
libswscale_factory.op = &libswscale_factory_op;
188
pjmedia_ffmpeg_add_ref();
189
return pjmedia_converter_mgr_register_factory(mgr, &libswscale_factory);
194
pjmedia_libswscale_converter_shutdown(pjmedia_converter_mgr *mgr,
198
pjmedia_ffmpeg_dec_ref();
199
return pjmedia_converter_mgr_unregister_factory(mgr, &libswscale_factory,
204
# pragma comment( lib, "avutil.lib")
205
# pragma comment( lib, "swscale.lib")
208
#endif /* #if PJMEDIA_HAS_LIBSWSCALE && PJMEDIA_HAS_LIBAVUTIL */