~ubuntu-branches/ubuntu/wily/sflphone/wily

« back to all changes in this revision

Viewing changes to daemon/libs/pjproject-2.2.1/pjmedia/src/pjmedia/converter_libswscale.c

  • Committer: Package Import Robot
  • Author(s): Jonathan Riddell
  • Date: 2015-01-07 14:51:16 UTC
  • mfrom: (4.3.5 sid)
  • Revision ID: package-import@ubuntu.com-20150107145116-yxnafinf4lrdvrmx
Tags: 1.4.1-0.1ubuntu1
* Merge with Debian, remaining changes:
 - Drop soprano, nepomuk build-dep
* Drop ubuntu patches, now upstream

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* $Id: converter_libswscale.c 4076 2012-04-24 09:40:35Z bennylp $ */
 
2
/*
 
3
 * Copyright (C) 2010-2011 Teluu Inc. (http://www.teluu.com)
 
4
 *
 
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.
 
9
 *
 
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.
 
14
 *
 
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
 
18
 */
 
19
#include <pjmedia/converter.h>
 
20
#include <pj/errno.h>
 
21
 
 
22
#if PJMEDIA_HAS_LIBSWSCALE && PJMEDIA_HAS_LIBAVUTIL
 
23
 
 
24
#include "ffmpeg_util.h"
 
25
#include <libswscale/swscale.h>
 
26
 
 
27
static pj_status_t factory_create_converter(pjmedia_converter_factory *cf,
 
28
                                            pj_pool_t *pool,
 
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);
 
36
 
 
37
 
 
38
struct fmt_info
 
39
{
 
40
    const pjmedia_video_format_info     *fmt_info;
 
41
    pjmedia_video_apply_fmt_param        apply_param;
 
42
};
 
43
 
 
44
struct ffmpeg_converter
 
45
{
 
46
    pjmedia_converter                    base;
 
47
    struct SwsContext                   *sws_ctx;
 
48
    struct fmt_info                      src,
 
49
                                         dst;
 
50
};
 
51
 
 
52
static pjmedia_converter_factory_op libswscale_factory_op =
 
53
{
 
54
    &factory_create_converter,
 
55
    &factory_destroy_factory
 
56
};
 
57
 
 
58
static pjmedia_converter_op liswscale_converter_op =
 
59
{
 
60
    &libswscale_conv_convert,
 
61
    &libswscale_conv_destroy
 
62
};
 
63
 
 
64
static pj_status_t factory_create_converter(pjmedia_converter_factory *cf,
 
65
                                            pj_pool_t *pool,
 
66
                                            const pjmedia_conversion_param *prm,
 
67
                                            pjmedia_converter **p_cv)
 
68
{
 
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;
 
74
    pj_status_t status;
 
75
 
 
76
    PJ_UNUSED_ARG(cf);
 
77
 
 
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)
 
83
    {
 
84
        return PJ_ENOTSUP;
 
85
    }
 
86
 
 
87
    /* lookup source format info */
 
88
    src_fmt_info = pjmedia_get_video_format_info(
 
89
                      pjmedia_video_format_mgr_instance(),
 
90
                      prm->src.id);
 
91
    if (!src_fmt_info)
 
92
        return PJ_ENOTSUP;
 
93
 
 
94
    /* lookup destination format info */
 
95
    dst_fmt_info = pjmedia_get_video_format_info(
 
96
                      pjmedia_video_format_mgr_instance(),
 
97
                      prm->dst.id);
 
98
    if (!dst_fmt_info)
 
99
        return PJ_ENOTSUP;
 
100
 
 
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);
 
103
 
 
104
    status = pjmedia_format_id_to_PixelFormat(prm->src.id, &srcFormat);
 
105
    if (status != PJ_SUCCESS)
 
106
        return PJ_ENOTSUP;
 
107
 
 
108
    status = pjmedia_format_id_to_PixelFormat(prm->dst.id, &dstFormat);
 
109
    if (status != PJ_SUCCESS)
 
110
        return PJ_ENOTSUP;
 
111
 
 
112
    sws_ctx = sws_getContext(src_detail->size.w, src_detail->size.h, srcFormat,
 
113
                             dst_detail->size.w, dst_detail->size.h, dstFormat,
 
114
                             SWS_BICUBIC,
 
115
                             NULL, NULL, NULL);
 
116
    if (sws_ctx == NULL)
 
117
        return PJ_ENOTSUP;
 
118
 
 
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;
 
126
 
 
127
    *p_cv = &fcv->base;
 
128
 
 
129
    return PJ_SUCCESS;
 
130
}
 
131
 
 
132
static void factory_destroy_factory(pjmedia_converter_factory *cf)
 
133
{
 
134
    PJ_UNUSED_ARG(cf);
 
135
}
 
136
 
 
137
static pj_status_t libswscale_conv_convert(pjmedia_converter *converter,
 
138
                                           pjmedia_frame *src_frame,
 
139
                                           pjmedia_frame *dst_frame)
 
140
{
 
141
    struct ffmpeg_converter *fcv = (struct ffmpeg_converter*)converter;
 
142
    struct fmt_info *src = &fcv->src,
 
143
                    *dst = &fcv->dst;
 
144
    int h;
 
145
 
 
146
    src->apply_param.buffer = src_frame->buf;
 
147
    (*src->fmt_info->apply_fmt)(src->fmt_info, &src->apply_param);
 
148
 
 
149
    dst->apply_param.buffer = dst_frame->buf;
 
150
    (*dst->fmt_info->apply_fmt)(dst->fmt_info, &dst->apply_param);
 
151
 
 
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);
 
157
 
 
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;
 
161
    PJ_UNUSED_ARG(h);
 
162
 
 
163
    return PJ_SUCCESS;
 
164
}
 
165
 
 
166
static void libswscale_conv_destroy(pjmedia_converter *converter)
 
167
{
 
168
    struct ffmpeg_converter *fcv = (struct ffmpeg_converter*)converter;
 
169
    if (fcv->sws_ctx) {
 
170
        struct SwsContext *tmp = fcv->sws_ctx;
 
171
        fcv->sws_ctx = NULL;
 
172
        sws_freeContext(tmp);
 
173
    }
 
174
}
 
175
 
 
176
static pjmedia_converter_factory libswscale_factory =
 
177
{
 
178
    NULL, NULL,                                 /* list */
 
179
    "libswscale",                               /* name */
 
180
    PJMEDIA_CONVERTER_PRIORITY_NORMAL+1,        /* priority */
 
181
    NULL                                        /* op will be init-ed later  */
 
182
};
 
183
 
 
184
PJ_DEF(pj_status_t)
 
185
pjmedia_libswscale_converter_init(pjmedia_converter_mgr *mgr)
 
186
{
 
187
    libswscale_factory.op = &libswscale_factory_op;
 
188
    pjmedia_ffmpeg_add_ref();
 
189
    return pjmedia_converter_mgr_register_factory(mgr, &libswscale_factory);
 
190
}
 
191
 
 
192
 
 
193
PJ_DEF(pj_status_t)
 
194
pjmedia_libswscale_converter_shutdown(pjmedia_converter_mgr *mgr,
 
195
                                      pj_pool_t *pool)
 
196
{
 
197
    PJ_UNUSED_ARG(pool);
 
198
    pjmedia_ffmpeg_dec_ref();
 
199
    return pjmedia_converter_mgr_unregister_factory(mgr, &libswscale_factory,
 
200
                                                    PJ_TRUE);
 
201
}
 
202
 
 
203
#ifdef _MSC_VER
 
204
#   pragma comment( lib, "avutil.lib")
 
205
#   pragma comment( lib, "swscale.lib")
 
206
#endif
 
207
 
 
208
#endif /* #if PJMEDIA_HAS_LIBSWSCALE && PJMEDIA_HAS_LIBAVUTIL */