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
74141f69
Commit
74141f69
authored
Oct 17, 2014
by
Kieran Kunhya
Committed by
Michael Niedermayer
Oct 26, 2014
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
avcodec: Add support for Opus in MPEG-TS
Signed-off-by:
Michael Niedermayer
<
michaelni@gmx.at
>
parent
05da586f
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
139 additions
and
22 deletions
+139
-22
opus.c
libavcodec/opus.c
+3
-8
opus.h
libavcodec/opus.h
+9
-0
opus_parser.c
libavcodec/opus_parser.c
+126
-13
version.h
libavcodec/version.h
+1
-1
No files found.
libavcodec/opus.c
View file @
74141f69
...
...
@@ -290,10 +290,6 @@ av_cold int ff_opus_parse_extradata(AVCodecContext *avctx,
OpusContext
*
s
)
{
static
const
uint8_t
default_channel_map
[
2
]
=
{
0
,
1
};
uint8_t
default_extradata
[
19
]
=
{
'O'
,
'p'
,
'u'
,
's'
,
'H'
,
'e'
,
'a'
,
'd'
,
1
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
};
int
(
*
channel_reorder
)(
int
,
int
)
=
channel_reorder_unknown
;
...
...
@@ -308,9 +304,8 @@ av_cold int ff_opus_parse_extradata(AVCodecContext *avctx,
"Multichannel configuration without extradata.
\n
"
);
return
AVERROR
(
EINVAL
);
}
default_extradata
[
9
]
=
(
avctx
->
channels
==
1
)
?
1
:
2
;
extradata
=
default_extradata
;
extradata_size
=
sizeof
(
default_extradata
);
extradata
=
opus_default_extradata
;
extradata_size
=
sizeof
(
opus_default_extradata
);
}
else
{
extradata
=
avctx
->
extradata
;
extradata_size
=
avctx
->
extradata_size
;
...
...
@@ -330,7 +325,7 @@ av_cold int ff_opus_parse_extradata(AVCodecContext *avctx,
avctx
->
delay
=
AV_RL16
(
extradata
+
10
);
channels
=
extradata
[
9
]
;
channels
=
avctx
->
extradata
?
extradata
[
9
]
:
(
avctx
->
channels
==
1
)
?
1
:
2
;
if
(
!
channels
)
{
av_log
(
avctx
,
AV_LOG_ERROR
,
"Zero channel count specified in the extadata
\n
"
);
return
AVERROR_INVALIDDATA
;
...
...
libavcodec/opus.h
View file @
74141f69
...
...
@@ -61,6 +61,15 @@
#define ROUND_MUL16(a,b) ((MUL16(a, b) + 16384) >> 15)
#define opus_ilog(i) (av_log2(i) + !!(i))
#define OPUS_TS_HEADER 0x7FE0 // 0x3ff (11 bits)
#define OPUS_TS_MASK 0xFFE0 // top 11 bits
static
const
uint8_t
opus_default_extradata
[
30
]
=
{
'O'
,
'p'
,
'u'
,
's'
,
'H'
,
'e'
,
'a'
,
'd'
,
1
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
};
enum
OpusMode
{
OPUS_MODE_SILK
,
OPUS_MODE_HYBRID
,
...
...
libavcodec/opus_parser.c
View file @
74141f69
...
...
@@ -27,49 +27,162 @@
#include "avcodec.h"
#include "opus.h"
#include "parser.h"
#include "bytestream.h"
typedef
struct
OpusParseContext
{
OpusContext
ctx
;
OpusPacket
pkt
;
int
extradata_parsed
;
ParseContext
pc
;
int
ts_framing
;
}
OpusParseContext
;
static
int
opus_parse
(
AVCodecParserContext
*
ctx
,
AVCodecContext
*
avctx
,
const
uint8_t
**
poutbuf
,
int
*
poutbuf_size
,
const
uint8_t
*
buf
,
int
buf_size
)
static
const
uint8_t
*
parse_opus_ts_header
(
const
uint8_t
*
start
,
int
*
payload_len
,
int
buf_len
)
{
const
uint8_t
*
buf
=
start
+
1
;
int
start_trim_flag
,
end_trim_flag
,
control_extension_flag
,
control_extension_length
;
uint8_t
flags
;
GetByteContext
gb
;
bytestream2_init
(
&
gb
,
buf
,
buf_len
);
flags
=
bytestream2_get_byte
(
&
gb
);
start_trim_flag
=
(
flags
>>
4
)
&
1
;
end_trim_flag
=
(
flags
>>
3
)
&
1
;
control_extension_flag
=
(
flags
>>
2
)
&
1
;
*
payload_len
=
0
;
while
(
bytestream2_peek_byte
(
&
gb
)
==
0xff
)
*
payload_len
+=
bytestream2_get_byte
(
&
gb
);
*
payload_len
+=
bytestream2_get_byte
(
&
gb
);
if
(
start_trim_flag
)
bytestream2_skip
(
&
gb
,
2
);
if
(
end_trim_flag
)
bytestream2_skip
(
&
gb
,
2
);
if
(
control_extension_flag
)
{
control_extension_length
=
bytestream2_get_byte
(
&
gb
);
bytestream2_skip
(
&
gb
,
control_extension_length
);
}
return
buf
+
bytestream2_tell
(
&
gb
);
}
/**
* Find the end of the current frame in the bitstream.
* @return the position of the first byte of the next frame, or -1
*/
static
int
opus_find_frame_end
(
AVCodecParserContext
*
ctx
,
AVCodecContext
*
avctx
,
const
uint8_t
*
buf
,
int
buf_size
,
int
*
header_len
)
{
OpusParseContext
*
s
=
ctx
->
priv_data
;
int
ret
;
ParseContext
*
pc
=
&
s
->
pc
;
int
ret
,
start_found
,
i
=
0
,
payload_len
=
0
;
const
uint8_t
*
payload
;
uint32_t
state
;
uint16_t
hdr
;
*
header_len
=
0
;
if
(
!
buf_size
)
return
0
;
start_found
=
pc
->
frame_start_found
;
state
=
pc
->
state
;
payload
=
buf
;
/* Check if we're using Opus in MPEG-TS framing */
if
(
!
s
->
ts_framing
&&
buf_size
>
2
)
{
hdr
=
AV_RB16
(
buf
);
if
((
hdr
&
OPUS_TS_MASK
)
==
OPUS_TS_HEADER
)
s
->
ts_framing
=
1
;
}
if
(
s
->
ts_framing
&&
!
start_found
)
{
for
(
i
=
0
;
i
<
buf_size
-
2
;
i
++
)
{
state
=
(
state
<<
8
)
|
payload
[
i
];
if
((
state
&
OPUS_TS_MASK
)
==
OPUS_TS_HEADER
)
{
payload
=
parse_opus_ts_header
(
payload
,
&
payload_len
,
buf_size
-
i
);
*
header_len
=
payload
-
buf
;
start_found
=
1
;
break
;
}
}
}
if
(
!
s
->
ts_framing
)
payload_len
=
buf_size
;
if
(
avctx
->
extradata
&&
!
s
->
extradata_parsed
)
{
ret
=
ff_opus_parse_extradata
(
avctx
,
&
s
->
ctx
);
if
(
ret
<
0
)
{
av_log
(
avctx
,
AV_LOG_ERROR
,
"Error parsing Ogg extradata.
\n
"
);
goto
fail
;
return
AVERROR_INVALIDDATA
;
}
av_freep
(
&
s
->
ctx
.
channel_maps
);
s
->
extradata_parsed
=
1
;
}
ret
=
ff_opus_parse_packet
(
&
s
->
pkt
,
buf
,
buf_size
,
s
->
ctx
.
nb_streams
>
1
);
if
(
ret
<
0
)
{
av_log
(
avctx
,
AV_LOG_ERROR
,
"Error parsing Opus packet header.
\n
"
);
goto
fail
;
if
(
payload_len
<=
buf_size
&&
(
!
s
->
ts_framing
||
start_found
))
{
ret
=
ff_opus_parse_packet
(
&
s
->
pkt
,
payload
,
payload_len
,
s
->
ctx
.
nb_streams
>
1
);
if
(
ret
<
0
)
{
av_log
(
avctx
,
AV_LOG_ERROR
,
"Error parsing Opus packet header.
\n
"
);
pc
->
frame_start_found
=
0
;
return
AVERROR_INVALIDDATA
;
}
ctx
->
duration
=
s
->
pkt
.
frame_count
*
s
->
pkt
.
frame_duration
;
}
ctx
->
duration
=
s
->
pkt
.
frame_count
*
s
->
pkt
.
frame_duration
;
if
(
s
->
ts_framing
)
{
if
(
start_found
)
{
if
(
payload_len
+
*
header_len
<=
buf_size
)
{
pc
->
frame_start_found
=
0
;
pc
->
state
=
-
1
;
return
payload_len
+
*
header_len
;
}
}
pc
->
frame_start_found
=
start_found
;
pc
->
state
=
state
;
return
END_NOT_FOUND
;
}
fail:
*
poutbuf
=
buf
;
*
poutbuf_size
=
buf_size
;
return
buf_size
;
}
static
int
opus_parse
(
AVCodecParserContext
*
ctx
,
AVCodecContext
*
avctx
,
const
uint8_t
**
poutbuf
,
int
*
poutbuf_size
,
const
uint8_t
*
buf
,
int
buf_size
)
{
OpusParseContext
*
s
=
ctx
->
priv_data
;
ParseContext
*
pc
=
&
s
->
pc
;
int
next
,
header_len
;
next
=
opus_find_frame_end
(
ctx
,
avctx
,
buf
,
buf_size
,
&
header_len
);
if
(
s
->
ts_framing
&&
next
!=
AVERROR_INVALIDDATA
&&
ff_combine_frame
(
pc
,
next
,
&
buf
,
&
buf_size
)
<
0
)
{
*
poutbuf
=
NULL
;
*
poutbuf_size
=
0
;
return
buf_size
;
}
if
(
next
==
AVERROR_INVALIDDATA
){
*
poutbuf
=
NULL
;
*
poutbuf_size
=
0
;
return
buf_size
;
}
*
poutbuf
=
buf
+
header_len
;
*
poutbuf_size
=
buf_size
-
header_len
;
return
next
;
}
AVCodecParser
ff_opus_parser
=
{
.
codec_ids
=
{
AV_CODEC_ID_OPUS
},
.
priv_data_size
=
sizeof
(
OpusParseContext
),
.
parser_parse
=
opus_parse
,
.
parser_close
=
ff_parse_close
};
libavcodec/version.h
View file @
74141f69
...
...
@@ -29,7 +29,7 @@
#include "libavutil/version.h"
#define LIBAVCODEC_VERSION_MAJOR 56
#define LIBAVCODEC_VERSION_MINOR
9
#define LIBAVCODEC_VERSION_MINOR
10
#define LIBAVCODEC_VERSION_MICRO 100
#define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
...
...
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