Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
BC
public
mediastreamer2
Commits
364f3eca
Commit
364f3eca
authored
Dec 06, 2016
by
Erwan Croze
👋🏻
Browse files
Adding turbojpeg a new jpeg dec/enc
parent
44348f4c
Changes
10
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
675 additions
and
248 deletions
+675
-248
CMakeLists.txt
CMakeLists.txt
+16
-3
cmake/FindTurboJpeg.cmake
cmake/FindTurboJpeg.cmake
+47
-0
src/CMakeLists.txt
src/CMakeLists.txt
+30
-4
src/utils/ffmpeg-priv.h
src/utils/ffmpeg-priv.h
+8
-8
src/videofilters/ffmpegjpegwriter.c
src/videofilters/ffmpegjpegwriter.c
+1
-1
src/videofilters/ffmpegnowebcam.c
src/videofilters/ffmpegnowebcam.c
+178
-0
src/videofilters/nowebcam.c
src/videofilters/nowebcam.c
+87
-231
src/videofilters/turbojpegnowebcam.c
src/videofilters/turbojpegnowebcam.c
+106
-0
src/videofilters/turbojpegwriter.c
src/videofilters/turbojpegwriter.c
+201
-0
src/voip/nowebcam.h
src/voip/nowebcam.h
+1
-1
No files found.
CMakeLists.txt
View file @
364f3eca
...
...
@@ -90,6 +90,7 @@ option(ENABLE_BV16 "Build mediastreamer2 with the BV16 codec." YES)
option
(
ENABLE_OPUS
"Build mediastreamer2 with the OPUS codec."
YES
)
option
(
ENABLE_SPEEX_CODEC
"Build mediastreamer2 with the SPEEX codec."
YES
)
option
(
ENABLE_SPEEX_DSP
"Build mediastreamer2 with the SPEEX DSP support."
YES
)
option
(
ENABLE_G729B_CNG
"Build mediastremer2 with G729 annex B cng."
NO
)
cmake_dependent_option
(
ENABLE_RESAMPLE
"Build mediastreamer2 with the resampling capability."
YES
"ENABLE_SPEEX_DSP"
NO
)
option
(
ENABLE_VIDEO
"Build mediastreamer2 with video support."
YES
)
...
...
@@ -104,7 +105,7 @@ cmake_dependent_option(ENABLE_VPX "Build mediastreamer2 with VPX codec." YES "EN
option
(
ENABLE_MKV
"Enable support of MKV files reading and writing."
YES
)
cmake_dependent_option
(
ENABLE_QNX
"Build medistreamer2 with BB10 filters."
NO
"ENABLE_VIDEO"
NO
)
cmake_dependent_option
(
ENABLE_VT_H264
"Build mediastreamer2 with H264 encoder/decoder based on VirtualToolbox (Apple only)"
YES
"ENABLE_VIDEO"
NO
)
option
(
ENABLE_
G729B_CNG
"Build mediastremer2 with G729 annex B cng."
NO
)
option
(
ENABLE_
JPEG
"Enable JPEG support"
YES
)
macro
(
apply_compile_flags SOURCE_FILES
)
if
(
${
SOURCE_FILES
}
)
...
...
@@ -324,6 +325,14 @@ if(ENABLE_G729B_CNG)
endif
()
endif
()
if
(
ENABLE_JPEG
)
find_package
(
TurboJpeg
)
if
(
NOT TURBOJPEG_FOUND
)
message
(
WARNING
"Could not find libturbo-jpeg, mediastreamer2 will be compiled without LibJpeg-Turbo"
)
set
(
ENABLE_JPEG OFF CACHE BOOL
"Enable JPEG support"
FORCE
)
endif
()
endif
()
if
(
LINPHONE_BUILDER_GROUP_EXTERNAL_SOURCE_PATH_BUILDERS
)
set
(
BcToolbox_FIND_COMPONENTS tester
)
include
(
"
${
EP_bctoolbox_CONFIG_DIR
}
/BcToolboxConfig.cmake"
)
...
...
@@ -414,6 +423,9 @@ endif()
if
(
MSVC_INCLUDE_DIR
)
include_directories
(
${
MSVC_INCLUDE_DIR
}
)
endif
()
if
(
TURBOJPEG_FOUND
)
include_directories
(
${
TURBOJPEG_INCLUDE_DIRS
}
)
endif
()
if
(
ENABLE_ANDROIDSND
)
include_directories
(
src/android
...
...
@@ -471,6 +483,9 @@ endif()
if
(
MATROSKA2_FOUND
)
set
(
HAVE_MATROSKA 1
)
endif
()
if
(
TURBO_JPEG_FOUND
)
set
(
HAVE_TURBO_JPEG 1
)
endif
()
if
(
ENABLE_RELATIVE_PREFIX
)
if
(
CMAKE_SYSTEM_NAME STREQUAL
"WindowsPhone"
OR CMAKE_SYSTEM_NAME STREQUAL
"WindowsStore"
)
set
(
PACKAGE_PLUGINS_DIR
"."
)
...
...
@@ -593,5 +608,3 @@ install(FILES
"
${
CMAKE_CURRENT_BINARY_DIR
}
/Mediastreamer2ConfigVersion.cmake"
DESTINATION
${
CONFIG_PACKAGE_LOCATION
}
)
cmake/FindTurboJpeg.cmake
0 → 100644
View file @
364f3eca
############################################################################
# FindTurboJpeg.txt
# Copyright (C) 2016 Belledonne Communications, Grenoble France
#
############################################################################
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
############################################################################
#
# - Find the turbojpeg include file and library
#
# TURBOJPEG_FOUND - system has turbojpeg
# TURBOJPEG_INCLUDE_DIRS - the turbojpeg include directory
# TURBOJPEG_LIBRARIES - The libraries needed to use turbojpeg
find_path
(
TURBOJPEG_INCLUDE_DIRS
NAMES turbojpeg.h
PATH_SUFFIXES include
)
if
(
TURBOJPEG_INCLUDE_DIRS
)
set
(
HAVE_TURBOJPEG_H 1
)
endif
()
find_library
(
TURBOJPEG_LIBRARIES
NAMES turbojpeg
)
include
(
FindPackageHandleStandardArgs
)
find_package_handle_standard_args
(
TurboJpeg
DEFAULT_MSG
TURBOJPEG_INCLUDE_DIRS TURBOJPEG_LIBRARIES
)
mark_as_advanced
(
TURBOJPEG_INCLUDE_DIRS TURBOJPEG_LIBRARIES
)
src/CMakeLists.txt
View file @
364f3eca
...
...
@@ -283,6 +283,15 @@ if(ENABLE_VIDEO)
voip/videostream.c
voip/video_preset_high_fps.c
)
if
(
FFMPEG_FOUND AND NOT TURBOJPEG_FOUND
)
list
(
APPEND VOIP_SOURCE_FILES_C
videofilters/ffmpegnowebcam.c
)
elseif
(
TURBOJPEG_FOUND
)
list
(
APPEND VOIP_SOURCE_FILES_C
videofilters/turbojpegnowebcam.c
)
endif
()
if
(
WIN32 AND NOT CMAKE_SYSTEM_NAME STREQUAL
"WindowsPhone"
AND NOT CMAKE_SYSTEM_NAME STREQUAL
"WindowsStore"
)
add_definitions
(
-DHAVE_DIRECTSHOW
)
list
(
APPEND VOIP_SOURCE_FILES_C
...
...
@@ -311,7 +320,7 @@ if(ENABLE_VIDEO)
videofilters/msosxdisplay.m
videofilters/avfound-capture.m
)
list
(
APPEND VOIP_SOURCE_FILES_C
utils/opengles_display.c
utils/opengles_display.h
...
...
@@ -358,10 +367,19 @@ if(ENABLE_VIDEO)
utils/ffmpeg-priv.h
utils/swscale.h
videofilters/h264dec.c
videofilters/jpegwriter.c
videofilters/videodec.c
videofilters/videoenc.c
)
if
(
NOT TURBOJPEG_FOUND
)
list
(
APPEND VOIP_SOURCE_FILES_C
videofilters/ffmpegjpegwriter.c
)
endif
()
endif
()
if
(
TURBOJPEG_FOUND
)
list
(
APPEND VOIP_SOURCE_FILES_C
videofilters/turbojpegwriter.c
)
endif
()
if
(
GLX_FOUND
)
list
(
APPEND VOIP_SOURCE_FILES_C
...
...
@@ -577,6 +595,9 @@ endif()
if
(
CAMAPI_FOUND
)
list
(
APPEND VOIP_LIBS
${
CAMAPI_LIBRARIES
}
)
endif
()
if
(
TURBOJPEG_FOUND
)
list
(
APPEND VOIP_LIBS
${
TURBOJPEG_LIBRARIES
}
)
endif
()
if
(
BCGG729_FOUND
)
add_definitions
(
-DHAVE_G729B=1
)
list
(
APPEND VOIP_LIBS
${
BCG729_LIBRARIES
}
)
...
...
@@ -632,12 +653,17 @@ endif()
if
(
FFMPEG_FOUND AND NOT WIN32
)
set
(
NO_DEPRECATED_DECLARATIONS_SOURCE_FILES
videofilters/jpegwriter.c
videofilters/videoenc.c
videofilters/videodec.c
videofilters/nowebcam.c
videofilters/h264dec.c
)
if
(
NOT TURBOJPEG_FOUND
)
set
(
NO_DEPRECATED_DECLARATIONS_SOURCE_FILES
${
NO_DEPRECATED_DECLARATIONS_SOURCE_FILES
}
videofilters/ffmpegjpegwriter.c
videofilters/nowebcam.c
)
endif
()
foreach
(
file
${
NO_DEPRECATED_DECLARATIONS_SOURCE_FILES
}
)
get_source_file_property
(
NO_DEPRECATED_DECLARATIONS_COMPILE_FLAGS
${
file
}
COMPILE_FLAGS
)
set_source_files_properties
(
${
file
}
PROPERTIES COMPILE_FLAGS
"
${
NO_DEPRECATED_DECLARATIONS_COMPILE_FLAGS
}
-Wno-error=deprecated-declarations"
)
...
...
src/utils/ffmpeg-priv.h
View file @
364f3eca
...
...
@@ -63,7 +63,7 @@ typedef struct AVPacket{
}
AVPacket
;
static
inline
void
av_init_packet
(
AVPacket
*
pkt
){
}
static
inline
int
avcodec_decode_video2
(
AVCodecContext
*
avctx
,
AVFrame
*
picture
,
int
*
got_picture_ptr
,
...
...
@@ -71,7 +71,7 @@ static inline int avcodec_decode_video2(AVCodecContext *avctx, AVFrame *picture,
return
avcodec_decode_video
(
avctx
,
picture
,
got_picture_ptr
,
avpkt
->
data
,
avpkt
->
size
);
}
#endif
#if HAVE_AVCODEC_OLD_CODEC_IDS
#if HAVE_AVCODEC_OLD_CODEC_IDS
#include <libavcodec/old_codec_ids.h>
#endif
...
...
@@ -90,15 +90,15 @@ static inline int avcodec_decode_video2(AVCodecContext *avctx, AVFrame *picture,
#endif
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(54,25,0)
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(54,25,0)
/*CODEC_ID_* and CodecID have been deprecated for a long time and this release removes it altogether. Please use AV_CODEC_ID_* and AVCodecID instead.*/
#define CodecID AVCodecID
#ifndef HAVE_AVCODEC_OLD_CODEC_IDS
#define CODEC_ID_H264 AV_CODEC_ID_H264
#define CODEC_ID_H263 AV_CODEC_ID_H263
#define CODEC_ID_H263P AV_CODEC_ID_H263P
#define CODEC_ID_MPEG4 AV_CODEC_ID_MPEG4
#define CODEC_ID_MJPEG AV_CODEC_ID_MJPEG
#define CODEC_ID_H264 AV_CODEC_ID_H264
#define CODEC_ID_H263 AV_CODEC_ID_H263
#define CODEC_ID_H263P AV_CODEC_ID_H263P
#define CODEC_ID_MPEG4 AV_CODEC_ID_MPEG4
#define CODEC_ID_MJPEG AV_CODEC_ID_MJPEG
#endif
#endif
...
...
src/videofilters/jpegwriter.c
→
src/videofilters/
ffmpeg
jpegwriter.c
View file @
364f3eca
...
...
@@ -72,7 +72,7 @@ static void close_file(JpegWriter *obj, bool_t doRenaming) {
}
ms_free
(
obj
->
filename
);
obj
->
filename
=
NULL
;
ms_free
(
obj
->
tmpFilename
);
obj
->
tmpFilename
=
NULL
;
}
...
...
src/videofilters/ffmpegnowebcam.c
0 → 100644
View file @
364f3eca
/*
mediastreamer2 library - modular sound and video processing and streaming
Copyright (C) 2006 Simon MORLAT (simon.morlat@linphone.org)
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifdef HAVE_CONFIG_H
#include "mediastreamer-config.h"
#endif
#include "mediastreamer2/msvideo.h"
#if __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
#endif
#ifndef NO_FFMPEG
#include "ffmpeg-priv.h"
#else
#define FF_INPUT_BUFFER_PADDING_SIZE 32
#endif
#if LIBAVCODEC_VERSION_MAJOR >= 57
#ifdef _MSC_VER
#pragma warning(disable : 4996)
#else
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#endif
#endif
#if TARGET_OS_IPHONE
#include <CoreGraphics/CGDataProvider.h>
#include <CoreGraphics/CGImage.h>
#include <CoreGraphics/CGContext.h>
#include <CoreGraphics/CGBitmapContext.h>
#endif
#ifdef _WIN32
#include <fcntl.h>
#include <sys/types.h>
#include <io.h>
#include <stdio.h>
#include <malloc.h>
#endif
mblk_t
*
jpeg2yuv
(
uint8_t
*
jpgbuf
,
int
bufsize
,
MSVideoSize
*
reqsize
){
#if !defined(NO_FFMPEG) && !TARGET_OS_IPHONE
/* this code must never be used for iOS */
AVCodecContext
av_context
;
int
got_picture
=
0
;
mblk_t
*
ret
;
struct
SwsContext
*
sws_ctx
;
AVPacket
pkt
;
MSPicture
dest
;
AVCodec
*
codec
=
avcodec_find_decoder
(
CODEC_ID_MJPEG
);
AVFrame
*
orig
=
av_frame_alloc
();
if
(
codec
==
NULL
){
ms_error
(
"Could not find MJPEG decoder in ffmpeg."
);
return
NULL
;
}
avcodec_get_context_defaults3
(
&
av_context
,
NULL
);
if
(
avcodec_open2
(
&
av_context
,
codec
,
NULL
)
<
0
){
ms_error
(
"jpeg2yuv: avcodec_open failed"
);
return
NULL
;
}
av_init_packet
(
&
pkt
);
pkt
.
data
=
jpgbuf
;
pkt
.
size
=
bufsize
;
if
(
avcodec_decode_video2
(
&
av_context
,
orig
,
&
got_picture
,
&
pkt
)
<
0
)
{
ms_error
(
"jpeg2yuv: avcodec_decode_video failed"
);
avcodec_close
(
&
av_context
);
return
NULL
;
}
ret
=
ms_yuv_buf_alloc
(
&
dest
,
reqsize
->
width
,
reqsize
->
height
);
/* not using SWS_FAST_BILINEAR because it doesn't play well with
* av_context.pix_fmt set to AV_PIX_FMT_YUVJ420P by jpeg decoder */
sws_ctx
=
sws_getContext
(
av_context
.
width
,
av_context
.
height
,
av_context
.
pix_fmt
,
reqsize
->
width
,
reqsize
->
height
,
AV_PIX_FMT_YUV420P
,
SWS_BILINEAR
,
NULL
,
NULL
,
NULL
);
if
(
sws_ctx
==
NULL
)
{
ms_error
(
"jpeg2yuv: ms_sws_getContext() failed."
);
avcodec_close
(
&
av_context
);
freemsg
(
ret
);
return
NULL
;
}
#if LIBSWSCALE_VERSION_INT >= AV_VERSION_INT(0,9,0)
if
(
sws_scale
(
sws_ctx
,(
const
uint8_t
*
const
*
)
orig
->
data
,
orig
->
linesize
,
0
,
av_context
.
height
,
dest
.
planes
,
dest
.
strides
)
<
0
){
#else
if
(
sws_scale
(
sws_ctx
,(
uint8_t
**
)
orig
->
data
,
orig
->
linesize
,
0
,
av_context
.
height
,
dest
.
planes
,
dest
.
strides
)
<
0
){
#endif
ms_error
(
"jpeg2yuv: ms_sws_scale() failed."
);
sws_freeContext
(
sws_ctx
);
avcodec_close
(
&
av_context
);
freemsg
(
ret
);
return
NULL
;
}
sws_freeContext
(
sws_ctx
);
av_frame_free
(
&
orig
);
avcodec_close
(
&
av_context
);
return
ret
;
#elif TARGET_OS_IPHONE
MSPicture
dest
;
CGDataProviderRef
dataProvider
=
CGDataProviderCreateWithData
(
NULL
,
jpgbuf
,
bufsize
,
NULL
);
// use the data provider to get a CGImage; release the data provider
CGImageRef
image
=
CGImageCreateWithJPEGDataProvider
(
dataProvider
,
NULL
,
FALSE
,
kCGRenderingIntentDefault
);
CGDataProviderRelease
(
dataProvider
);
reqsize
->
width
=
CGImageGetWidth
(
image
);
reqsize
->
height
=
CGImageGetHeight
(
image
);
uint8_t
*
tmp
=
(
uint8_t
*
)
malloc
(
reqsize
->
width
*
reqsize
->
height
*
4
);
mblk_t
*
ret
=
ms_yuv_buf_alloc
(
&
dest
,
reqsize
->
width
,
reqsize
->
height
);
CGColorSpaceRef
colourSpace
=
CGColorSpaceCreateDeviceRGB
();
CGContextRef
imageContext
=
CGBitmapContextCreate
(
tmp
,
reqsize
->
width
,
reqsize
->
height
,
8
,
reqsize
->
width
*
4
,
colourSpace
,
kCGImageAlphaNoneSkipLast
);
CGColorSpaceRelease
(
colourSpace
);
// draw the image to the context, release it
CGContextDrawImage
(
imageContext
,
CGRectMake
(
0
,
0
,
reqsize
->
width
,
reqsize
->
height
),
image
);
CGImageRelease
(
image
);
/* convert tmp/RGB -> ret/YUV */
for
(
int
y
=
0
;
y
<
reqsize
->
height
;
y
++
)
{
for
(
int
x
=
0
;
x
<
reqsize
->
width
;
x
++
)
{
uint8_t
r
=
tmp
[
y
*
reqsize
->
width
*
4
+
x
*
4
+
0
];
uint8_t
g
=
tmp
[
y
*
reqsize
->
width
*
4
+
x
*
4
+
1
];
uint8_t
b
=
tmp
[
y
*
reqsize
->
width
*
4
+
x
*
4
+
2
];
// Y
*
dest
.
planes
[
0
]
++
=
(
uint8_t
)((
0
.
257
*
r
)
+
(
0
.
504
*
g
)
+
(
0
.
098
*
b
)
+
16
);
// U/V subsampling
if
((
y
%
2
==
0
)
&&
(
x
%
2
==
0
))
{
uint32_t
r32
=
0
,
g32
=
0
,
b32
=
0
;
for
(
int
i
=
0
;
i
<
2
;
i
++
)
{
for
(
int
j
=
0
;
j
<
2
;
j
++
)
{
r32
+=
tmp
[(
y
+
i
)
*
reqsize
->
width
*
4
+
(
x
+
j
)
*
4
+
0
];
g32
+=
tmp
[(
y
+
i
)
*
reqsize
->
width
*
4
+
(
x
+
j
)
*
4
+
1
];
b32
+=
tmp
[(
y
+
i
)
*
reqsize
->
width
*
4
+
(
x
+
j
)
*
4
+
2
];
}
}
r32
=
(
uint32_t
)(
r32
*
0
.
25
f
);
g32
=
(
uint32_t
)(
g32
*
0
.
25
f
);
b32
=
(
uint32_t
)
(
b32
*
0
.
25
f
);
// U
*
dest
.
planes
[
1
]
++
=
(
uint8_t
)(
-
(
0
.
148
*
r32
)
-
(
0
.
291
*
g32
)
+
(
0
.
439
*
b32
)
+
128
);
// V
*
dest
.
planes
[
2
]
++
=
(
uint8_t
)((
0
.
439
*
r32
)
-
(
0
.
368
*
g32
)
-
(
0
.
071
*
b32
)
+
128
);
}
}
}
free
(
tmp
);
return
ret
;
#else
return
NULL
;
#endif
}
#if __clang__
#pragma clang diagnostic pop
#endif
src/videofilters/nowebcam.c
View file @
364f3eca
...
...
@@ -17,7 +17,6 @@ along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifdef HAVE_CONFIG_H
#include "mediastreamer-config.h"
#endif
...
...
@@ -27,6 +26,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "mediastreamer2/msfilter.h"
#include "mediastreamer2/msticker.h"
#include "mediastreamer2/mswebcam.h"
#include "../voip/nowebcam.h"
#if __clang__
...
...
@@ -34,11 +34,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
#endif
#ifndef NO_FFMPEG
#include "ffmpeg-priv.h"
#else
#define FF_INPUT_BUFFER_PADDING_SIZE 32
#endif
#if LIBAVCODEC_VERSION_MAJOR >= 57
...
...
@@ -59,134 +55,9 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include <sys/stat.h>
#ifdef _WIN32
#include <fcntl.h>
#include <sys/types.h>
#include <io.h>
#include <stdio.h>
#include <malloc.h>
#endif
static
mblk_t
*
jpeg2yuv
(
uint8_t
*
jpgbuf
,
int
bufsize
,
MSVideoSize
*
reqsize
){
#if !defined(NO_FFMPEG) && !TARGET_OS_IPHONE
/* this code must never be used for iOS */
AVCodecContext
av_context
;
int
got_picture
=
0
;
mblk_t
*
ret
;
struct
SwsContext
*
sws_ctx
;
AVPacket
pkt
;
MSPicture
dest
;
AVCodec
*
codec
=
avcodec_find_decoder
(
CODEC_ID_MJPEG
);
AVFrame
*
orig
=
av_frame_alloc
();
if
(
codec
==
NULL
){
ms_error
(
"Could not find MJPEG decoder in ffmpeg."
);
return
NULL
;
}
avcodec_get_context_defaults3
(
&
av_context
,
NULL
);
if
(
avcodec_open2
(
&
av_context
,
codec
,
NULL
)
<
0
){
ms_error
(
"jpeg2yuv: avcodec_open failed"
);
return
NULL
;
}
av_init_packet
(
&
pkt
);
pkt
.
data
=
jpgbuf
;
pkt
.
size
=
bufsize
;
if
(
avcodec_decode_video2
(
&
av_context
,
orig
,
&
got_picture
,
&
pkt
)
<
0
)
{
ms_error
(
"jpeg2yuv: avcodec_decode_video failed"
);
avcodec_close
(
&
av_context
);
return
NULL
;
}
ret
=
ms_yuv_buf_alloc
(
&
dest
,
reqsize
->
width
,
reqsize
->
height
);
/* not using SWS_FAST_BILINEAR because it doesn't play well with
* av_context.pix_fmt set to AV_PIX_FMT_YUVJ420P by jpeg decoder */
sws_ctx
=
sws_getContext
(
av_context
.
width
,
av_context
.
height
,
av_context
.
pix_fmt
,
reqsize
->
width
,
reqsize
->
height
,
AV_PIX_FMT_YUV420P
,
SWS_BILINEAR
,
NULL
,
NULL
,
NULL
);
if
(
sws_ctx
==
NULL
)
{
ms_error
(
"jpeg2yuv: ms_sws_getContext() failed."
);
avcodec_close
(
&
av_context
);
freemsg
(
ret
);
return
NULL
;
}
#if LIBSWSCALE_VERSION_INT >= AV_VERSION_INT(0,9,0)
if
(
sws_scale
(
sws_ctx
,(
const
uint8_t
*
const
*
)
orig
->
data
,
orig
->
linesize
,
0
,
av_context
.
height
,
dest
.
planes
,
dest
.
strides
)
<
0
){
#else
if
(
sws_scale
(
sws_ctx
,(
uint8_t
**
)
orig
->
data
,
orig
->
linesize
,
0
,
av_context
.
height
,
dest
.
planes
,
dest
.
strides
)
<
0
){
#endif
ms_error
(
"jpeg2yuv: ms_sws_scale() failed."
);
sws_freeContext
(
sws_ctx
);
avcodec_close
(
&
av_context
);
freemsg
(
ret
);
return
NULL
;
}
sws_freeContext
(
sws_ctx
);
av_frame_free
(
&
orig
);
avcodec_close
(
&
av_context
);
return
ret
;
#elif TARGET_OS_IPHONE
MSPicture
dest
;
CGDataProviderRef
dataProvider
=
CGDataProviderCreateWithData
(
NULL
,
jpgbuf
,
bufsize
,
NULL
);
// use the data provider to get a CGImage; release the data provider
CGImageRef
image
=
CGImageCreateWithJPEGDataProvider
(
dataProvider
,
NULL
,
FALSE
,
kCGRenderingIntentDefault
);
CGDataProviderRelease
(
dataProvider
);
reqsize
->
width
=
CGImageGetWidth
(
image
);
reqsize
->
height
=
CGImageGetHeight
(
image
);
uint8_t
*
tmp
=
(
uint8_t
*
)
malloc
(
reqsize
->
width
*
reqsize
->
height
*
4
);
mblk_t
*
ret
=
ms_yuv_buf_alloc
(
&
dest
,
reqsize
->
width
,
reqsize
->
height
);
CGColorSpaceRef
colourSpace
=
CGColorSpaceCreateDeviceRGB
();
CGContextRef
imageContext
=
CGBitmapContextCreate
(
tmp
,
reqsize
->
width
,
reqsize
->
height
,
8
,
reqsize
->
width
*
4
,
colourSpace
,
kCGImageAlphaNoneSkipLast
);
CGColorSpaceRelease
(
colourSpace
);
// draw the image to the context, release it
CGContextDrawImage
(
imageContext
,
CGRectMake
(
0
,
0
,
reqsize
->
width
,
reqsize
->
height
),
image
);
CGImageRelease
(
image
);
/* convert tmp/RGB -> ret/YUV */
for
(
int
y
=
0
;
y
<
reqsize
->
height
;
y
++
)
{
for
(
int
x
=
0
;
x
<
reqsize
->
width
;
x
++
)
{
uint8_t
r
=
tmp
[
y
*
reqsize
->
width
*
4
+
x
*
4
+
0
];
uint8_t
g
=
tmp
[
y
*
reqsize
->
width
*
4
+
x
*
4
+
1
];
uint8_t
b
=
tmp
[
y
*
reqsize
->
width
*
4
+
x
*
4
+
2
];
// Y
*
dest
.
planes
[
0
]
++
=
(
uint8_t
)((
0
.
257
*
r
)
+
(
0
.
504
*
g
)
+
(
0
.
098
*
b
)
+
16
);
// U/V subsampling
if
((
y
%
2
==
0
)
&&
(
x
%
2
==
0
))
{
uint32_t
r32
=
0
,
g32
=
0
,
b32
=
0
;
for
(
int
i
=
0
;
i
<
2
;
i
++
)
{
for
(
int
j
=
0
;
j
<
2
;
j
++
)
{
r32
+=
tmp
[(
y
+
i
)
*
reqsize
->
width
*
4
+
(
x
+
j
)
*
4
+
0
];
g32
+=
tmp
[(
y
+
i
)
*
reqsize
->
width
*
4
+
(
x
+
j
)
*
4
+
1
];
b32
+=
tmp
[(
y
+
i
)
*
reqsize
->
width
*
4
+
(
x
+
j
)
*
4
+
2
];
}
}
r32
=
(
uint32_t
)(
r32
*
0
.
25
f
);
g32
=
(
uint32_t
)(
g32
*
0
.
25
f
);
b32
=
(
uint32_t
)
(
b32
*
0
.
25
f
);
// U
*
dest
.
planes
[
1
]
++
=
(
uint8_t
)(
-
(
0
.
148
*
r32
)
-
(
0
.
291
*
g32
)
+
(
0
.
439
*
b32
)
+
128
);
// V
*
dest
.
planes
[
2
]
++
=
(
uint8_t
)((
0
.
439
*
r32
)
-
(
0
.
368
*
g32
)
-
(
0
.
071
*
b32
)
+
128
);
}
}
}
free
(
tmp
);
return
ret
;
#else
return
NULL
;
#endif
}
static
mblk_t
*
_ms_load_jpeg_as_yuv
(
const
char
*
jpgpath
,
MSVideoSize
*
reqsize
){
static
mblk_t
*
_ms_load_jpeg_as_yuv
(
const
char
*
jpgpath
,
MSVideoSize
*
reqsize
)
{
#if defined(_WIN32)
mblk_t
*
m
=
NULL
;
mblk_t
*
m
=
NULL
;
DWORD
st_sizel
;
DWORD
st_sizeh
;
uint8_t
*
jpgbuf
;
...
...
@@ -203,12 +74,12 @@ static mblk_t *_ms_load_jpeg_as_yuv(const char *jpgpath, MSVideoSize *reqsize){
#else
fd
=
CreateFile
(
wUnicode
,
GENERIC_READ
,
FILE_SHARE_READ
,
NULL
,
OPEN_EXISTING
,
0
,
NULL
);
#endif
if
(
fd
==
INVALID_HANDLE_VALUE
){
if
(
fd
==
INVALID_HANDLE_VALUE
)
{
ms_error
(
"Failed to open %s"
,
jpgpath
);
return
NULL
;
}
st_sizel
=
0
;
st_sizeh
=
0
;
st_sizel
=
0
;
st_sizeh
=
0
;
#ifndef MS2_WINDOWS_DESKTOP
{
WIN32_FILE_ATTRIBUTE_DATA
attr_data
;
...
...
@@ -219,71 +90,65 @@ static mblk_t *_ms_load_jpeg_as_yuv(const char *jpgpath, MSVideoSize *reqsize){
#else
st_sizel
=
GetFileSize
(
fd
,
&
st_sizeh
);
#endif
if
(
st_sizeh
>
0
||
st_sizel
<=
0
)
{
if
(
st_sizeh
>
0
||
st_sizel
<=
0
)
{
CloseHandle
(
fd
);
ms_error
(
"Can't load file %s"
,
jpgpath
);
return
NULL
;
}
jpgbuf
=
(
uint8_t
*
)
ms_malloc0
(
st_sizel
);
if
(
jpgbuf
==
NULL
)
{
if
(
jpgbuf
==
NULL
)
{
CloseHandle
(
fd
);
ms_error
(
"Cannot allocate buffer for %s"
,
jpgpath
);
ms_error
(
"Cannot allocate buffer for %s"
,
jpgpath
);
return
NULL
;
}
err
=
0
;
err
=
0
;
ReadFile
(
fd
,
jpgbuf
,
st_sizel
,
&
err
,
NULL
)
;