Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
V
vlc
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Redmine
Redmine
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
videolan
vlc
Commits
286fa11d
Commit
286fa11d
authored
May 20, 2015
by
Thomas Guillem
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
mediacodec: add NDK module
The JNI module is now a submodule.
parent
cae9e8d8
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
559 additions
and
3 deletions
+559
-3
modules/codec/Makefile.am
modules/codec/Makefile.am
+1
-1
modules/codec/omxil/mediacodec.c
modules/codec/omxil/mediacodec.c
+12
-2
modules/codec/omxil/mediacodec.h
modules/codec/omxil/mediacodec.h
+1
-0
modules/codec/omxil/mediacodec_ndk.c
modules/codec/omxil/mediacodec_ndk.c
+545
-0
No files found.
modules/codec/Makefile.am
View file @
286fa11d
...
@@ -398,7 +398,7 @@ libiomx_plugin_la_LIBADD = $(libomxil_plugin_la_LIBADD)
...
@@ -398,7 +398,7 @@ libiomx_plugin_la_LIBADD = $(libomxil_plugin_la_LIBADD)
libmediacodec_plugin_la_CPPFLAGS
=
$(AM_CPPFLAGS)
-I
$(srcdir)
/codec/omxil
libmediacodec_plugin_la_CPPFLAGS
=
$(AM_CPPFLAGS)
-I
$(srcdir)
/codec/omxil
libmediacodec_plugin_la_SOURCES
=
codec/omxil/mediacodec.c codec/omxil/mediacodec.h
\
libmediacodec_plugin_la_SOURCES
=
codec/omxil/mediacodec.c codec/omxil/mediacodec.h
\
codec/omxil/mediacodec_jni.c codec/omxil/utils.c
\
codec/omxil/mediacodec_jni.c codec/omxil/
mediacodec_ndk.c codec/omxil/
utils.c
\
video_chroma/copy.c codec/omxil/android_opaque.c codec/omxil/android_opaque.h
\
video_chroma/copy.c codec/omxil/android_opaque.c codec/omxil/android_opaque.h
\
packetizer/h264_nal.c packetizer/h264_nal.h
packetizer/h264_nal.c packetizer/h264_nal.h
packetizer/hevc_nal.c
packetizer/hevc_nal.h
packetizer/hevc_nal.c
packetizer/hevc_nal.h
...
...
modules/codec/omxil/mediacodec.c
View file @
286fa11d
...
@@ -173,6 +173,7 @@ struct decoder_sys_t
...
@@ -173,6 +173,7 @@ struct decoder_sys_t
* Local prototypes
* Local prototypes
*****************************************************************************/
*****************************************************************************/
static
int
OpenDecoderJni
(
vlc_object_t
*
);
static
int
OpenDecoderJni
(
vlc_object_t
*
);
static
int
OpenDecoderNdk
(
vlc_object_t
*
);
static
void
CloseDecoder
(
vlc_object_t
*
);
static
void
CloseDecoder
(
vlc_object_t
*
);
static
picture_t
*
DecodeVideo
(
decoder_t
*
,
block_t
**
);
static
picture_t
*
DecodeVideo
(
decoder_t
*
,
block_t
**
);
...
@@ -197,8 +198,12 @@ vlc_module_begin ()
...
@@ -197,8 +198,12 @@ vlc_module_begin ()
set_capability
(
"decoder"
,
0
)
/* Only enabled via commandline arguments */
set_capability
(
"decoder"
,
0
)
/* Only enabled via commandline arguments */
add_bool
(
CFG_PREFIX
"dr"
,
true
,
add_bool
(
CFG_PREFIX
"dr"
,
true
,
DIRECTRENDERING_TEXT
,
DIRECTRENDERING_LONGTEXT
,
true
)
DIRECTRENDERING_TEXT
,
DIRECTRENDERING_LONGTEXT
,
true
)
set_callbacks
(
OpenDecoderJni
,
CloseDecoder
)
set_callbacks
(
OpenDecoderNdk
,
CloseDecoder
)
add_shortcut
(
"mediacodec_jni"
)
add_shortcut
(
"mediacodec_ndk"
)
add_submodule
()
set_capability
(
"decoder"
,
0
)
set_callbacks
(
OpenDecoderJni
,
CloseDecoder
)
add_shortcut
(
"mediacodec_jni"
)
vlc_module_end
()
vlc_module_end
()
...
@@ -542,6 +547,11 @@ static int OpenDecoder(vlc_object_t *p_this, pf_MediaCodecApi_init pf_init)
...
@@ -542,6 +547,11 @@ static int OpenDecoder(vlc_object_t *p_this, pf_MediaCodecApi_init pf_init)
return
StartMediaCodec
(
p_dec
);
return
StartMediaCodec
(
p_dec
);
}
}
static
int
OpenDecoderNdk
(
vlc_object_t
*
p_this
)
{
return
OpenDecoder
(
p_this
,
MediaCodecNdk_Init
);
}
static
int
OpenDecoderJni
(
vlc_object_t
*
p_this
)
static
int
OpenDecoderJni
(
vlc_object_t
*
p_this
)
{
{
return
OpenDecoder
(
p_this
,
MediaCodecJni_Init
);
return
OpenDecoder
(
p_this
,
MediaCodecJni_Init
);
...
...
modules/codec/omxil/mediacodec.h
View file @
286fa11d
...
@@ -30,6 +30,7 @@ typedef struct mc_api_out mc_api_out;
...
@@ -30,6 +30,7 @@ typedef struct mc_api_out mc_api_out;
typedef
int
(
*
pf_MediaCodecApi_init
)(
mc_api
*
);
typedef
int
(
*
pf_MediaCodecApi_init
)(
mc_api
*
);
int
MediaCodecJni_Init
(
mc_api
*
);
int
MediaCodecJni_Init
(
mc_api
*
);
int
MediaCodecNdk_Init
(
mc_api
*
);
struct
mc_api_out
struct
mc_api_out
{
{
...
...
modules/codec/omxil/mediacodec_ndk.c
0 → 100644
View file @
286fa11d
/*****************************************************************************
* mediacodec_ndk.c: mc_api implementation using NDK
*****************************************************************************
* Copyright © 2015 VLC authors and VideoLAN, VideoLabs
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser 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.
*****************************************************************************/
/*****************************************************************************
* Preamble
*****************************************************************************/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <jni.h>
#include <dlfcn.h>
#include <stdint.h>
#include <assert.h>
#include <vlc_common.h>
#include <OMX_Core.h>
#include <OMX_Component.h>
#include "omxil_utils.h"
#include "mediacodec.h"
#include "../../video_output/android/utils.h"
#define THREAD_NAME "mediacodec_ndk"
extern
JNIEnv
*
jni_get_env
(
const
char
*
name
);
/*****************************************************************************
* NdkMediaError.h
*****************************************************************************/
typedef
enum
{
AMEDIA_OK
=
0
,
AMEDIA_ERROR_BASE
=
-
10000
,
AMEDIA_ERROR_UNKNOWN
=
AMEDIA_ERROR_BASE
,
AMEDIA_ERROR_MALFORMED
=
AMEDIA_ERROR_BASE
-
1
,
AMEDIA_ERROR_UNSUPPORTED
=
AMEDIA_ERROR_BASE
-
2
,
AMEDIA_ERROR_INVALID_OBJECT
=
AMEDIA_ERROR_BASE
-
3
,
AMEDIA_ERROR_INVALID_PARAMETER
=
AMEDIA_ERROR_BASE
-
4
,
AMEDIA_DRM_ERROR_BASE
=
-
20000
,
AMEDIA_DRM_NOT_PROVISIONED
=
AMEDIA_DRM_ERROR_BASE
-
1
,
AMEDIA_DRM_RESOURCE_BUSY
=
AMEDIA_DRM_ERROR_BASE
-
2
,
AMEDIA_DRM_DEVICE_REVOKED
=
AMEDIA_DRM_ERROR_BASE
-
3
,
AMEDIA_DRM_SHORT_BUFFER
=
AMEDIA_DRM_ERROR_BASE
-
4
,
AMEDIA_DRM_SESSION_NOT_OPENED
=
AMEDIA_DRM_ERROR_BASE
-
5
,
AMEDIA_DRM_TAMPER_DETECTED
=
AMEDIA_DRM_ERROR_BASE
-
6
,
AMEDIA_DRM_VERIFY_FAILED
=
AMEDIA_DRM_ERROR_BASE
-
7
,
AMEDIA_DRM_NEED_KEY
=
AMEDIA_DRM_ERROR_BASE
-
8
,
AMEDIA_DRM_LICENSE_EXPIRED
=
AMEDIA_DRM_ERROR_BASE
-
9
,
}
media_status_t
;
/*****************************************************************************
* NdkMediaCodec.h
*****************************************************************************/
struct
AMediaCodec
;
typedef
struct
AMediaCodec
AMediaCodec
;
struct
AMediaCodecBufferInfo
{
int32_t
offset
;
int32_t
size
;
int64_t
presentationTimeUs
;
uint32_t
flags
;
};
typedef
struct
AMediaCodecBufferInfo
AMediaCodecBufferInfo
;
enum
{
AMEDIACODEC_BUFFER_FLAG_END_OF_STREAM
=
4
,
AMEDIACODEC_CONFIGURE_FLAG_ENCODE
=
1
,
AMEDIACODEC_INFO_OUTPUT_BUFFERS_CHANGED
=
-
3
,
AMEDIACODEC_INFO_OUTPUT_FORMAT_CHANGED
=
-
2
,
AMEDIACODEC_INFO_TRY_AGAIN_LATER
=
-
1
};
struct
AMediaFormat
;
typedef
struct
AMediaFormat
AMediaFormat
;
struct
AMediaCrypto
;
typedef
struct
AMediaCrypto
AMediaCrypto
;
/*****************************************************************************
* Ndk symbols
*****************************************************************************/
typedef
AMediaCodec
*
(
*
pf_AMediaCodec_createDecoderByType
)(
const
char
*
mime_type
);
typedef
media_status_t
(
*
pf_AMediaCodec_configure
)(
AMediaCodec
*
,
const
AMediaFormat
*
format
,
ANativeWindow
*
surface
,
AMediaCrypto
*
crypto
,
uint32_t
flags
);
typedef
media_status_t
(
*
pf_AMediaCodec_start
)(
AMediaCodec
*
);
typedef
media_status_t
(
*
pf_AMediaCodec_stop
)(
AMediaCodec
*
);
typedef
media_status_t
(
*
pf_AMediaCodec_flush
)(
AMediaCodec
*
);
typedef
media_status_t
(
*
pf_AMediaCodec_delete
)(
AMediaCodec
*
);
typedef
AMediaFormat
*
(
*
pf_AMediaCodec_getOutputFormat
)(
AMediaCodec
*
);
typedef
ssize_t
(
*
pf_AMediaCodec_dequeueInputBuffer
)(
AMediaCodec
*
,
int64_t
timeoutUs
);
typedef
uint8_t
*
(
*
pf_AMediaCodec_getInputBuffer
)(
AMediaCodec
*
,
size_t
idx
,
size_t
*
out_size
);
typedef
media_status_t
(
*
pf_AMediaCodec_queueInputBuffer
)(
AMediaCodec
*
,
size_t
idx
,
off_t
offset
,
size_t
size
,
uint64_t
time
,
uint32_t
flags
);
typedef
ssize_t
(
*
pf_AMediaCodec_dequeueOutputBuffer
)(
AMediaCodec
*
,
AMediaCodecBufferInfo
*
info
,
int64_t
timeoutUs
);
typedef
uint8_t
*
(
*
pf_AMediaCodec_getOutputBuffer
)(
AMediaCodec
*
,
size_t
idx
,
size_t
*
out_size
);
typedef
media_status_t
(
*
pf_AMediaCodec_releaseOutputBuffer
)(
AMediaCodec
*
,
size_t
idx
,
bool
render
);
typedef
AMediaFormat
*
(
*
pf_AMediaFormat_new
)();
typedef
media_status_t
(
*
pf_AMediaFormat_delete
)(
AMediaFormat
*
);
typedef
void
(
*
pf_AMediaFormat_setString
)(
AMediaFormat
*
,
const
char
*
name
,
const
char
*
value
);
typedef
void
(
*
pf_AMediaFormat_setInt32
)(
AMediaFormat
*
,
const
char
*
name
,
int32_t
value
);
typedef
bool
(
*
pf_AMediaFormat_getInt32
)(
AMediaFormat
*
,
const
char
*
name
,
int32_t
*
out
);
struct
syms
{
struct
{
pf_AMediaCodec_createDecoderByType
createDecoderByType
;
pf_AMediaCodec_configure
configure
;
pf_AMediaCodec_start
start
;
pf_AMediaCodec_stop
stop
;
pf_AMediaCodec_flush
flush
;
pf_AMediaCodec_delete
delete
;
pf_AMediaCodec_getOutputFormat
getOutputFormat
;
pf_AMediaCodec_dequeueInputBuffer
dequeueInputBuffer
;
pf_AMediaCodec_getInputBuffer
getInputBuffer
;
pf_AMediaCodec_queueInputBuffer
queueInputBuffer
;
pf_AMediaCodec_dequeueOutputBuffer
dequeueOutputBuffer
;
pf_AMediaCodec_getOutputBuffer
getOutputBuffer
;
pf_AMediaCodec_releaseOutputBuffer
releaseOutputBuffer
;
}
AMediaCodec
;
struct
{
pf_AMediaFormat_new
new
;
pf_AMediaFormat_delete
delete
;
pf_AMediaFormat_setString
setString
;
pf_AMediaFormat_setInt32
setInt32
;
pf_AMediaFormat_getInt32
getInt32
;
}
AMediaFormat
;
};
static
struct
syms
syms
;
static
native_window_api_t
anw_syms
;
struct
members
{
const
char
*
name
;
int
offset
;
bool
critical
;
};
static
struct
members
members
[]
=
{
#define OFF(x) offsetof(struct syms, AMediaCodec.x)
{
"AMediaCodec_createDecoderByType"
,
OFF
(
createDecoderByType
),
true
},
{
"AMediaCodec_configure"
,
OFF
(
configure
),
true
},
{
"AMediaCodec_start"
,
OFF
(
start
),
true
},
{
"AMediaCodec_stop"
,
OFF
(
stop
),
true
},
{
"AMediaCodec_flush"
,
OFF
(
flush
),
true
},
{
"AMediaCodec_delete"
,
OFF
(
delete
),
true
},
{
"AMediaCodec_getOutputFormat"
,
OFF
(
getOutputFormat
),
true
},
{
"AMediaCodec_dequeueInputBuffer"
,
OFF
(
dequeueInputBuffer
),
true
},
{
"AMediaCodec_getInputBuffer"
,
OFF
(
getInputBuffer
),
true
},
{
"AMediaCodec_queueInputBuffer"
,
OFF
(
queueInputBuffer
),
true
},
{
"AMediaCodec_dequeueOutputBuffer"
,
OFF
(
dequeueOutputBuffer
),
true
},
{
"AMediaCodec_getOutputBuffer"
,
OFF
(
getOutputBuffer
),
true
},
{
"AMediaCodec_releaseOutputBuffer"
,
OFF
(
releaseOutputBuffer
),
true
},
#undef OFF
#define OFF(x) offsetof(struct syms, AMediaFormat.x)
{
"AMediaFormat_new"
,
OFF
(
new
),
true
},
{
"AMediaFormat_delete"
,
OFF
(
delete
),
true
},
{
"AMediaFormat_setString"
,
OFF
(
setString
),
true
},
{
"AMediaFormat_setInt32"
,
OFF
(
setInt32
),
true
},
{
"AMediaFormat_getInt32"
,
OFF
(
getInt32
),
true
},
#undef OFF
{
NULL
,
0
,
false
}
};
#undef OFF
/* Initialize all symbols.
* Done only one time during the first initialisation */
static
bool
InitSymbols
(
mc_api
*
api
)
{
static
vlc_mutex_t
lock
=
VLC_STATIC_MUTEX
;
static
int
i_init_state
=
-
1
;
bool
ret
;
vlc_mutex_lock
(
&
lock
);
if
(
i_init_state
!=
-
1
)
goto
end
;
i_init_state
=
0
;
void
*
ndk_handle
=
dlopen
(
"libmediandk.so"
,
RTLD_NOW
);
if
(
!
ndk_handle
)
goto
end
;
for
(
int
i
=
0
;
members
[
i
].
name
;
i
++
)
{
void
*
sym
=
dlsym
(
ndk_handle
,
members
[
i
].
name
);
if
(
!
sym
&&
members
[
i
].
critical
)
{
dlclose
(
ndk_handle
);
goto
end
;
}
*
(
void
**
)((
uint8_t
*
)
&
syms
+
members
[
i
].
offset
)
=
sym
;
}
void
*
anw_handle
=
LoadNativeWindowAPI
(
&
anw_syms
);
if
(
!
anw_handle
)
{
dlclose
(
ndk_handle
);
goto
end
;
}
i_init_state
=
1
;
end:
ret
=
i_init_state
==
1
;
if
(
!
ret
)
msg_Err
(
api
->
p_obj
,
"MediaCodec NDK init failed"
);
vlc_mutex_unlock
(
&
lock
);
return
ret
;
}
/****************************************************************************
* Local prototypes
****************************************************************************/
struct
mc_api_sys
{
AMediaCodec
*
p_codec
;
AMediaFormat
*
p_format
;
ANativeWindow
*
p_anw
;
};
/*****************************************************************************
* Stop
*****************************************************************************/
static
int
Stop
(
mc_api
*
api
)
{
mc_api_sys
*
p_sys
=
api
->
p_sys
;
api
->
b_direct_rendering
=
false
;
api
->
b_support_interlaced
=
false
;
api
->
psz_name
=
NULL
;
if
(
p_sys
->
p_codec
)
{
if
(
api
->
b_started
)
{
syms
.
AMediaCodec
.
stop
(
p_sys
->
p_codec
);
api
->
b_started
=
false
;
}
syms
.
AMediaCodec
.
delete
(
p_sys
->
p_codec
);
p_sys
->
p_codec
=
NULL
;
}
if
(
p_sys
->
p_format
)
{
syms
.
AMediaFormat
.
delete
(
p_sys
->
p_format
);
p_sys
->
p_format
=
NULL
;
}
if
(
p_sys
->
p_anw
)
{
anw_syms
.
winRelease
(
p_sys
->
p_anw
);
p_sys
->
p_anw
=
NULL
;
}
msg_Dbg
(
api
->
p_obj
,
"MediaCodec via NDK closed"
);
return
VLC_SUCCESS
;
}
/*****************************************************************************
* Start
*****************************************************************************/
static
int
Start
(
mc_api
*
api
,
jobject
jsurface
,
const
char
*
psz_mime
,
int
i_width
,
int
i_height
,
size_t
h264_profile
,
int
i_angle
)
{
mc_api_sys
*
p_sys
=
api
->
p_sys
;
int
i_ret
=
VLC_EGENERIC
;
(
void
)
h264_profile
;
p_sys
->
p_codec
=
syms
.
AMediaCodec
.
createDecoderByType
(
psz_mime
);
if
(
!
p_sys
->
p_codec
)
{
msg_Err
(
api
->
p_obj
,
"AMediaCodec.createDecoderByType for %s failed"
,
psz_mime
);
goto
error
;
}
p_sys
->
p_format
=
syms
.
AMediaFormat
.
new
();
if
(
!
p_sys
->
p_format
)
{
msg_Err
(
api
->
p_obj
,
"AMediaFormat.new failed"
);
goto
error
;
}
syms
.
AMediaFormat
.
setString
(
p_sys
->
p_format
,
"mime"
,
psz_mime
);
syms
.
AMediaFormat
.
setInt32
(
p_sys
->
p_format
,
"width"
,
i_width
);
syms
.
AMediaFormat
.
setInt32
(
p_sys
->
p_format
,
"height"
,
i_height
);
syms
.
AMediaFormat
.
setInt32
(
p_sys
->
p_format
,
"rotation-degrees"
,
i_angle
);
if
(
jsurface
)
{
JNIEnv
*
env
;
if
(
!
(
env
=
jni_get_env
(
THREAD_NAME
)))
goto
error
;
p_sys
->
p_anw
=
anw_syms
.
winFromSurface
(
env
,
jsurface
);
}
if
(
syms
.
AMediaCodec
.
configure
(
p_sys
->
p_codec
,
p_sys
->
p_format
,
p_sys
->
p_anw
,
NULL
,
0
)
!=
AMEDIA_OK
)
{
msg_Err
(
api
->
p_obj
,
"AMediaCodec.configure failed"
);
goto
error
;
}
if
(
syms
.
AMediaCodec
.
start
(
p_sys
->
p_codec
)
!=
AMEDIA_OK
)
{
msg_Err
(
api
->
p_obj
,
"AMediaCodec.start failed"
);
goto
error
;
}
api
->
b_started
=
true
;
api
->
b_direct_rendering
=
!!
p_sys
->
p_anw
;
api
->
b_support_interlaced
=
true
;
api
->
psz_name
=
""
;
// TODO
i_ret
=
VLC_SUCCESS
;
msg_Dbg
(
api
->
p_obj
,
"MediaCodec via NDK opened"
);
error:
if
(
i_ret
!=
VLC_SUCCESS
)
Stop
(
api
);
return
i_ret
;
}
/*****************************************************************************
* Flush
*****************************************************************************/
static
int
Flush
(
mc_api
*
api
)
{
mc_api_sys
*
p_sys
=
api
->
p_sys
;
if
(
syms
.
AMediaCodec
.
flush
(
p_sys
->
p_codec
)
==
AMEDIA_OK
)
return
VLC_SUCCESS
;
else
return
VLC_EGENERIC
;
}
/*****************************************************************************
* PutInput
*****************************************************************************/
static
int
PutInput
(
mc_api
*
api
,
const
void
*
p_buf
,
size_t
i_size
,
mtime_t
i_ts
,
bool
b_config
,
mtime_t
i_timeout
)
{
mc_api_sys
*
p_sys
=
api
->
p_sys
;
ssize_t
i_index
;
uint8_t
*
p_mc_buf
;
size_t
i_mc_size
;
(
void
)
b_config
;
i_index
=
syms
.
AMediaCodec
.
dequeueInputBuffer
(
p_sys
->
p_codec
,
i_timeout
);
if
(
i_index
<
0
)
{
if
(
i_index
==
AMEDIACODEC_INFO_TRY_AGAIN_LATER
)
return
0
;
else
{
msg_Err
(
api
->
p_obj
,
"AMediaCodec.dequeueInputBuffer failed"
);
return
VLC_EGENERIC
;
}
}
p_mc_buf
=
syms
.
AMediaCodec
.
getInputBuffer
(
p_sys
->
p_codec
,
i_index
,
&
i_mc_size
);
if
(
!
p_mc_buf
)
return
VLC_EGENERIC
;
if
(
i_mc_size
>
i_size
)
i_mc_size
=
i_size
;
memcpy
(
p_mc_buf
,
p_buf
,
i_mc_size
);
if
(
syms
.
AMediaCodec
.
queueInputBuffer
(
p_sys
->
p_codec
,
i_index
,
0
,
i_mc_size
,
i_ts
,
0
)
==
AMEDIA_OK
)
return
1
;
else
{
msg_Err
(
api
->
p_obj
,
"AMediaCodec.queueInputBuffer failed"
);
return
VLC_EGENERIC
;
}
}
static
int32_t
GetFormatInteger
(
AMediaFormat
*
p_format
,
const
char
*
psz_name
)
{
int32_t
i_out
=
0
;
syms
.
AMediaFormat
.
getInt32
(
p_format
,
psz_name
,
&
i_out
);
return
i_out
;
}
/*****************************************************************************
* GetOutput
*****************************************************************************/
static
int
GetOutput
(
mc_api
*
api
,
mc_api_out
*
p_out
,
mtime_t
i_timeout
)
{
mc_api_sys
*
p_sys
=
api
->
p_sys
;
AMediaCodecBufferInfo
info
;
ssize_t
i_index
;
i_index
=
syms
.
AMediaCodec
.
dequeueOutputBuffer
(
p_sys
->
p_codec
,
&
info
,
i_timeout
);
if
(
i_index
>=
0
)
{
p_out
->
type
=
MC_OUT_TYPE_BUF
;
p_out
->
u
.
buf
.
i_index
=
i_index
;
p_out
->
u
.
buf
.
i_ts
=
info
.
presentationTimeUs
;
if
(
api
->
b_direct_rendering
)
{
p_out
->
u
.
buf
.
p_ptr
=
NULL
;
p_out
->
u
.
buf
.
i_size
=
0
;
}
else
{
size_t
i_mc_size
;
uint8_t
*
p_mc_buf
=
syms
.
AMediaCodec
.
getOutputBuffer
(
p_sys
->
p_codec
,
i_index
,
&
i_mc_size
);
if
(
!
p_mc_buf
)
{
msg_Err
(
api
->
p_obj
,
"AMediaCodec.getOutputBuffer failed"
);
return
VLC_EGENERIC
;
}
p_out
->
u
.
buf
.
p_ptr
=
p_mc_buf
+
info
.
offset
;
p_out
->
u
.
buf
.
i_size
=
i_mc_size
;
}
return
1
;
}
else
if
(
i_index
==
AMEDIACODEC_INFO_OUTPUT_FORMAT_CHANGED
)
{
AMediaFormat
*
format
=
syms
.
AMediaCodec
.
getOutputFormat
(
p_sys
->
p_codec
);
p_out
->
type
=
MC_OUT_TYPE_CONF
;
p_out
->
u
.
conf
.
width
=
GetFormatInteger
(
format
,
"width"
);
p_out
->
u
.
conf
.
height
=
GetFormatInteger
(
format
,
"height"
);
p_out
->
u
.
conf
.
stride
=
GetFormatInteger
(
format
,
"stride"
);
p_out
->
u
.
conf
.
slice_height
=
GetFormatInteger
(
format
,
"slice-height"
);
p_out
->
u
.
conf
.
pixel_format
=
GetFormatInteger
(
format
,
"color-format"
);
p_out
->
u
.
conf
.
crop_left
=
GetFormatInteger
(
format
,
"crop-left"
);
p_out
->
u
.
conf
.
crop_top
=
GetFormatInteger
(
format
,
"crop-top"
);
p_out
->
u
.
conf
.
crop_right
=
GetFormatInteger
(
format
,
"crop-right"
);
p_out
->
u
.
conf
.
crop_bottom
=
GetFormatInteger
(
format
,
"crop-bottom"
);
return
1
;
}
else
if
(
i_index
==
AMEDIACODEC_INFO_OUTPUT_BUFFERS_CHANGED
||
i_index
==
AMEDIACODEC_INFO_TRY_AGAIN_LATER
)
{
return
0
;
}
else
{
msg_Err
(
api
->
p_obj
,
"AMediaCodec.dequeueOutputBuffer failed"
);
return
VLC_EGENERIC
;
}
}
/*****************************************************************************
* ReleaseOutput
*****************************************************************************/
static
int
ReleaseOutput
(
mc_api
*
api
,
int
i_index
,
bool
b_render
)
{
mc_api_sys
*
p_sys
=
api
->
p_sys
;
if
(
syms
.
AMediaCodec
.
releaseOutputBuffer
(
p_sys
->
p_codec
,
i_index
,
b_render
)
==
AMEDIA_OK
)
return
VLC_SUCCESS
;
else
return
VLC_EGENERIC
;
}
/*****************************************************************************
* Clean
*****************************************************************************/
static
void
Clean
(
mc_api
*
api
)
{
free
(
api
->
p_sys
);
}
/*****************************************************************************
* MediaCodecNdk_Init
*****************************************************************************/
int
MediaCodecNdk_Init
(
mc_api
*
api
)
{
if
(
!
InitSymbols
(
api
))
return
VLC_EGENERIC
;
api
->
p_sys
=
calloc
(
1
,
sizeof
(
mc_api_sys
));
if
(
!
api
->
p_sys
)
return
VLC_EGENERIC
;
api
->
clean
=
Clean
;
api
->
start
=
Start
;
api
->
stop
=
Stop
;
api
->
flush
=
Flush
;
api
->
put_in
=
PutInput
;
api
->
get_out
=
GetOutput
;
api
->
release_out
=
ReleaseOutput
;
return
VLC_SUCCESS
;
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment