Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
F
FFmpeg
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Container Registry
Model registry
Operate
Environments
Monitor
Incidents
Service Desk
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
libremedia
Tethys
FFmpeg
Commits
ef23ed6f
Commit
ef23ed6f
authored
8 years ago
by
Baptiste Coudurier
Browse files
Options
Downloads
Patches
Plain Diff
lavf/mxfdec: demux s436m as eia608 subtitle track
parent
9b7ab579
No related branches found
Branches containing commit
No related tags found
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
libavformat/mxfdec.c
+106
-0
106 additions, 0 deletions
libavformat/mxfdec.c
with
106 additions
and
0 deletions
libavformat/mxfdec.c
+
106
−
0
View file @
ef23ed6f
...
@@ -52,6 +52,7 @@
...
@@ -52,6 +52,7 @@
#include
"libavutil/intreadwrite.h"
#include
"libavutil/intreadwrite.h"
#include
"libavutil/parseutils.h"
#include
"libavutil/parseutils.h"
#include
"libavutil/timecode.h"
#include
"libavutil/timecode.h"
#include
"libavutil/opt.h"
#include
"avformat.h"
#include
"avformat.h"
#include
"internal.h"
#include
"internal.h"
#include
"mxf.h"
#include
"mxf.h"
...
@@ -265,6 +266,7 @@ typedef struct MXFIndexTable {
...
@@ -265,6 +266,7 @@ typedef struct MXFIndexTable {
}
MXFIndexTable
;
}
MXFIndexTable
;
typedef
struct
MXFContext
{
typedef
struct
MXFContext
{
const
AVClass
*
class
;
/**< Class for private options. */
MXFPartition
*
partitions
;
MXFPartition
*
partitions
;
unsigned
partitions_count
;
unsigned
partitions_count
;
MXFOP
op
;
MXFOP
op
;
...
@@ -287,6 +289,7 @@ typedef struct MXFContext {
...
@@ -287,6 +289,7 @@ typedef struct MXFContext {
int
last_forward_partition
;
int
last_forward_partition
;
int
nb_index_tables
;
int
nb_index_tables
;
MXFIndexTable
*
index_tables
;
MXFIndexTable
*
index_tables
;
int
eia608_extract
;
}
MXFContext
;
}
MXFContext
;
/* NOTE: klv_offset is not set (-1) for local keys */
/* 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)
...
@@ -449,6 +452,81 @@ static int find_body_sid_by_offset(MXFContext *mxf, int64_t offset)
return
mxf
->
partitions
[
a
].
body_sid
;
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 */
/* XXX: use AVBitStreamFilter */
static
int
mxf_get_d10_aes3_packet
(
AVIOContext
*
pb
,
AVStream
*
st
,
AVPacket
*
pkt
,
int64_t
length
)
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)
...
@@ -2433,6 +2511,11 @@ static int mxf_parse_structural_metadata(MXFContext *mxf)
st
->
codecpar
->
codec_type
=
type
;
st
->
codecpar
->
codec_type
=
type
;
if
(
container_ul
->
desc
)
if
(
container_ul
->
desc
)
av_dict_set
(
&
st
->
metadata
,
"data_type"
,
container_ul
->
desc
,
0
);
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
(
descriptor
->
extradata
)
{
if
(
!
ff_alloc_extradata
(
st
->
codecpar
,
descriptor
->
extradata_size
))
{
if
(
!
ff_alloc_extradata
(
st
->
codecpar
,
descriptor
->
extradata_size
))
{
...
@@ -3409,6 +3492,13 @@ static int mxf_read_packet(AVFormatContext *s, AVPacket *pkt)
...
@@ -3409,6 +3492,13 @@ static int mxf_read_packet(AVFormatContext *s, AVPacket *pkt)
mxf
->
current_klv_data
=
(
KLVPacket
){{
0
}};
mxf
->
current_klv_data
=
(
KLVPacket
){{
0
}};
return
ret
;
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
{
}
else
{
ret
=
av_get_packet
(
s
->
pb
,
pkt
,
klv
.
length
);
ret
=
av_get_packet
(
s
->
pb
,
pkt
,
klv
.
length
);
if
(
ret
<
0
)
{
if
(
ret
<
0
)
{
...
@@ -3607,6 +3697,21 @@ static int mxf_read_seek(AVFormatContext *s, int stream_index, int64_t sample_ti
...
@@ -3607,6 +3697,21 @@ static int mxf_read_seek(AVFormatContext *s, int stream_index, int64_t sample_ti
return
0
;
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
=
{
AVInputFormat
ff_mxf_demuxer
=
{
.
name
=
"mxf"
,
.
name
=
"mxf"
,
.
long_name
=
NULL_IF_CONFIG_SMALL
(
"MXF (Material eXchange Format)"
),
.
long_name
=
NULL_IF_CONFIG_SMALL
(
"MXF (Material eXchange Format)"
),
...
@@ -3617,4 +3722,5 @@ AVInputFormat ff_mxf_demuxer = {
...
@@ -3617,4 +3722,5 @@ AVInputFormat ff_mxf_demuxer = {
.
read_packet
=
mxf_read_packet
,
.
read_packet
=
mxf_read_packet
,
.
read_close
=
mxf_read_close
,
.
read_close
=
mxf_read_close
,
.
read_seek
=
mxf_read_seek
,
.
read_seek
=
mxf_read_seek
,
.
priv_class
=
&
demuxer_class
,
};
};
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment