Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
TrueDei
FFmpeg
提交
ca2f19b9
F
FFmpeg
项目概览
TrueDei
/
FFmpeg
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
F
FFmpeg
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
ca2f19b9
编写于
3月 21, 2016
作者:
A
Anton Khirnov
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
h264: switch to h2645_parse for NAL parsing
上级
a7829a2a
变更
3
显示空白变更内容
内联
并排
Showing
3 changed file
with
155 addition
and
296 deletion
+155
-296
libavcodec/Makefile
libavcodec/Makefile
+2
-1
libavcodec/h264.c
libavcodec/h264.c
+150
-295
libavcodec/h264.h
libavcodec/h264.h
+3
-0
未找到文件。
libavcodec/Makefile
浏览文件 @
ca2f19b9
...
...
@@ -252,7 +252,8 @@ OBJS-$(CONFIG_H264_DECODER) += h264.o h264_cabac.o h264_cavlc.o \
h264_direct.o h264_loopfilter.o
\
h264_mb.o h264_picture.o h264_ps.o
\
h264_refs.o h264_sei.o
\
h264_slice.o h264data.o h264_parse.o
h264_slice.o h264data.o h264_parse.o
\
h2645_parse.o
OBJS-$(CONFIG_H264_MMAL_DECODER)
+=
mmaldec.o
OBJS-$(CONFIG_H264_NVENC_ENCODER)
+=
nvenc_h264.o
OBJS-$(CONFIG_H264_QSV_DECODER)
+=
qsvdec_h2645.o
...
...
libavcodec/h264.c
浏览文件 @
ca2f19b9
...
...
@@ -38,6 +38,7 @@
#include "error_resilience.h"
#include "avcodec.h"
#include "h264.h"
#include "h2645_parse.h"
#include "h264data.h"
#include "h264chroma.h"
#include "h264_mvpred.h"
...
...
@@ -221,25 +222,6 @@ nsc:
return
dst
;
}
/**
* Identify the exact end of the bitstream
* @return the length of the trailing, or 0 if damaged
*/
static
int
decode_rbsp_trailing
(
H264Context
*
h
,
const
uint8_t
*
src
)
{
int
v
=
*
src
;
int
r
;
ff_tlog
(
h
->
avctx
,
"rbsp trailing %X
\n
"
,
v
);
for
(
r
=
1
;
r
<
9
;
r
++
)
{
if
(
v
&
1
)
return
r
;
v
>>=
1
;
}
return
0
;
}
void
ff_h264_free_tables
(
H264Context
*
h
)
{
int
i
;
...
...
@@ -1143,113 +1125,30 @@ int ff_set_ref_count(H264Context *h, H264SliceContext *sl)
return
0
;
}
static
int
find_start_code
(
const
uint8_t
*
buf
,
int
buf_size
,
int
buf_index
,
int
next_avc
)
{
// start code prefix search
for
(;
buf_index
+
3
<
next_avc
;
buf_index
++
)
// This should always succeed in the first iteration.
if
(
buf
[
buf_index
]
==
0
&&
buf
[
buf_index
+
1
]
==
0
&&
buf
[
buf_index
+
2
]
==
1
)
break
;
if
(
buf_index
+
3
>=
buf_size
)
return
buf_size
;
return
buf_index
+
3
;
}
static
int
get_avc_nalsize
(
H264Context
*
h
,
const
uint8_t
*
buf
,
int
buf_size
,
int
*
buf_index
)
{
int
i
,
nalsize
=
0
;
if
(
*
buf_index
>=
buf_size
-
h
->
nal_length_size
)
{
// the end of the buffer is reached, refill it.
return
AVERROR
(
EAGAIN
);
}
for
(
i
=
0
;
i
<
h
->
nal_length_size
;
i
++
)
nalsize
=
(
nalsize
<<
8
)
|
buf
[(
*
buf_index
)
++
];
if
(
nalsize
<=
0
||
nalsize
>
buf_size
-
*
buf_index
)
{
av_log
(
h
->
avctx
,
AV_LOG_ERROR
,
"AVC: nal size %d
\n
"
,
nalsize
);
return
AVERROR_INVALIDDATA
;
}
return
nalsize
;
}
static
int
get_bit_length
(
H264Context
*
h
,
const
uint8_t
*
buf
,
const
uint8_t
*
ptr
,
int
dst_length
,
int
i
,
int
next_avc
)
{
if
((
h
->
workaround_bugs
&
FF_BUG_AUTODETECT
)
&&
i
+
3
<
next_avc
&&
buf
[
i
]
==
0x00
&&
buf
[
i
+
1
]
==
0x00
&&
buf
[
i
+
2
]
==
0x01
&&
buf
[
i
+
3
]
==
0xE0
)
h
->
workaround_bugs
|=
FF_BUG_TRUNCATED
;
if
(
!
(
h
->
workaround_bugs
&
FF_BUG_TRUNCATED
))
while
(
dst_length
>
0
&&
ptr
[
dst_length
-
1
]
==
0
)
dst_length
--
;
if
(
!
dst_length
)
return
0
;
return
8
*
dst_length
-
decode_rbsp_trailing
(
h
,
ptr
+
dst_length
-
1
);
}
static
int
get_last_needed_nal
(
H264Context
*
h
,
const
uint8_t
*
buf
,
int
buf_size
)
static
int
get_last_needed_nal
(
H264Context
*
h
)
{
int
next_avc
=
h
->
is_avc
?
0
:
buf_size
;
int
nal_index
=
0
;
int
buf_index
=
0
;
int
nals_needed
=
0
;
int
i
;
while
(
1
)
{
for
(
i
=
0
;
i
<
h
->
pkt
.
nb_nals
;
i
++
)
{
H2645NAL
*
nal
=
&
h
->
pkt
.
nals
[
i
];
GetBitContext
gb
;
int
nalsize
=
0
;
int
dst_length
,
bit_length
,
consumed
;
const
uint8_t
*
ptr
;
if
(
buf_index
>=
next_avc
)
{
nalsize
=
get_avc_nalsize
(
h
,
buf
,
buf_size
,
&
buf_index
);
if
(
nalsize
<
0
)
break
;
next_avc
=
buf_index
+
nalsize
;
}
else
{
buf_index
=
find_start_code
(
buf
,
buf_size
,
buf_index
,
next_avc
);
if
(
buf_index
>=
buf_size
)
break
;
}
ptr
=
ff_h264_decode_nal
(
h
,
&
h
->
slice_ctx
[
0
],
buf
+
buf_index
,
&
dst_length
,
&
consumed
,
next_avc
-
buf_index
);
if
(
!
ptr
||
dst_length
<
0
)
return
AVERROR_INVALIDDATA
;
buf_index
+=
consumed
;
bit_length
=
get_bit_length
(
h
,
buf
,
ptr
,
dst_length
,
buf_index
,
next_avc
);
nal_index
++
;
/* packets can sometimes contain multiple PPS/SPS,
* e.g. two PAFF field pictures in one packet, or a demuxer
* which splits NALs strangely if so, when frame threading we
* can't start the next thread until we've read all of them */
switch
(
h
->
nal_unit_
type
)
{
switch
(
nal
->
type
)
{
case
NAL_SPS
:
case
NAL_PPS
:
nals_needed
=
nal_index
;
nals_needed
=
i
;
break
;
case
NAL_DPA
:
case
NAL_IDR_SLICE
:
case
NAL_SLICE
:
init_get_bits
(
&
gb
,
ptr
,
bit_length
);
init_get_bits
(
&
gb
,
nal
->
data
+
1
,
(
nal
->
size
-
1
)
*
8
);
if
(
!
get_ue_golomb
(
&
gb
))
nals_needed
=
nal_index
;
nals_needed
=
i
;
}
}
...
...
@@ -1260,13 +1159,9 @@ static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size,
int
parse_extradata
)
{
AVCodecContext
*
const
avctx
=
h
->
avctx
;
H264SliceContext
*
sl
;
int
buf_index
;
unsigned
context_count
;
int
next_avc
;
unsigned
context_count
=
0
;
int
nals_needed
=
0
;
///< number of NALs that need decoding before the next frame thread starts
int
nal_index
;
int
ret
=
0
;
int
i
,
ret
=
0
;
h
->
max_contexts
=
h
->
slice_context_count
;
if
(
!
(
avctx
->
flags2
&
AV_CODEC_FLAG2_CHUNKS
))
{
...
...
@@ -1276,63 +1171,24 @@ static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size,
ff_h264_reset_sei
(
h
);
}
if
(
avctx
->
active_thread_type
&
FF_THREAD_FRAME
)
nals_needed
=
get_last_needed_nal
(
h
,
buf
,
buf_size
);
{
buf_index
=
0
;
context_count
=
0
;
next_avc
=
h
->
is_avc
?
0
:
buf_size
;
nal_index
=
0
;
for
(;;)
{
int
consumed
;
int
dst_length
;
int
bit_length
;
const
uint8_t
*
ptr
;
int
nalsize
=
0
;
int
err
;
if
(
buf_index
>=
next_avc
)
{
nalsize
=
get_avc_nalsize
(
h
,
buf
,
buf_size
,
&
buf_index
);
if
(
nalsize
<
0
)
break
;
next_avc
=
buf_index
+
nalsize
;
}
else
{
buf_index
=
find_start_code
(
buf
,
buf_size
,
buf_index
,
next_avc
);
if
(
buf_index
>=
buf_size
)
break
;
if
(
buf_index
>=
next_avc
)
continue
;
}
sl
=
&
h
->
slice_ctx
[
context_count
];
ptr
=
ff_h264_decode_nal
(
h
,
sl
,
buf
+
buf_index
,
&
dst_length
,
&
consumed
,
next_avc
-
buf_index
);
if
(
!
ptr
||
dst_length
<
0
)
{
ret
=
-
1
;
goto
end
;
ret
=
ff_h2645_packet_split
(
&
h
->
pkt
,
buf
,
buf_size
,
avctx
,
h
->
is_avc
,
h
->
nal_length_size
,
avctx
->
codec_id
);
if
(
ret
<
0
)
{
av_log
(
avctx
,
AV_LOG_ERROR
,
"Error splitting the input into NAL units.
\n
"
);
return
ret
;
}
bit_length
=
get_bit_length
(
h
,
buf
,
ptr
,
dst_length
,
buf_index
+
consumed
,
next_avc
);
if
(
h
->
avctx
->
debug
&
FF_DEBUG_STARTCODE
)
av_log
(
h
->
avctx
,
AV_LOG_DEBUG
,
"NAL %d at %d/%d length %d
\n
"
,
h
->
nal_unit_type
,
buf_index
,
buf_size
,
dst_length
);
if
(
h
->
is_avc
&&
(
nalsize
!=
consumed
)
&&
nalsize
)
av_log
(
h
->
avctx
,
AV_LOG_DEBUG
,
"AVC: Consumed only %d bytes instead of %d
\n
"
,
consumed
,
nalsize
);
if
(
avctx
->
active_thread_type
&
FF_THREAD_FRAME
)
nals_needed
=
get_last_needed_nal
(
h
);
buf_index
+=
consumed
;
nal_index
++
;
for
(
i
=
0
;
i
<
h
->
pkt
.
nb_nals
;
i
++
)
{
H2645NAL
*
nal
=
&
h
->
pkt
.
nals
[
i
];
H264SliceContext
*
sl
=
&
h
->
slice_ctx
[
context_count
];
int
err
;
if
(
avctx
->
skip_frame
>=
AVDISCARD_NONREF
&&
h
->
nal_ref_idc
==
0
&&
h
->
nal_unit_type
!=
NAL_SEI
)
nal
->
ref_idc
==
0
&&
nal
->
type
!=
NAL_SEI
)
continue
;
again:
...
...
@@ -1341,19 +1197,22 @@ again:
* with frame-mt */
if
(
parse_extradata
&&
HAVE_THREADS
&&
(
h
->
avctx
->
active_thread_type
&
FF_THREAD_FRAME
)
&&
(
h
->
nal_unit_type
!=
NAL_PPS
&&
h
->
nal_unit_type
!=
NAL_SPS
))
{
if
(
h
->
nal_unit_type
<
NAL_AUD
||
h
->
nal_unit_type
>
NAL_AUXILIARY_SLICE
)
(
nal
->
type
!=
NAL_PPS
&&
nal
->
type
!=
NAL_SPS
))
{
if
(
nal
->
type
<
NAL_AUD
||
nal
->
type
>
NAL_AUXILIARY_SLICE
)
av_log
(
avctx
,
AV_LOG_INFO
,
"Ignoring NAL unit %d during extradata parsing
\n
"
,
h
->
nal_unit_
type
);
h
->
nal_unit_
type
=
NAL_FF_IGNORE
;
nal
->
type
);
nal
->
type
=
NAL_FF_IGNORE
;
}
// FIXME these should stop being context-global variables
h
->
nal_ref_idc
=
nal
->
ref_idc
;
h
->
nal_unit_type
=
nal
->
type
;
err
=
0
;
switch
(
h
->
nal_unit_
type
)
{
switch
(
nal
->
type
)
{
case
NAL_IDR_SLICE
:
if
(
h
->
nal_unit_
type
!=
NAL_IDR_SLICE
)
{
if
(
nal
->
type
!=
NAL_IDR_SLICE
)
{
av_log
(
h
->
avctx
,
AV_LOG_ERROR
,
"Invalid mix of idr and non-idr slices
\n
"
);
ret
=
-
1
;
...
...
@@ -1361,7 +1220,7 @@ again:
}
idr
(
h
);
// FIXME ensure we don't lose some frames if there is reordering
case
NAL_SLICE
:
init_get_bits
(
&
sl
->
gb
,
ptr
,
bit_length
)
;
sl
->
gb
=
nal
->
gb
;
if
((
err
=
ff_h264_decode_slice_header
(
h
,
sl
)))
break
;
...
...
@@ -1372,23 +1231,21 @@ again:
}
h
->
cur_pic_ptr
->
f
->
key_frame
|=
(
h
->
nal_unit_type
==
NAL_IDR_SLICE
)
||
(
h
->
sei_recovery_frame_cnt
>=
0
);
(
nal
->
type
==
NAL_IDR_SLICE
)
||
(
h
->
sei_recovery_frame_cnt
>=
0
);
if
(
h
->
nal_unit_type
==
NAL_IDR_SLICE
||
h
->
recovery_frame
==
h
->
frame_num
)
{
if
(
nal
->
type
==
NAL_IDR_SLICE
||
h
->
recovery_frame
==
h
->
frame_num
)
{
h
->
recovery_frame
=
-
1
;
h
->
cur_pic_ptr
->
recovered
=
1
;
}
// If we have an IDR, all frames after it in decoded order are
// "recovered".
if
(
h
->
nal_unit_
type
==
NAL_IDR_SLICE
)
if
(
nal
->
type
==
NAL_IDR_SLICE
)
h
->
frame_recovered
|=
FRAME_RECOVERED_IDR
;
h
->
cur_pic_ptr
->
recovered
|=
!!
(
h
->
frame_recovered
&
FRAME_RECOVERED_IDR
);
if
(
h
->
current_slice
==
1
)
{
if
(
!
(
avctx
->
flags2
&
AV_CODEC_FLAG2_CHUNKS
))
decode_postinit
(
h
,
nal_index
>=
nals_needed
);
decode_postinit
(
h
,
i
>=
nals_needed
);
if
(
h
->
avctx
->
hwaccel
&&
(
ret
=
h
->
avctx
->
hwaccel
->
start_frame
(
h
->
avctx
,
NULL
,
0
))
<
0
)
...
...
@@ -1396,17 +1253,14 @@ again:
}
if
(
sl
->
redundant_pic_count
==
0
&&
(
avctx
->
skip_frame
<
AVDISCARD_NONREF
||
h
->
nal_ref_idc
)
&&
(
avctx
->
skip_frame
<
AVDISCARD_NONREF
||
nal
->
ref_idc
)
&&
(
avctx
->
skip_frame
<
AVDISCARD_BIDIR
||
sl
->
slice_type_nos
!=
AV_PICTURE_TYPE_B
)
&&
(
avctx
->
skip_frame
<
AVDISCARD_NONKEY
||
h
->
cur_pic_ptr
->
f
->
key_frame
)
&&
avctx
->
skip_frame
<
AVDISCARD_ALL
)
{
if
(
avctx
->
hwaccel
)
{
ret
=
avctx
->
hwaccel
->
decode_slice
(
avctx
,
&
buf
[
buf_index
-
consumed
],
consumed
);
ret
=
avctx
->
hwaccel
->
decode_slice
(
avctx
,
nal
->
raw_data
,
nal
->
raw_size
);
if
(
ret
<
0
)
return
ret
;
}
else
...
...
@@ -1421,20 +1275,20 @@ again:
goto
end
;
break
;
case
NAL_SEI
:
init_get_bits
(
&
h
->
gb
,
ptr
,
bit_length
)
;
h
->
gb
=
nal
->
gb
;
ret
=
ff_h264_decode_sei
(
h
);
if
(
ret
<
0
&&
(
h
->
avctx
->
err_recognition
&
AV_EF_EXPLODE
))
goto
end
;
break
;
case
NAL_SPS
:
init_get_bits
(
&
h
->
gb
,
ptr
,
bit_length
)
;
h
->
gb
=
nal
->
gb
;
ret
=
ff_h264_decode_seq_parameter_set
(
h
);
if
(
ret
<
0
&&
(
h
->
avctx
->
err_recognition
&
AV_EF_EXPLODE
))
goto
end
;
break
;
case
NAL_PPS
:
init_get_bits
(
&
h
->
gb
,
ptr
,
bit_length
)
;
ret
=
ff_h264_decode_picture_parameter_set
(
h
,
bit_length
);
h
->
gb
=
nal
->
gb
;
ret
=
ff_h264_decode_picture_parameter_set
(
h
,
nal
->
size_bits
);
if
(
ret
<
0
&&
(
h
->
avctx
->
err_recognition
&
AV_EF_EXPLODE
))
goto
end
;
break
;
...
...
@@ -1449,7 +1303,7 @@ again:
break
;
default:
av_log
(
avctx
,
AV_LOG_DEBUG
,
"Unknown NAL code: %d (%d bits)
\n
"
,
h
->
nal_unit_type
,
bit_length
);
nal
->
type
,
nal
->
size_bits
);
}
if
(
context_count
==
h
->
max_contexts
)
{
...
...
@@ -1470,7 +1324,6 @@ again:
goto
again
;
}
}
}
if
(
context_count
)
{
ret
=
ff_h264_execute_decode_slices
(
h
,
context_count
);
if
(
ret
<
0
&&
(
h
->
avctx
->
err_recognition
&
AV_EF_EXPLODE
))
...
...
@@ -1485,7 +1338,7 @@ end:
h
->
picture_structure
==
PICT_BOTTOM_FIELD
);
}
return
(
ret
<
0
)
?
ret
:
buf_
index
;
return
(
ret
<
0
)
?
ret
:
buf_
size
;
}
/**
...
...
@@ -1632,6 +1485,8 @@ av_cold void ff_h264_free_context(H264Context *h)
for
(
i
=
0
;
i
<
MAX_PPS_COUNT
;
i
++
)
av_freep
(
h
->
pps_buffers
+
i
);
ff_h2645_packet_uninit
(
&
h
->
pkt
);
}
static
av_cold
int
h264_decode_end
(
AVCodecContext
*
avctx
)
...
...
libavcodec/h264.h
浏览文件 @
ca2f19b9
...
...
@@ -34,6 +34,7 @@
#include "error_resilience.h"
#include "get_bits.h"
#include "h264_parse.h"
#include "h2645_parse.h"
#include "h264chroma.h"
#include "h264dsp.h"
#include "h264pred.h"
...
...
@@ -471,6 +472,8 @@ typedef struct H264Context {
H264SliceContext
*
slice_ctx
;
int
nb_slice_ctx
;
H2645Packet
pkt
;
int
pixel_shift
;
///< 0 for 8-bit H264, 1 for high-bit-depth H264
/* coded dimensions -- 16 * mb w/h */
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录