Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
F
ffmpeg
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Stefan Westerfeld
ffmpeg
Commits
140da8e8
Commit
140da8e8
authored
Sep 05, 2016
by
Matthieu Bouron
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
lavc: add hevc mediacodec decoder
parent
b82c1a37
Changes
10
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
373 additions
and
34 deletions
+373
-34
Changelog
Changelog
+1
-0
configure
configure
+3
-0
Makefile
libavcodec/Makefile
+2
-1
allcodecs.c
libavcodec/allcodecs.c
+2
-0
hevc_parse.c
libavcodec/hevc_parse.c
+134
-0
hevc_parse.h
libavcodec/hevc_parse.h
+33
-0
mediacodec_wrapper.c
libavcodec/mediacodec_wrapper.c
+20
-3
mediacodecdec.c
libavcodec/mediacodecdec.c
+7
-0
mediacodecdec_h2645.c
libavcodec/mediacodecdec_h2645.c
+169
-28
version.h
libavcodec/version.h
+2
-2
No files found.
Changelog
View file @
140da8e8
...
...
@@ -28,6 +28,7 @@ version <next>:
- gblur filter
- avgblur filter
- sobel and prewitt filter
- MediaCodec HEVC decoding
version 3.1:
...
...
configure
View file @
140da8e8
...
...
@@ -2585,6 +2585,9 @@ h264_videotoolbox_hwaccel_select="h264_decoder"
hevc_cuvid_hwaccel_deps
=
"cuda cuvid CUVIDHEVCPICPARAMS"
hevc_d3d11va_hwaccel_deps
=
"d3d11va DXVA_PicParams_HEVC"
hevc_d3d11va_hwaccel_select
=
"hevc_decoder"
hevc_mediacodec_decoder_deps
=
"mediacodec"
hevc_mediacodec_hwaccel_deps
=
"mediacodec"
hevc_mediacodec_decoder_select
=
"hevc_mp4toannexb_bsf hevc_parser"
hevc_dxva2_hwaccel_deps
=
"dxva2 DXVA_PicParams_HEVC"
hevc_dxva2_hwaccel_select
=
"hevc_decoder"
hevc_qsv_hwaccel_deps
=
"libmfx"
...
...
libavcodec/Makefile
View file @
140da8e8
...
...
@@ -316,7 +316,7 @@ OBJS-$(CONFIG_H264_DECODER) += h264dec.o h264_cabac.o h264_cavlc.o \
h264_slice.o
h264data.o
h264_parse.o
\
h2645_parse.o
OBJS-$(CONFIG_H264_CUVID_DECODER)
+=
cuvid.o
OBJS-$(CONFIG_H264_MEDIACODEC_DECODER)
+=
mediacodecdec_h264.o
OBJS-$(CONFIG_H264_MEDIACODEC_DECODER)
+=
mediacodecdec_h264
5
.o
OBJS-$(CONFIG_H264_MMAL_DECODER)
+=
mmaldec.o
OBJS-$(CONFIG_H264_NVENC_ENCODER)
+=
nvenc_h264.o
OBJS-$(CONFIG_NVENC_ENCODER)
+=
nvenc_h264.o
...
...
@@ -333,6 +333,7 @@ OBJS-$(CONFIG_HEVC_DECODER) += hevc.o hevc_mvs.o hevc_ps.o hevc_sei.o
hevc_cabac.o
hevc_refs.o
hevcpred.o
\
hevcdsp.o
hevc_filter.o
h2645_parse.o
hevc_data.o
OBJS-$(CONFIG_HEVC_CUVID_DECODER)
+=
cuvid.o
OBJS-$(CONFIG_HEVC_MEDIACODEC_DECODER)
+=
mediacodecdec_h2645.o
hevc_parse.o
OBJS-$(CONFIG_HEVC_NVENC_ENCODER)
+=
nvenc_hevc.o
OBJS-$(CONFIG_NVENC_HEVC_ENCODER)
+=
nvenc_hevc.o
OBJS-$(CONFIG_HEVC_QSV_DECODER)
+=
qsvdec_h2645.o
...
...
libavcodec/allcodecs.c
View file @
140da8e8
...
...
@@ -84,6 +84,7 @@ void avcodec_register_all(void)
REGISTER_HWACCEL
(
HEVC_CUVID
,
hevc_cuvid
);
REGISTER_HWACCEL
(
HEVC_D3D11VA
,
hevc_d3d11va
);
REGISTER_HWACCEL
(
HEVC_DXVA2
,
hevc_dxva2
);
REGISTER_HWACCEL
(
HEVC_MEDIACODEC
,
hevc_mediacodec
);
REGISTER_HWACCEL
(
HEVC_QSV
,
hevc_qsv
);
REGISTER_HWACCEL
(
HEVC_VAAPI
,
hevc_vaapi
);
REGISTER_HWACCEL
(
HEVC_VDPAU
,
hevc_vdpau
);
...
...
@@ -644,6 +645,7 @@ void avcodec_register_all(void)
REGISTER_ENCODER
(
NVENC_HEVC
,
nvenc_hevc
);
#endif
REGISTER_DECODER
(
HEVC_CUVID
,
hevc_cuvid
);
REGISTER_DECODER
(
HEVC_MEDIACODEC
,
hevc_mediacodec
);
REGISTER_ENCODER
(
HEVC_NVENC
,
hevc_nvenc
);
REGISTER_ENCODER
(
HEVC_QSV
,
hevc_qsv
);
REGISTER_ENCODER
(
HEVC_VAAPI
,
hevc_vaapi
);
...
...
libavcodec/hevc_parse.c
0 → 100644
View file @
140da8e8
/*
* This file is part of FFmpeg.
*
* FFmpeg 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.
*
* FFmpeg 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 FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "bytestream.h"
#include "h2645_parse.h"
#include "hevc.h"
#include "hevc_parse.h"
static
int
hevc_decode_nal_units
(
const
uint8_t
*
buf
,
int
buf_size
,
HEVCParamSets
*
ps
,
int
is_nalff
,
int
nal_length_size
,
void
*
logctx
)
{
int
i
;
int
ret
=
0
;
H2645Packet
pkt
=
{
0
};
ret
=
ff_h2645_packet_split
(
&
pkt
,
buf
,
buf_size
,
logctx
,
is_nalff
,
nal_length_size
,
AV_CODEC_ID_HEVC
,
1
);
if
(
ret
<
0
)
{
goto
done
;
}
for
(
i
=
0
;
i
<
pkt
.
nb_nals
;
i
++
)
{
H2645NAL
*
nal
=
&
pkt
.
nals
[
i
];
/* ignore everything except parameter sets and VCL NALUs */
switch
(
nal
->
type
)
{
case
NAL_VPS
:
ff_hevc_decode_nal_vps
(
&
nal
->
gb
,
logctx
,
ps
);
break
;
case
NAL_SPS
:
ff_hevc_decode_nal_sps
(
&
nal
->
gb
,
logctx
,
ps
,
1
);
break
;
case
NAL_PPS
:
ff_hevc_decode_nal_pps
(
&
nal
->
gb
,
logctx
,
ps
);
break
;
case
NAL_TRAIL_R
:
case
NAL_TRAIL_N
:
case
NAL_TSA_N
:
case
NAL_TSA_R
:
case
NAL_STSA_N
:
case
NAL_STSA_R
:
case
NAL_BLA_W_LP
:
case
NAL_BLA_W_RADL
:
case
NAL_BLA_N_LP
:
case
NAL_IDR_W_RADL
:
case
NAL_IDR_N_LP
:
case
NAL_CRA_NUT
:
case
NAL_RADL_N
:
case
NAL_RADL_R
:
case
NAL_RASL_N
:
case
NAL_RASL_R
:
av_log
(
logctx
,
AV_LOG_ERROR
,
"Invalid NAL unit: %d
\n
"
,
nal
->
type
);
ret
=
AVERROR_INVALIDDATA
;
goto
done
;
break
;
}
}
done:
ff_h2645_packet_uninit
(
&
pkt
);
return
ret
;
}
int
ff_hevc_decode_extradata
(
const
uint8_t
*
data
,
int
size
,
HEVCParamSets
*
ps
,
int
*
is_nalff
,
int
*
nal_length_size
,
int
err_recognition
,
void
*
logctx
)
{
int
ret
=
0
;
GetByteContext
gb
;
bytestream2_init
(
&
gb
,
data
,
size
);
if
(
size
>
3
&&
(
data
[
0
]
||
data
[
1
]
||
data
[
2
]
>
1
))
{
/* It seems the extradata is encoded as hvcC format.
* Temporarily, we support configurationVersion==0 until 14496-15 3rd
* is finalized. When finalized, configurationVersion will be 1 and we
* can recognize hvcC by checking if avctx->extradata[0]==1 or not. */
int
i
,
j
,
num_arrays
,
nal_len_size
;
*
is_nalff
=
1
;
bytestream2_skip
(
&
gb
,
21
);
nal_len_size
=
(
bytestream2_get_byte
(
&
gb
)
&
3
)
+
1
;
num_arrays
=
bytestream2_get_byte
(
&
gb
);
/* nal units in the hvcC always have length coded with 2 bytes,
* so put a fake nal_length_size = 2 while parsing them */
*
nal_length_size
=
2
;
/* Decode nal units from hvcC. */
for
(
i
=
0
;
i
<
num_arrays
;
i
++
)
{
int
type
=
bytestream2_get_byte
(
&
gb
)
&
0x3f
;
int
cnt
=
bytestream2_get_be16
(
&
gb
);
for
(
j
=
0
;
j
<
cnt
;
j
++
)
{
// +2 for the nal size field
int
nalsize
=
bytestream2_peek_be16
(
&
gb
)
+
2
;
if
(
bytestream2_get_bytes_left
(
&
gb
)
<
nalsize
)
{
av_log
(
logctx
,
AV_LOG_ERROR
,
"Invalid NAL unit size in extradata.
\n
"
);
return
AVERROR_INVALIDDATA
;
}
ret
=
hevc_decode_nal_units
(
gb
.
buffer
,
nalsize
,
ps
,
*
is_nalff
,
*
nal_length_size
,
logctx
);
if
(
ret
<
0
)
{
av_log
(
logctx
,
AV_LOG_ERROR
,
"Decoding nal unit %d %d from hvcC failed
\n
"
,
type
,
i
);
return
ret
;
}
bytestream2_skip
(
&
gb
,
nalsize
);
}
}
/* Now store right nal length size, that will be used to parse
* all other nals */
*
nal_length_size
=
nal_len_size
;
}
else
{
*
is_nalff
=
0
;
ret
=
hevc_decode_nal_units
(
data
,
size
,
ps
,
*
is_nalff
,
*
nal_length_size
,
logctx
);
if
(
ret
<
0
)
return
ret
;
}
return
ret
;
}
libavcodec/hevc_parse.h
0 → 100644
View file @
140da8e8
/*
* This file is part of FFmpeg.
*
* FFmpeg 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.
*
* FFmpeg 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 FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @file
* H.265 parser code
*/
#ifndef AVCODEC_HEVC_PARSE_H
#define AVCODEC_HEVC_PARSE_H
#include "hevc.h"
int
ff_hevc_decode_extradata
(
const
uint8_t
*
data
,
int
size
,
HEVCParamSets
*
ps
,
int
*
is_nalff
,
int
*
nal_length_size
,
int
err_recognition
,
void
*
logctx
);
#endif
/* AVCODEC_HEVC_PARSE_H */
libavcodec/mediacodec_wrapper.c
View file @
140da8e8
...
...
@@ -62,6 +62,10 @@ struct JNIAMediaCodecListFields {
jfieldID
avc_profile_high422_id
;
jfieldID
avc_profile_high444_id
;
jfieldID
hevc_profile_main_id
;
jfieldID
hevc_profile_main10_id
;
jfieldID
hevc_profile_main10_hdr10_id
;
}
JNIAMediaCodecListFields
;
static
const
struct
FFJniField
jni_amediacodeclist_mapping
[]
=
{
...
...
@@ -94,6 +98,10 @@ static const struct FFJniField jni_amediacodeclist_mapping[] = {
{
"android/media/MediaCodecInfo$CodecProfileLevel"
,
"AVCProfileHigh422"
,
"I"
,
FF_JNI_STATIC_FIELD
,
offsetof
(
struct
JNIAMediaCodecListFields
,
avc_profile_high422_id
),
1
},
{
"android/media/MediaCodecInfo$CodecProfileLevel"
,
"AVCProfileHigh444"
,
"I"
,
FF_JNI_STATIC_FIELD
,
offsetof
(
struct
JNIAMediaCodecListFields
,
avc_profile_high444_id
),
1
},
{
"android/media/MediaCodecInfo$CodecProfileLevel"
,
"HEVCProfileMain"
,
"I"
,
FF_JNI_STATIC_FIELD
,
offsetof
(
struct
JNIAMediaCodecListFields
,
hevc_profile_main_id
),
0
},
{
"android/media/MediaCodecInfo$CodecProfileLevel"
,
"HEVCProfileMain10"
,
"I"
,
FF_JNI_STATIC_FIELD
,
offsetof
(
struct
JNIAMediaCodecListFields
,
hevc_profile_main10_id
),
0
},
{
"android/media/MediaCodecInfo$CodecProfileLevel"
,
"HEVCProfileMain10HDR10"
,
"I"
,
FF_JNI_STATIC_FIELD
,
offsetof
(
struct
JNIAMediaCodecListFields
,
hevc_profile_main10_hdr10_id
),
0
},
{
NULL
}
};
...
...
@@ -303,6 +311,7 @@ int ff_AMediaCodecProfile_getProfileFromAVCodecContext(AVCodecContext *avctx)
JNIEnv
*
env
=
NULL
;
struct
JNIAMediaCodecListFields
jfields
=
{
0
};
jfieldID
field_id
=
0
;
JNI_GET_ENV_OR_RETURN
(
env
,
avctx
,
-
1
);
...
...
@@ -311,8 +320,6 @@ int ff_AMediaCodecProfile_getProfileFromAVCodecContext(AVCodecContext *avctx)
}
if
(
avctx
->
codec_id
==
AV_CODEC_ID_H264
)
{
jfieldID
field_id
=
0
;
switch
(
avctx
->
profile
)
{
case
FF_PROFILE_H264_BASELINE
:
case
FF_PROFILE_H264_CONSTRAINED_BASELINE
:
...
...
@@ -341,6 +348,17 @@ int ff_AMediaCodecProfile_getProfileFromAVCodecContext(AVCodecContext *avctx)
field_id
=
jfields
.
avc_profile_high444_id
;
break
;
}
}
else
if
(
avctx
->
codec_id
==
AV_CODEC_ID_HEVC
)
{
switch
(
avctx
->
profile
)
{
case
FF_PROFILE_HEVC_MAIN
:
case
FF_PROFILE_HEVC_MAIN_STILL_PICTURE
:
field_id
=
jfields
.
hevc_profile_main_id
;
break
;
case
FF_PROFILE_HEVC_MAIN_10
:
field_id
=
jfields
.
hevc_profile_main10_id
;
break
;
}
}
if
(
field_id
)
{
ret
=
(
*
env
)
->
GetStaticIntField
(
env
,
jfields
.
codec_profile_level_class
,
field_id
);
...
...
@@ -349,7 +367,6 @@ int ff_AMediaCodecProfile_getProfileFromAVCodecContext(AVCodecContext *avctx)
goto
done
;
}
}
}
done:
ff_jni_reset_jfields
(
env
,
&
jfields
,
jni_amediacodeclist_mapping
,
0
,
avctx
);
...
...
libavcodec/mediacodecdec.c
View file @
140da8e8
...
...
@@ -758,3 +758,10 @@ AVHWAccel ff_h264_mediacodec_hwaccel = {
.
id
=
AV_CODEC_ID_H264
,
.
pix_fmt
=
AV_PIX_FMT_MEDIACODEC
,
};
AVHWAccel
ff_hevc_mediacodec_hwaccel
=
{
.
name
=
"mediacodec"
,
.
type
=
AVMEDIA_TYPE_VIDEO
,
.
id
=
AV_CODEC_ID_HEVC
,
.
pix_fmt
=
AV_PIX_FMT_MEDIACODEC
,
};
libavcodec/mediacodecdec_h264.c
→
libavcodec/mediacodecdec_h264
5
.c
View file @
140da8e8
/*
* Android MediaCodec H.264
decoder
* Android MediaCodec H.264
/ H.265 decoders
*
* Copyright (c) 2015-2016 Matthieu Bouron <matthieu.bouron stupeflix.com>
*
...
...
@@ -33,12 +33,11 @@
#include "avcodec.h"
#include "h264_parse.h"
#include "hevc_parse.h"
#include "internal.h"
#include "mediacodecdec.h"
#include "mediacodec_wrapper.h"
#define CODEC_MIME "video/avc"
typedef
struct
MediaCodecH264DecContext
{
MediaCodecDecContext
*
ctx
;
...
...
@@ -66,7 +65,7 @@ static av_cold int mediacodec_decode_close(AVCodecContext *avctx)
return
0
;
}
static
int
h264_ps_to_nalu
(
const
uint8_t
*
src
,
int
src_size
,
uint8_t
**
out
,
int
*
out_size
)
static
int
h264
5
_ps_to_nalu
(
const
uint8_t
*
src
,
int
src_size
,
uint8_t
**
out
,
int
*
out_size
)
{
int
i
;
int
ret
=
0
;
...
...
@@ -118,7 +117,8 @@ done:
return
ret
;
}
static
av_cold
int
mediacodec_decode_init
(
AVCodecContext
*
avctx
)
#if CONFIG_H264_MEDIACODEC_DECODER
static
int
h264_set_extradata
(
AVCodecContext
*
avctx
,
FFAMediaFormat
*
format
)
{
int
i
;
int
ret
;
...
...
@@ -129,24 +129,8 @@ static av_cold int mediacodec_decode_init(AVCodecContext *avctx)
int
is_avc
=
0
;
int
nal_length_size
=
0
;
const
AVBitStreamFilter
*
bsf
=
NULL
;
FFAMediaFormat
*
format
=
NULL
;
MediaCodecH264DecContext
*
s
=
avctx
->
priv_data
;
memset
(
&
ps
,
0
,
sizeof
(
ps
));
format
=
ff_AMediaFormat_new
();
if
(
!
format
)
{
av_log
(
avctx
,
AV_LOG_ERROR
,
"Failed to create media format
\n
"
);
ret
=
AVERROR_EXTERNAL
;
goto
done
;
}
ff_AMediaFormat_setString
(
format
,
"mime"
,
CODEC_MIME
);
ff_AMediaFormat_setInt32
(
format
,
"width"
,
avctx
->
width
);
ff_AMediaFormat_setInt32
(
format
,
"height"
,
avctx
->
height
);
ret
=
ff_h264_decode_extradata
(
avctx
->
extradata
,
avctx
->
extradata_size
,
&
ps
,
&
is_avc
,
&
nal_length_size
,
0
,
avctx
);
if
(
ret
<
0
)
{
...
...
@@ -170,13 +154,13 @@ static av_cold int mediacodec_decode_init(AVCodecContext *avctx)
uint8_t
*
data
=
NULL
;
size_t
data_size
=
0
;
if
((
ret
=
h264_ps_to_nalu
(
sps
->
data
,
sps
->
data_size
,
&
data
,
&
data_size
))
<
0
)
{
if
((
ret
=
h264
5
_ps_to_nalu
(
sps
->
data
,
sps
->
data_size
,
&
data
,
&
data_size
))
<
0
)
{
goto
done
;
}
ff_AMediaFormat_setBuffer
(
format
,
"csd-0"
,
(
void
*
)
data
,
data_size
);
av_freep
(
&
data
);
if
((
ret
=
h264_ps_to_nalu
(
pps
->
data
,
pps
->
data_size
,
&
data
,
&
data_size
))
<
0
)
{
if
((
ret
=
h264
5
_ps_to_nalu
(
pps
->
data
,
pps
->
data_size
,
&
data
,
&
data_size
))
<
0
)
{
goto
done
;
}
ff_AMediaFormat_setBuffer
(
format
,
"csd-1"
,
(
void
*
)
data
,
data_size
);
...
...
@@ -184,9 +168,150 @@ static av_cold int mediacodec_decode_init(AVCodecContext *avctx)
}
else
{
av_log
(
avctx
,
AV_LOG_ERROR
,
"Could not extract PPS/SPS from extradata"
);
ret
=
AVERROR_INVALIDDATA
;
}
done:
ff_h264_ps_uninit
(
&
ps
);
return
ret
;
}
#endif
#if CONFIG_HEVC_MEDIACODEC_DECODER
static
int
hevc_set_extradata
(
AVCodecContext
*
avctx
,
FFAMediaFormat
*
format
)
{
int
i
;
int
ret
;
HEVCParamSets
ps
;
const
HEVCVPS
*
vps
=
NULL
;
const
HEVCPPS
*
pps
=
NULL
;
const
HEVCSPS
*
sps
=
NULL
;
int
is_nalff
=
0
;
int
nal_length_size
=
0
;
uint8_t
*
vps_data
=
NULL
;
uint8_t
*
sps_data
=
NULL
;
uint8_t
*
pps_data
=
NULL
;
int
vps_data_size
=
0
;
int
sps_data_size
=
0
;
int
pps_data_size
=
0
;
memset
(
&
ps
,
0
,
sizeof
(
ps
));
ret
=
ff_hevc_decode_extradata
(
avctx
->
extradata
,
avctx
->
extradata_size
,
&
ps
,
&
is_nalff
,
&
nal_length_size
,
0
,
avctx
);
if
(
ret
<
0
)
{
goto
done
;
}
for
(
i
=
0
;
i
<
MAX_VPS_COUNT
;
i
++
)
{
if
(
ps
.
vps_list
[
i
])
{
vps
=
(
const
HEVCVPS
*
)
ps
.
vps_list
[
i
]
->
data
;
break
;
}
}
for
(
i
=
0
;
i
<
MAX_PPS_COUNT
;
i
++
)
{
if
(
ps
.
pps_list
[
i
])
{
pps
=
(
const
HEVCPPS
*
)
ps
.
pps_list
[
i
]
->
data
;
break
;
}
}
if
(
pps
)
{
if
(
ps
.
sps_list
[
pps
->
sps_id
])
{
sps
=
(
const
HEVCSPS
*
)
ps
.
sps_list
[
pps
->
sps_id
]
->
data
;
}
}
if
(
vps
&&
pps
&&
sps
)
{
uint8_t
*
data
;
int
data_size
;
if
((
ret
=
h2645_ps_to_nalu
(
vps
->
data
,
vps
->
data_size
,
&
vps_data
,
&
vps_data_size
))
<
0
||
(
ret
=
h2645_ps_to_nalu
(
sps
->
data
,
sps
->
data_size
,
&
sps_data
,
&
sps_data_size
))
<
0
||
(
ret
=
h2645_ps_to_nalu
(
pps
->
data
,
pps
->
data_size
,
&
pps_data
,
&
pps_data_size
))
<
0
)
{
goto
done
;
}
data_size
=
vps_data_size
+
sps_data_size
+
pps_data_size
;
data
=
av_mallocz
(
data_size
);
if
(
!
data
)
{
ret
=
AVERROR
(
ENOMEM
);
goto
done
;
}
memcpy
(
data
,
vps_data
,
vps_data_size
);
memcpy
(
data
+
vps_data_size
,
sps_data
,
sps_data_size
);
memcpy
(
data
+
vps_data_size
+
sps_data_size
,
pps_data
,
pps_data_size
);
ff_AMediaFormat_setBuffer
(
format
,
"csd-0"
,
data
,
data_size
);
av_freep
(
&
data
);
}
else
{
av_log
(
avctx
,
AV_LOG_ERROR
,
"Could not extract VPS/PPS/SPS from extradata"
);
ret
=
AVERROR_INVALIDDATA
;
}
done:
av_freep
(
&
vps_data
);
av_freep
(
&
sps_data
);
av_freep
(
&
pps_data
);
return
ret
;
}
#endif
static
av_cold
int
mediacodec_decode_init
(
AVCodecContext
*
avctx
)
{
int
ret
;
const
char
*
codec_mime
=
NULL
;
const
char
*
bsf_name
=
NULL
;
const
AVBitStreamFilter
*
bsf
=
NULL
;
FFAMediaFormat
*
format
=
NULL
;
MediaCodecH264DecContext
*
s
=
avctx
->
priv_data
;
format
=
ff_AMediaFormat_new
();
if
(
!
format
)
{
av_log
(
avctx
,
AV_LOG_ERROR
,
"Failed to create media format
\n
"
);
ret
=
AVERROR_EXTERNAL
;
goto
done
;
}
switch
(
avctx
->
codec_id
)
{
#if CONFIG_H264_MEDIACODEC_DECODER
case
AV_CODEC_ID_H264
:
codec_mime
=
"video/avc"
;
bsf_name
=
"h264_mp4toannexb"
;
ret
=
h264_set_extradata
(
avctx
,
format
);
if
(
ret
<
0
)
goto
done
;
break
;
#endif
#if CONFIG_HEVC_MEDIACODEC_DECODER
case
AV_CODEC_ID_HEVC
:
codec_mime
=
"video/hevc"
;
bsf_name
=
"hevc_mp4toannexb"
;
ret
=
hevc_set_extradata
(
avctx
,
format
);
if
(
ret
<
0
)
goto
done
;
break
;
#endif
default:
av_assert0
(
0
);
}
ff_AMediaFormat_setString
(
format
,
"mime"
,
codec_mime
);
ff_AMediaFormat_setInt32
(
format
,
"width"
,
avctx
->
width
);
ff_AMediaFormat_setInt32
(
format
,
"height"
,
avctx
->
height
);
s
->
ctx
=
av_mallocz
(
sizeof
(
*
s
->
ctx
));
if
(
!
s
->
ctx
)
{
av_log
(
avctx
,
AV_LOG_ERROR
,
"Failed to allocate MediaCodecDecContext
\n
"
);
...
...
@@ -194,7 +319,7 @@ static av_cold int mediacodec_decode_init(AVCodecContext *avctx)
goto
done
;
}
if
((
ret
=
ff_mediacodec_dec_init
(
avctx
,
s
->
ctx
,
CODEC_MIME
,
format
))
<
0
)
{
if
((
ret
=
ff_mediacodec_dec_init
(
avctx
,
s
->
ctx
,
codec_mime
,
format
))
<
0
)
{
s
->
ctx
=
NULL
;
goto
done
;
}
...
...
@@ -207,7 +332,7 @@ static av_cold int mediacodec_decode_init(AVCodecContext *avctx)
goto
done
;
}
bsf
=
av_bsf_get_by_name
(
"h264_mp4toannexb"
);
bsf
=
av_bsf_get_by_name
(
bsf_name
);
if
(
!
bsf
)
{
ret
=
AVERROR_BSF_NOT_FOUND
;
goto
done
;
...
...
@@ -233,8 +358,6 @@ done:
mediacodec_decode_close
(
avctx
);
}
ff_h264_ps_uninit
(
&
ps
);
return
ret
;
}
...
...
@@ -323,7 +446,7 @@ static int mediacodec_decode_frame(AVCodecContext *avctx, void *data,
goto
done
;
}
/*
h264_mp4toannexb is used here and does not requires
flushing */
/*
{h264,hevc}_mp4toannexb are used here and do not require
flushing */
av_assert0
(
ret
!=
AVERROR_EOF
);
if
(
ret
<
0
)
{
...
...
@@ -358,6 +481,7 @@ static void mediacodec_decode_flush(AVCodecContext *avctx)
ff_mediacodec_dec_flush
(
avctx
,
s
->
ctx
);
}
#if CONFIG_H264_MEDIACODEC_DECODER
AVCodec
ff_h264_mediacodec_decoder
=
{
.
name
=
"h264_mediacodec"
,
.
long_name
=
NULL_IF_CONFIG_SMALL
(
"H.264 Android MediaCodec decoder"
),
...
...
@@ -371,3 +495,20 @@ AVCodec ff_h264_mediacodec_decoder = {
.
capabilities
=
CODEC_CAP_DELAY
,
.
caps_internal
=
FF_CODEC_CAP_SETS_PKT_DTS
,
};
#endif
#if CONFIG_HEVC_MEDIACODEC_DECODER
AVCodec
ff_hevc_mediacodec_decoder
=
{
.
name
=
"hevc_mediacodec"
,
.
long_name
=
NULL_IF_CONFIG_SMALL
(
"H.265 Android MediaCodec decoder"
),
.
type
=
AVMEDIA_TYPE_VIDEO
,
.
id
=
AV_CODEC_ID_HEVC
,
.
priv_data_size
=
sizeof
(
MediaCodecH264DecContext
),
.
init
=
mediacodec_decode_init
,
.
decode
=
mediacodec_decode_frame
,
.
flush
=
mediacodec_decode_flush
,
.
close
=
mediacodec_decode_close
,
.
capabilities
=
CODEC_CAP_DELAY
,
.
caps_internal
=
FF_CODEC_CAP_SETS_PKT_DTS
,
};
#endif
libavcodec/version.h
View file @
140da8e8
...
...
@@ -28,8 +28,8 @@
#include "libavutil/version.h"
#define LIBAVCODEC_VERSION_MAJOR 57
#define LIBAVCODEC_VERSION_MINOR 5
5
#define LIBAVCODEC_VERSION_MICRO 10
1
#define LIBAVCODEC_VERSION_MINOR 5
6
#define LIBAVCODEC_VERSION_MICRO 10
0
#define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
LIBAVCODEC_VERSION_MINOR, \
...
...
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