Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
F
ffmpeg
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
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
submodule
ffmpeg
Commits
96084251
Commit
96084251
authored
Feb 13, 2015
by
Gilles Chanteperdrix
Committed by
Martin Storsjö
Feb 21, 2015
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
libavformat: add robust MPEG audio depacketization (RFC 5219)
Signed-off-by:
Martin Storsjö
<
martin@martin.st
>
parent
5cbae565
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
229 additions
and
1 deletion
+229
-1
Changelog
Changelog
+1
-0
Makefile
libavformat/Makefile
+1
-0
rtpdec.c
libavformat/rtpdec.c
+1
-0
rtpdec_formats.h
libavformat/rtpdec_formats.h
+1
-0
rtpdec_mpa_robust.c
libavformat/rtpdec_mpa_robust.c
+224
-0
version.h
libavformat/version.h
+1
-1
No files found.
Changelog
View file @
96084251
...
...
@@ -17,6 +17,7 @@ version <next>:
- Intel QSV-accelerated H.264 decoding
- DSS SP decoder and DSS demuxer
- RTP depacketizer for AC3 payload format (RFC 4184)
- RTP depacketizer for loss tolerant payload format for MP3 audio (RFC 5219)
version 11:
...
...
libavformat/Makefile
View file @
96084251
...
...
@@ -40,6 +40,7 @@ OBJS-$(CONFIG_RTPDEC) += rdt.o \
rtpdec_ilbc.o
\
rtpdec_jpeg.o
\
rtpdec_latm.o
\
rtpdec_mpa_robust.o
\
rtpdec_mpeg12.o
\
rtpdec_mpeg4.o
\
rtpdec_mpegts.o
\
...
...
libavformat/rtpdec.c
View file @
96084251
...
...
@@ -78,6 +78,7 @@ void ff_register_rtp_dynamic_payload_handlers(void)
ff_register_dynamic_payload_handler
(
&
ff_mp4a_latm_dynamic_handler
);
ff_register_dynamic_payload_handler
(
&
ff_mp4v_es_dynamic_handler
);
ff_register_dynamic_payload_handler
(
&
ff_mpeg_audio_dynamic_handler
);
ff_register_dynamic_payload_handler
(
&
ff_mpeg_audio_robust_dynamic_handler
);
ff_register_dynamic_payload_handler
(
&
ff_mpeg_video_dynamic_handler
);
ff_register_dynamic_payload_handler
(
&
ff_mpeg4_generic_dynamic_handler
);
ff_register_dynamic_payload_handler
(
&
ff_mpegts_dynamic_handler
);
...
...
libavformat/rtpdec_formats.h
View file @
96084251
...
...
@@ -61,6 +61,7 @@ extern RTPDynamicProtocolHandler ff_jpeg_dynamic_handler;
extern
RTPDynamicProtocolHandler
ff_mp4a_latm_dynamic_handler
;
extern
RTPDynamicProtocolHandler
ff_mp4v_es_dynamic_handler
;
extern
RTPDynamicProtocolHandler
ff_mpeg_audio_dynamic_handler
;
extern
RTPDynamicProtocolHandler
ff_mpeg_audio_robust_dynamic_handler
;
extern
RTPDynamicProtocolHandler
ff_mpeg_video_dynamic_handler
;
extern
RTPDynamicProtocolHandler
ff_mpeg4_generic_dynamic_handler
;
extern
RTPDynamicProtocolHandler
ff_mpegts_dynamic_handler
;
...
...
libavformat/rtpdec_mpa_robust.c
0 → 100644
View file @
96084251
/*
* RTP parser for loss tolerant payload format for MP3 audio (RFC 5219)
* Copyright (c) 2015 Gilles Chanteperdrix <gch@xenomai.org>
*
* This file is part of Libav.
*
* Libav 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.
*
* Libav 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 Libav; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "libavutil/attributes.h"
#include "libavutil/intreadwrite.h"
#include "rtpdec_formats.h"
struct
PayloadContext
{
unsigned
adu_size
;
unsigned
cur_size
;
uint32_t
timestamp
;
uint8_t
*
split_buf
;
int
split_pos
,
split_buf_size
,
split_pkts
;
AVIOContext
*
fragment
;
};
static
av_cold
int
mpa_robust_init
(
AVFormatContext
*
ctx
,
int
st_index
,
PayloadContext
*
data
)
{
if
(
st_index
<
0
)
return
0
;
ctx
->
streams
[
st_index
]
->
need_parsing
=
AVSTREAM_PARSE_HEADERS
;
return
0
;
}
static
PayloadContext
*
mpa_robust_new_context
(
void
)
{
return
av_mallocz
(
sizeof
(
PayloadContext
));
}
static
inline
void
free_fragment
(
PayloadContext
*
data
)
{
if
(
data
->
fragment
)
{
uint8_t
*
p
;
avio_close_dyn_buf
(
data
->
fragment
,
&
p
);
av_free
(
p
);
data
->
fragment
=
NULL
;
}
}
static
void
mpa_robust_free_context
(
PayloadContext
*
data
)
{
free_fragment
(
data
);
av_free
(
data
->
split_buf
);
av_free
(
data
);
}
static
int
mpa_robust_parse_rtp_header
(
AVFormatContext
*
ctx
,
const
uint8_t
*
buf
,
int
len
,
unsigned
*
adu_size
,
unsigned
*
cont
)
{
unsigned
header_size
;
if
(
len
<
2
)
{
av_log
(
ctx
,
AV_LOG_ERROR
,
"Invalid %d bytes packet
\n
"
,
len
);
return
AVERROR_INVALIDDATA
;
}
*
cont
=
!!
(
buf
[
0
]
&
0x80
);
if
(
!
(
buf
[
0
]
&
0x40
))
{
header_size
=
1
;
*
adu_size
=
buf
[
0
]
&
~
0xc0
;
}
else
{
header_size
=
2
;
*
adu_size
=
AV_RB16
(
buf
)
&
~
0xc000
;
}
return
header_size
;
}
static
int
mpa_robust_parse_packet
(
AVFormatContext
*
ctx
,
PayloadContext
*
data
,
AVStream
*
st
,
AVPacket
*
pkt
,
uint32_t
*
timestamp
,
const
uint8_t
*
buf
,
int
len
,
uint16_t
seq
,
int
flags
)
{
unsigned
adu_size
,
continuation
;
int
err
,
header_size
;
if
(
!
buf
)
{
buf
=
&
data
->
split_buf
[
data
->
split_pos
];
len
=
data
->
split_buf_size
-
data
->
split_pos
;
header_size
=
mpa_robust_parse_rtp_header
(
ctx
,
buf
,
len
,
&
adu_size
,
&
continuation
);
if
(
header_size
<
0
)
{
av_freep
(
&
data
->
split_buf
);
return
header_size
;
}
buf
+=
header_size
;
len
-=
header_size
;
if
(
continuation
||
adu_size
>
len
)
{
av_freep
(
&
data
->
split_buf
);
av_log
(
ctx
,
AV_LOG_ERROR
,
"Invalid frame
\n
"
);
return
AVERROR_INVALIDDATA
;
}
if
(
av_new_packet
(
pkt
,
adu_size
))
{
av_log
(
ctx
,
AV_LOG_ERROR
,
"Out of memory.
\n
"
);
return
AVERROR
(
ENOMEM
);
}
pkt
->
stream_index
=
st
->
index
;
memcpy
(
pkt
->
data
,
buf
,
adu_size
);
data
->
split_pos
+=
adu_size
;
if
(
data
->
split_pos
==
data
->
split_buf_size
)
{
av_freep
(
&
data
->
split_buf
);
return
0
;
}
return
1
;
}
header_size
=
mpa_robust_parse_rtp_header
(
ctx
,
buf
,
len
,
&
adu_size
,
&
continuation
);
if
(
header_size
<
0
)
return
header_size
;
buf
+=
header_size
;
len
-=
header_size
;
if
(
!
continuation
&&
adu_size
<=
len
)
{
/* One or more complete frames */
if
(
av_new_packet
(
pkt
,
adu_size
))
{
av_log
(
ctx
,
AV_LOG_ERROR
,
"Out of memory.
\n
"
);
return
AVERROR
(
ENOMEM
);
}
pkt
->
stream_index
=
st
->
index
;
memcpy
(
pkt
->
data
,
buf
,
adu_size
);
buf
+=
adu_size
;
len
-=
adu_size
;
if
(
len
)
{
data
->
split_buf_size
=
len
;
data
->
split_buf
=
av_malloc
(
data
->
split_buf_size
);
data
->
split_pos
=
0
;
if
(
!
data
->
split_buf
)
{
av_log
(
ctx
,
AV_LOG_ERROR
,
"Out of memory.
\n
"
);
av_free_packet
(
pkt
);
return
AVERROR
(
ENOMEM
);
}
memcpy
(
data
->
split_buf
,
buf
,
data
->
split_buf_size
);
return
1
;
}
return
0
;
}
else
if
(
!
continuation
)
{
/* && adu_size > len */
/* First fragment */
free_fragment
(
data
);
data
->
adu_size
=
adu_size
;
data
->
cur_size
=
len
;
data
->
timestamp
=
*
timestamp
;
err
=
avio_open_dyn_buf
(
&
data
->
fragment
);
if
(
err
<
0
)
return
err
;
avio_write
(
data
->
fragment
,
buf
,
len
);
return
AVERROR
(
EAGAIN
);
}
/* else continuation == 1 */
/* Fragment other than first */
if
(
!
data
->
fragment
)
{
av_log
(
ctx
,
AV_LOG_WARNING
,
"Received packet without a start fragment; dropping.
\n
"
);
return
AVERROR
(
EAGAIN
);
}
if
(
adu_size
=
data
->
adu_size
||
data
->
timestamp
!=
*
timestamp
)
{
free_fragment
(
data
);
av_log
(
ctx
,
AV_LOG_ERROR
,
"Invalid packet received
\n
"
);
return
AVERROR_INVALIDDATA
;
}
avio_write
(
data
->
fragment
,
buf
,
len
);
data
->
cur_size
+=
len
;
if
(
data
->
cur_size
<
data
->
adu_size
)
return
AVERROR
(
EAGAIN
);
err
=
ff_rtp_finalize_packet
(
pkt
,
&
data
->
fragment
,
st
->
index
);
if
(
err
<
0
)
{
av_log
(
ctx
,
AV_LOG_ERROR
,
"Error occurred when getting fragment buffer.
\n
"
);
return
err
;
}
return
0
;
}
RTPDynamicProtocolHandler
ff_mpeg_audio_robust_dynamic_handler
=
{
.
codec_type
=
AVMEDIA_TYPE_AUDIO
,
.
codec_id
=
AV_CODEC_ID_MP3ADU
,
.
init
=
mpa_robust_init
,
.
alloc
=
mpa_robust_new_context
,
.
free
=
mpa_robust_free_context
,
.
parse_packet
=
mpa_robust_parse_packet
,
.
enc_name
=
"mpa-robust"
,
};
libavformat/version.h
View file @
96084251
...
...
@@ -30,7 +30,7 @@
#include "libavutil/version.h"
#define LIBAVFORMAT_VERSION_MAJOR 56
#define LIBAVFORMAT_VERSION_MINOR 1
3
#define LIBAVFORMAT_VERSION_MINOR 1
4
#define LIBAVFORMAT_VERSION_MICRO 0
#define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_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