Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
小白菜888
Ffmpeg
提交
ef23ed6f
F
Ffmpeg
项目概览
小白菜888
/
Ffmpeg
通知
3
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,发现更多精彩内容 >>
提交
ef23ed6f
编写于
2月 14, 2017
作者:
B
Baptiste Coudurier
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
lavf/mxfdec: demux s436m as eia608 subtitle track
上级
9b7ab579
变更
1
显示空白变更内容
内联
并排
Showing
1 changed file
with
106 addition
and
0 deletion
+106
-0
libavformat/mxfdec.c
libavformat/mxfdec.c
+106
-0
未找到文件。
libavformat/mxfdec.c
浏览文件 @
ef23ed6f
...
...
@@ -52,6 +52,7 @@
#include "libavutil/intreadwrite.h"
#include "libavutil/parseutils.h"
#include "libavutil/timecode.h"
#include "libavutil/opt.h"
#include "avformat.h"
#include "internal.h"
#include "mxf.h"
...
...
@@ -265,6 +266,7 @@ typedef struct MXFIndexTable {
}
MXFIndexTable
;
typedef
struct
MXFContext
{
const
AVClass
*
class
;
/**< Class for private options. */
MXFPartition
*
partitions
;
unsigned
partitions_count
;
MXFOP
op
;
...
...
@@ -287,6 +289,7 @@ typedef struct MXFContext {
int
last_forward_partition
;
int
nb_index_tables
;
MXFIndexTable
*
index_tables
;
int
eia608_extract
;
}
MXFContext
;
/* NOTE: klv_offset is not set (-1) for local keys */
...
...
@@ -449,6 +452,81 @@ static int find_body_sid_by_offset(MXFContext *mxf, int64_t offset)
return
mxf
->
partitions
[
a
].
body_sid
;
}
static
int
mxf_get_eia608_packet
(
AVFormatContext
*
s
,
AVStream
*
st
,
AVPacket
*
pkt
,
int64_t
length
)
{
int
count
=
avio_rb16
(
s
->
pb
);
int
cdp_identifier
,
cdp_length
,
cdp_footer_id
,
ccdata_id
,
cc_count
;
int
line_num
,
sample_coding
,
sample_count
;
int
did
,
sdid
,
data_length
;
int
i
,
ret
;
if
(
count
!=
1
)
av_log
(
s
,
AV_LOG_WARNING
,
"unsupported multiple ANC packets (%d) per KLV packet
\n
"
,
count
);
for
(
i
=
0
;
i
<
count
;
i
++
)
{
if
(
length
<
6
)
{
av_log
(
s
,
AV_LOG_ERROR
,
"error reading s436m packet %"
PRId64
"
\n
"
,
length
);
return
AVERROR_INVALIDDATA
;
}
line_num
=
avio_rb16
(
s
->
pb
);
avio_r8
(
s
->
pb
);
// wrapping type
sample_coding
=
avio_r8
(
s
->
pb
);
sample_count
=
avio_rb16
(
s
->
pb
);
length
-=
6
+
8
+
sample_count
;
if
(
line_num
!=
9
&&
line_num
!=
11
)
continue
;
if
(
sample_coding
==
7
||
sample_coding
==
8
||
sample_coding
==
9
)
{
av_log
(
s
,
AV_LOG_WARNING
,
"unsupported s436m 10 bit sample coding
\n
"
);
continue
;
}
if
(
length
<
0
)
return
AVERROR_INVALIDDATA
;
avio_rb32
(
s
->
pb
);
// array count
avio_rb32
(
s
->
pb
);
// array elem size
did
=
avio_r8
(
s
->
pb
);
sdid
=
avio_r8
(
s
->
pb
);
data_length
=
avio_r8
(
s
->
pb
);
if
(
did
!=
0x61
||
sdid
!=
1
)
{
av_log
(
s
,
AV_LOG_WARNING
,
"unsupported did or sdid: %x %x
\n
"
,
did
,
sdid
);
continue
;
}
cdp_identifier
=
avio_rb16
(
s
->
pb
);
// cdp id
if
(
cdp_identifier
!=
0x9669
)
{
av_log
(
s
,
AV_LOG_ERROR
,
"wrong cdp identifier %x
\n
"
,
cdp_identifier
);
return
AVERROR_INVALIDDATA
;
}
cdp_length
=
avio_r8
(
s
->
pb
);
avio_r8
(
s
->
pb
);
// cdp_frame_rate
avio_r8
(
s
->
pb
);
// cdp_flags
avio_rb16
(
s
->
pb
);
// cdp_hdr_sequence_cntr
ccdata_id
=
avio_r8
(
s
->
pb
);
// ccdata_id
if
(
ccdata_id
!=
0x72
)
{
av_log
(
s
,
AV_LOG_ERROR
,
"wrong cdp data section %x
\n
"
,
ccdata_id
);
return
AVERROR_INVALIDDATA
;
}
cc_count
=
avio_r8
(
s
->
pb
)
&
0x1f
;
ret
=
av_get_packet
(
s
->
pb
,
pkt
,
cc_count
*
3
);
if
(
ret
<
0
)
return
ret
;
if
(
cdp_length
-
9
-
4
<
cc_count
*
3
)
{
av_log
(
s
,
AV_LOG_ERROR
,
"wrong cdp size %d cc count %d
\n
"
,
cdp_length
,
cc_count
);
return
AVERROR_INVALIDDATA
;
}
avio_skip
(
s
->
pb
,
data_length
-
9
-
4
-
cc_count
*
3
);
cdp_footer_id
=
avio_r8
(
s
->
pb
);
if
(
cdp_footer_id
!=
0x74
)
{
av_log
(
s
,
AV_LOG_ERROR
,
"wrong cdp footer section %x
\n
"
,
cdp_footer_id
);
return
AVERROR_INVALIDDATA
;
}
avio_rb16
(
s
->
pb
);
// cdp_ftr_sequence_cntr
avio_r8
(
s
->
pb
);
// packet_checksum
break
;
}
return
0
;
}
/* XXX: use AVBitStreamFilter */
static
int
mxf_get_d10_aes3_packet
(
AVIOContext
*
pb
,
AVStream
*
st
,
AVPacket
*
pkt
,
int64_t
length
)
{
...
...
@@ -2433,6 +2511,11 @@ static int mxf_parse_structural_metadata(MXFContext *mxf)
st
->
codecpar
->
codec_type
=
type
;
if
(
container_ul
->
desc
)
av_dict_set
(
&
st
->
metadata
,
"data_type"
,
container_ul
->
desc
,
0
);
if
(
mxf
->
eia608_extract
&&
!
strcmp
(
container_ul
->
desc
,
"vbi_vanc_smpte_436M"
))
{
st
->
codecpar
->
codec_type
=
AVMEDIA_TYPE_SUBTITLE
;
st
->
codecpar
->
codec_id
=
AV_CODEC_ID_EIA_608
;
}
}
if
(
descriptor
->
extradata
)
{
if
(
!
ff_alloc_extradata
(
st
->
codecpar
,
descriptor
->
extradata_size
))
{
...
...
@@ -3409,6 +3492,13 @@ static int mxf_read_packet(AVFormatContext *s, AVPacket *pkt)
mxf
->
current_klv_data
=
(
KLVPacket
){{
0
}};
return
ret
;
}
}
else
if
(
mxf
->
eia608_extract
&&
s
->
streams
[
index
]
->
codecpar
->
codec_id
==
AV_CODEC_ID_EIA_608
)
{
ret
=
mxf_get_eia608_packet
(
s
,
s
->
streams
[
index
],
pkt
,
klv
.
length
);
if
(
ret
<
0
)
{
mxf
->
current_klv_data
=
(
KLVPacket
){{
0
}};
return
ret
;
}
}
else
{
ret
=
av_get_packet
(
s
->
pb
,
pkt
,
klv
.
length
);
if
(
ret
<
0
)
{
...
...
@@ -3607,6 +3697,21 @@ static int mxf_read_seek(AVFormatContext *s, int stream_index, int64_t sample_ti
return
0
;
}
static
const
AVOption
options
[]
=
{
{
"eia608_extract"
,
"extract eia 608 captions from s436m track"
,
offsetof
(
MXFContext
,
eia608_extract
),
AV_OPT_TYPE_BOOL
,
{.
i64
=
0
},
0
,
1
,
AV_OPT_FLAG_DECODING_PARAM
},
{
NULL
},
};
static
const
AVClass
demuxer_class
=
{
.
class_name
=
"mxf"
,
.
item_name
=
av_default_item_name
,
.
option
=
options
,
.
version
=
LIBAVUTIL_VERSION_INT
,
.
category
=
AV_CLASS_CATEGORY_DEMUXER
,
};
AVInputFormat
ff_mxf_demuxer
=
{
.
name
=
"mxf"
,
.
long_name
=
NULL_IF_CONFIG_SMALL
(
"MXF (Material eXchange Format)"
),
...
...
@@ -3617,4 +3722,5 @@ AVInputFormat ff_mxf_demuxer = {
.
read_packet
=
mxf_read_packet
,
.
read_close
=
mxf_read_close
,
.
read_seek
=
mxf_read_seek
,
.
priv_class
=
&
demuxer_class
,
};
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录