Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in / Register
Toggle navigation
F
ffmpeg.wasm-core
Project
Project
Details
Activity
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
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Linshizhi
ffmpeg.wasm-core
Commits
cc614660
Commit
cc614660
authored
Nov 11, 2019
by
James Almer
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
avformat: add an AV1 Annex B demuxer
Signed-off-by:
James Almer
<
jamrial@gmail.com
>
parent
97d9cff2
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
283 additions
and
2 deletions
+283
-2
Changelog
Changelog
+1
-0
configure
configure
+1
-0
Makefile
libavformat/Makefile
+1
-0
allformats.c
libavformat/allformats.c
+1
-0
av1dec.c
libavformat/av1dec.c
+277
-0
version.h
libavformat/version.h
+2
-2
No files found.
Changelog
View file @
cc614660
...
...
@@ -23,6 +23,7 @@ version <next>:
- QSV-accelerated VP9 encoding
- AV1 encoding support via librav1e
- AV1 frame merge bitstream filter
- AV1 Annex B demuxer
version 4.2:
...
...
configure
View file @
cc614660
...
...
@@ -3250,6 +3250,7 @@ asf_demuxer_select="riffdec"
asf_o_demuxer_select
=
"riffdec"
asf_muxer_select
=
"riffenc"
asf_stream_muxer_select
=
"asf_muxer"
av1_demuxer_select
=
"av1_frame_merge_bsf av1_parser"
avi_demuxer_select
=
"iso_media riffdec exif"
avi_muxer_select
=
"riffenc"
caf_demuxer_select
=
"iso_media riffdec"
...
...
libavformat/Makefile
View file @
cc614660
...
...
@@ -350,6 +350,7 @@ OBJS-$(CONFIG_NULL_MUXER) += nullenc.o
OBJS-$(CONFIG_NUT_DEMUXER)
+=
nutdec.o
nut.o
isom.o
OBJS-$(CONFIG_NUT_MUXER)
+=
nutenc.o
nut.o
OBJS-$(CONFIG_NUV_DEMUXER)
+=
nuv.o
OBJS-$(CONFIG_AV1_DEMUXER)
+=
av1dec.o
OBJS-$(CONFIG_OGG_DEMUXER)
+=
oggdec.o
\
oggparsecelt.o
\
oggparsedaala.o
\
...
...
libavformat/allformats.c
View file @
cc614660
...
...
@@ -70,6 +70,7 @@ extern AVOutputFormat ff_ast_muxer;
extern
AVOutputFormat
ff_asf_stream_muxer
;
extern
AVInputFormat
ff_au_demuxer
;
extern
AVOutputFormat
ff_au_muxer
;
extern
AVInputFormat
ff_av1_demuxer
;
extern
AVInputFormat
ff_avi_demuxer
;
extern
AVOutputFormat
ff_avi_muxer
;
extern
AVInputFormat
ff_avisynth_demuxer
;
...
...
libavformat/av1dec.c
0 → 100644
View file @
cc614660
/*
* AV1 Annex B demuxer
* Copyright (c) 2019 James Almer <jamrial@gmail.com>
*
* 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 "config.h"
#include "libavutil/common.h"
#include "libavutil/opt.h"
#include "libavcodec/av1_parse.h"
#include "avformat.h"
#include "avio_internal.h"
#include "internal.h"
typedef
struct
AnnexBContext
{
const
AVClass
*
class
;
AVBSFContext
*
bsf
;
uint32_t
temporal_unit_size
;
uint32_t
frame_unit_size
;
AVRational
framerate
;
}
AnnexBContext
;
static
int
leb
(
AVIOContext
*
pb
,
uint32_t
*
len
)
{
int
more
,
i
=
0
;
uint8_t
byte
;
*
len
=
0
;
do
{
unsigned
bits
;
byte
=
avio_r8
(
pb
);
more
=
byte
&
0x80
;
bits
=
byte
&
0x7f
;
if
(
i
<=
3
||
(
i
==
4
&&
bits
<
(
1
<<
4
)))
*
len
|=
bits
<<
(
i
*
7
);
else
if
(
bits
)
return
AVERROR_INVALIDDATA
;
if
(
++
i
==
8
&&
more
)
return
AVERROR_INVALIDDATA
;
if
(
pb
->
eof_reached
||
pb
->
error
)
return
pb
->
error
?
pb
->
error
:
AVERROR
(
EIO
);
}
while
(
more
);
return
i
;
}
static
int
read_obu
(
const
uint8_t
*
buf
,
int
size
,
int64_t
*
obu_size
,
int
*
type
)
{
int
start_pos
,
temporal_id
,
spatial_id
;
int
len
;
len
=
parse_obu_header
(
buf
,
size
,
obu_size
,
&
start_pos
,
type
,
&
temporal_id
,
&
spatial_id
);
if
(
len
<
0
)
return
len
;
return
0
;
}
static
int
annexb_probe
(
const
AVProbeData
*
p
)
{
AVIOContext
pb
;
int64_t
obu_size
;
uint32_t
temporal_unit_size
,
frame_unit_size
,
obu_unit_size
;
int
seq
=
0
,
frame_header
=
0
;
int
ret
,
type
,
cnt
=
0
;
ffio_init_context
(
&
pb
,
p
->
buf
,
p
->
buf_size
,
0
,
NULL
,
NULL
,
NULL
,
NULL
);
ret
=
leb
(
&
pb
,
&
temporal_unit_size
);
if
(
ret
<
0
)
return
0
;
cnt
+=
ret
;
ret
=
leb
(
&
pb
,
&
frame_unit_size
);
if
(
ret
<
0
||
((
int64_t
)
frame_unit_size
+
ret
)
>
temporal_unit_size
)
return
0
;
cnt
+=
ret
;
temporal_unit_size
-=
ret
;
ret
=
leb
(
&
pb
,
&
obu_unit_size
);
if
(
ret
<
0
||
((
int64_t
)
obu_unit_size
+
ret
)
>=
frame_unit_size
)
return
0
;
cnt
+=
ret
;
temporal_unit_size
-=
obu_unit_size
+
ret
;
frame_unit_size
-=
obu_unit_size
+
ret
;
avio_skip
(
&
pb
,
obu_unit_size
);
if
(
pb
.
eof_reached
||
pb
.
error
)
return
0
;
// Check that the first OBU is a Temporal Delimiter.
ret
=
read_obu
(
p
->
buf
+
cnt
,
FFMIN
(
p
->
buf_size
-
cnt
,
obu_unit_size
),
&
obu_size
,
&
type
);
if
(
ret
<
0
||
type
!=
AV1_OBU_TEMPORAL_DELIMITER
||
obu_size
>
0
)
return
0
;
cnt
+=
obu_unit_size
;
do
{
ret
=
leb
(
&
pb
,
&
obu_unit_size
);
if
(
ret
<
0
||
((
int64_t
)
obu_unit_size
+
ret
)
>
frame_unit_size
)
return
0
;
cnt
+=
ret
;
avio_skip
(
&
pb
,
obu_unit_size
);
if
(
pb
.
eof_reached
||
pb
.
error
)
return
0
;
ret
=
read_obu
(
p
->
buf
+
cnt
,
FFMIN
(
p
->
buf_size
-
cnt
,
obu_unit_size
),
&
obu_size
,
&
type
);
if
(
ret
<
0
)
return
0
;
cnt
+=
obu_unit_size
;
if
(
type
==
AV1_OBU_SEQUENCE_HEADER
)
seq
=
1
;
if
(
type
==
AV1_OBU_FRAME
||
type
==
AV1_OBU_FRAME_HEADER
)
{
if
(
frame_header
||
!
seq
)
return
0
;
frame_header
=
1
;
break
;
}
if
(
type
==
AV1_OBU_TILE_GROUP
&&
!
frame_header
)
return
0
;
temporal_unit_size
-=
obu_unit_size
+
ret
;
frame_unit_size
-=
obu_unit_size
+
ret
;
}
while
(
!
frame_header
&&
frame_unit_size
);
return
frame_header
?
AVPROBE_SCORE_EXTENSION
+
1
:
0
;
}
static
int
annexb_read_header
(
AVFormatContext
*
s
)
{
AnnexBContext
*
c
=
s
->
priv_data
;
const
AVBitStreamFilter
*
filter
=
av_bsf_get_by_name
(
"av1_frame_merge"
);
AVStream
*
st
;
int
ret
;
if
(
!
filter
)
{
av_log
(
c
,
AV_LOG_ERROR
,
"av1_frame_merge bitstream filter "
"not found. This is a bug, please report it.
\n
"
);
return
AVERROR_BUG
;
}
st
=
avformat_new_stream
(
s
,
NULL
);
if
(
!
st
)
return
AVERROR
(
ENOMEM
);
st
->
codecpar
->
codec_type
=
AVMEDIA_TYPE_VIDEO
;
st
->
codecpar
->
codec_id
=
AV_CODEC_ID_AV1
;
st
->
need_parsing
=
AVSTREAM_PARSE_HEADERS
;
st
->
internal
->
avctx
->
framerate
=
c
->
framerate
;
// taken from rawvideo demuxers
avpriv_set_pts_info
(
st
,
64
,
1
,
1200000
);
ret
=
av_bsf_alloc
(
filter
,
&
c
->
bsf
);
if
(
ret
<
0
)
return
ret
;
ret
=
avcodec_parameters_copy
(
c
->
bsf
->
par_in
,
st
->
codecpar
);
if
(
ret
<
0
)
{
av_bsf_free
(
&
c
->
bsf
);
return
ret
;
}
ret
=
av_bsf_init
(
c
->
bsf
);
if
(
ret
<
0
)
av_bsf_free
(
&
c
->
bsf
);
return
ret
;
}
static
int
annexb_read_packet
(
AVFormatContext
*
s
,
AVPacket
*
pkt
)
{
AnnexBContext
*
c
=
s
->
priv_data
;
uint32_t
obu_unit_size
;
int
ret
,
len
;
retry:
if
(
avio_feof
(
s
->
pb
))
{
if
(
c
->
temporal_unit_size
||
c
->
frame_unit_size
)
return
AVERROR
(
EIO
);
av_bsf_send_packet
(
c
->
bsf
,
NULL
);
goto
end
;
}
if
(
!
c
->
temporal_unit_size
)
{
len
=
leb
(
s
->
pb
,
&
c
->
temporal_unit_size
);
if
(
len
<
0
)
return
AVERROR_INVALIDDATA
;
}
if
(
!
c
->
frame_unit_size
)
{
len
=
leb
(
s
->
pb
,
&
c
->
frame_unit_size
);
if
(
len
<
0
||
((
int64_t
)
c
->
frame_unit_size
+
len
)
>
c
->
temporal_unit_size
)
return
AVERROR_INVALIDDATA
;
c
->
temporal_unit_size
-=
len
;
}
len
=
leb
(
s
->
pb
,
&
obu_unit_size
);
if
(
len
<
0
||
((
int64_t
)
obu_unit_size
+
len
)
>
c
->
frame_unit_size
)
return
AVERROR_INVALIDDATA
;
ret
=
av_get_packet
(
s
->
pb
,
pkt
,
obu_unit_size
);
if
(
ret
<
0
)
return
ret
;
if
(
ret
!=
obu_unit_size
)
return
AVERROR
(
EIO
);
c
->
temporal_unit_size
-=
obu_unit_size
+
len
;
c
->
frame_unit_size
-=
obu_unit_size
+
len
;
ret
=
av_bsf_send_packet
(
c
->
bsf
,
pkt
);
if
(
ret
<
0
)
{
av_log
(
s
,
AV_LOG_ERROR
,
"Failed to send packet to "
"av1_frame_merge filter
\n
"
);
return
ret
;
}
end:
ret
=
av_bsf_receive_packet
(
c
->
bsf
,
pkt
);
if
(
ret
<
0
&&
ret
!=
AVERROR
(
EAGAIN
)
&&
ret
!=
AVERROR_EOF
)
av_log
(
s
,
AV_LOG_ERROR
,
"av1_frame_merge filter failed to "
"send output packet
\n
"
);
if
(
ret
==
AVERROR
(
EAGAIN
))
goto
retry
;
return
ret
;
}
static
int
annexb_read_close
(
AVFormatContext
*
s
)
{
AnnexBContext
*
c
=
s
->
priv_data
;
av_bsf_free
(
&
c
->
bsf
);
return
0
;
}
#define OFFSET(x) offsetof(AnnexBContext, x)
#define DEC AV_OPT_FLAG_DECODING_PARAM
static
const
AVOption
annexb_options
[]
=
{
{
"framerate"
,
""
,
OFFSET
(
framerate
),
AV_OPT_TYPE_VIDEO_RATE
,
{.
str
=
"25"
},
0
,
INT_MAX
,
DEC
},
{
NULL
},
};
static
const
AVClass
annexb_demuxer_class
=
{
.
class_name
=
"AV1 Annex B demuxer"
,
.
item_name
=
av_default_item_name
,
.
option
=
annexb_options
,
.
version
=
LIBAVUTIL_VERSION_INT
,
};
AVInputFormat
ff_av1_demuxer
=
{
.
name
=
"av1"
,
.
long_name
=
NULL_IF_CONFIG_SMALL
(
"AV1 Annex B"
),
.
priv_data_size
=
sizeof
(
AnnexBContext
),
.
read_probe
=
annexb_probe
,
.
read_header
=
annexb_read_header
,
.
read_packet
=
annexb_read_packet
,
.
read_close
=
annexb_read_close
,
.
extensions
=
"obu"
,
.
flags
=
AVFMT_GENERIC_INDEX
,
.
priv_class
=
&
annexb_demuxer_class
,
};
libavformat/version.h
View file @
cc614660
...
...
@@ -32,8 +32,8 @@
// Major bumping may affect Ticket5467, 5421, 5451(compatibility with Chromium)
// Also please add any ticket numbers that you believe might be affected here
#define LIBAVFORMAT_VERSION_MAJOR 58
#define LIBAVFORMAT_VERSION_MINOR 3
4
#define LIBAVFORMAT_VERSION_MICRO 10
1
#define LIBAVFORMAT_VERSION_MINOR 3
5
#define LIBAVFORMAT_VERSION_MICRO 10
0
#define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \
LIBAVFORMAT_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