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
b4f32c42
Commit
b4f32c42
authored
Mar 21, 2016
by
Thomas Volkert
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
rtpdec: support for VC-2 HQ RTP payload format (draft v1)
parent
df34b700
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
232 additions
and
2 deletions
+232
-2
Changelog
Changelog
+1
-0
Makefile
libavformat/Makefile
+1
-0
rtpdec.c
libavformat/rtpdec.c
+2
-0
rtpdec_formats.h
libavformat/rtpdec_formats.h
+1
-0
rtpdec_vc2hq.c
libavformat/rtpdec_vc2hq.c
+225
-0
version.h
libavformat/version.h
+2
-2
No files found.
Changelog
View file @
b4f32c42
...
...
@@ -12,6 +12,7 @@ version <next>:
- ciescope filter
- protocol blacklisting API
- MediaCodec H264 decoding
- VC-2 HQ RTP payload format (draft v1) depacketizer
version 3.0:
...
...
libavformat/Makefile
View file @
b4f32c42
...
...
@@ -54,6 +54,7 @@ OBJS-$(CONFIG_RTPDEC) += rdt.o \
rtpdec_qdm2.o
\
rtpdec_qt.o
\
rtpdec_svq3.o
\
rtpdec_vc2hq.o
\
rtpdec_vp8.o
\
rtpdec_vp9.o
\
rtpdec_xiph.o
\
...
...
libavformat/rtpdec.c
View file @
b4f32c42
...
...
@@ -105,6 +105,7 @@ void ff_register_rtp_dynamic_payload_handlers(void)
ff_register_dynamic_payload_handler
(
&
ff_quicktime_rtp_vid_handler
);
ff_register_dynamic_payload_handler
(
&
ff_svq3_dynamic_handler
);
ff_register_dynamic_payload_handler
(
&
ff_theora_dynamic_handler
);
ff_register_dynamic_payload_handler
(
&
ff_vc2hq_dynamic_handler
);
ff_register_dynamic_payload_handler
(
&
ff_vorbis_dynamic_handler
);
ff_register_dynamic_payload_handler
(
&
ff_vp8_dynamic_handler
);
ff_register_dynamic_payload_handler
(
&
ff_vp9_dynamic_handler
);
...
...
@@ -713,6 +714,7 @@ static int enqueue_packet(RTPDemuxContext *s, uint8_t *buf, int len)
packet
->
next
=
*
cur
;
*
cur
=
packet
;
s
->
queue_len
++
;
av_log
(
0
,
AV_LOG_ERROR
,
"queue: %d
\n
"
,
s
->
queue_len
);
return
0
;
}
...
...
libavformat/rtpdec_formats.h
View file @
b4f32c42
...
...
@@ -80,6 +80,7 @@ extern RTPDynamicProtocolHandler ff_quicktime_rtp_aud_handler;
extern
RTPDynamicProtocolHandler
ff_quicktime_rtp_vid_handler
;
extern
RTPDynamicProtocolHandler
ff_svq3_dynamic_handler
;
extern
RTPDynamicProtocolHandler
ff_theora_dynamic_handler
;
extern
RTPDynamicProtocolHandler
ff_vc2hq_dynamic_handler
;
extern
RTPDynamicProtocolHandler
ff_vorbis_dynamic_handler
;
extern
RTPDynamicProtocolHandler
ff_vp8_dynamic_handler
;
extern
RTPDynamicProtocolHandler
ff_vp9_dynamic_handler
;
...
...
libavformat/rtpdec_vc2hq.c
0 → 100644
View file @
b4f32c42
/*
* RTP parser for VC-2 HQ payload format (draft version 1) - experimental
* Copyright (c) 2016 Thomas Volkert <thomas@netzeal.de>
*
* 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 "libavutil/intreadwrite.h"
#include "libavcodec/dirac.h"
#include "avio_internal.h"
#include "rtpdec_formats.h"
#define RTP_VC2HQ_PL_HEADER_SIZE 4
#define DIRAC_DATA_UNIT_HEADER_SIZE 13
#define DIRAC_PIC_NR_SIZE 4
#define DIRAC_RTP_PCODE_HQ_PIC_FRAGMENT 0xEC
struct
PayloadContext
{
AVIOContext
*
buf
;
uint32_t
frame_size
;
uint32_t
frame_nr
;
uint32_t
timestamp
;
uint32_t
last_unit_size
;
int
seen_sequence_header
;
};
static
const
uint8_t
start_sequence
[]
=
{
'B'
,
'B'
,
'C'
,
'D'
};
static
void
fill_parse_info_header
(
PayloadContext
*
pl_ctx
,
uint8_t
*
buf
,
uint8_t
parse_code
,
uint32_t
data_unit_size
)
{
memcpy
(
buf
,
start_sequence
,
sizeof
(
start_sequence
));
buf
[
4
]
=
parse_code
;
AV_WB32
(
&
buf
[
5
],
data_unit_size
);
AV_WB32
(
&
buf
[
9
],
pl_ctx
->
last_unit_size
);
pl_ctx
->
last_unit_size
=
data_unit_size
;
}
static
int
vc2hq_handle_sequence_header
(
PayloadContext
*
pl_ctx
,
AVStream
*
st
,
AVPacket
*
pkt
,
const
uint8_t
*
buf
,
int
len
)
{
int
res
;
uint32_t
size
=
DIRAC_DATA_UNIT_HEADER_SIZE
+
len
;
if
((
res
=
av_new_packet
(
pkt
,
DIRAC_DATA_UNIT_HEADER_SIZE
+
len
))
<
0
)
return
res
;
fill_parse_info_header
(
pl_ctx
,
pkt
->
data
,
0x00
,
size
);
/* payload of seq. header */
memcpy
(
pkt
->
data
+
DIRAC_DATA_UNIT_HEADER_SIZE
,
buf
,
len
);
pkt
->
stream_index
=
st
->
index
;
pl_ctx
->
seen_sequence_header
=
1
;
return
0
;
}
static
int
vc2hq_mark_end_of_sequence
(
PayloadContext
*
pl_ctx
,
AVStream
*
st
,
AVPacket
*
pkt
)
{
int
res
;
uint32_t
size
=
0
;
/* create A/V packet */
if
((
res
=
av_new_packet
(
pkt
,
DIRAC_DATA_UNIT_HEADER_SIZE
))
<
0
)
return
res
;
fill_parse_info_header
(
pl_ctx
,
pkt
->
data
,
0x10
,
size
);
pkt
->
stream_index
=
st
->
index
;
pl_ctx
->
seen_sequence_header
=
0
;
return
0
;
}
static
int
vc2hq_handle_frame_fragment
(
AVFormatContext
*
ctx
,
PayloadContext
*
pl_ctx
,
AVStream
*
st
,
AVPacket
*
pkt
,
uint32_t
*
timestamp
,
const
uint8_t
*
buf
,
int
len
,
int
flags
)
{
int
res
;
uint32_t
pic_nr
;
uint16_t
frag_len
;
uint16_t
no_slices
;
/* sanity check for size of input packet: 16 bytes header in any case as minimum */
if
(
len
<
16
)
{
av_log
(
ctx
,
AV_LOG_ERROR
,
"Too short RTP/VC2hq packet, got %d bytes
\n
"
,
len
);
return
AVERROR_INVALIDDATA
;
}
pic_nr
=
AV_RB32
(
&
buf
[
4
]);
frag_len
=
AV_RB16
(
&
buf
[
12
]);
no_slices
=
AV_RB16
(
&
buf
[
14
]);
if
(
pl_ctx
->
buf
&&
pl_ctx
->
frame_nr
!=
pic_nr
)
{
av_log
(
ctx
,
AV_LOG_WARNING
,
"Dropping buffered RTP/VC2hq packet fragments - non-continuous picture numbers
\n
"
);
ffio_free_dyn_buf
(
&
pl_ctx
->
buf
);
}
/* transform parameters? */
if
(
no_slices
==
0
)
{
if
(
len
<
frag_len
+
16
)
{
av_log
(
ctx
,
AV_LOG_ERROR
,
"Too short RTP/VC2hq packet, got %d bytes
\n
"
,
len
);
return
AVERROR_INVALIDDATA
;
}
/* start frame buffering with new dynamic buffer */
if
(
!
pl_ctx
->
buf
)
{
res
=
avio_open_dyn_buf
(
&
pl_ctx
->
buf
);
if
(
res
<
0
)
return
res
;
/* reserve memory for frame header */
res
=
avio_seek
(
pl_ctx
->
buf
,
DIRAC_DATA_UNIT_HEADER_SIZE
+
DIRAC_PIC_NR_SIZE
,
SEEK_SET
);
if
(
res
<
0
)
return
res
;
pl_ctx
->
frame_nr
=
pic_nr
;
pl_ctx
->
timestamp
=
*
timestamp
;
pl_ctx
->
frame_size
=
DIRAC_DATA_UNIT_HEADER_SIZE
+
DIRAC_PIC_NR_SIZE
;
}
avio_write
(
pl_ctx
->
buf
,
buf
+
16
/* skip pl header */
,
frag_len
);
pl_ctx
->
frame_size
+=
frag_len
;
return
AVERROR
(
EAGAIN
);
}
else
{
if
(
len
<
frag_len
+
20
)
{
av_log
(
ctx
,
AV_LOG_ERROR
,
"Too short RTP/VC2hq packet, got %d bytes
\n
"
,
len
);
return
AVERROR_INVALIDDATA
;
}
/* transform parameters were missed, no buffer available */
if
(
!
pl_ctx
->
buf
)
return
AVERROR_INVALIDDATA
;
avio_write
(
pl_ctx
->
buf
,
buf
+
20
/* skip pl header */
,
frag_len
);
pl_ctx
->
frame_size
+=
frag_len
;
/* RTP marker bit means: last fragment of current frame was received;
otherwise, an additional fragment is needed for the current frame */
if
(
!
(
flags
&
RTP_FLAG_MARKER
))
return
AVERROR
(
EAGAIN
);
}
/* close frame buffering and create A/V packet */
res
=
ff_rtp_finalize_packet
(
pkt
,
&
pl_ctx
->
buf
,
st
->
index
);
if
(
res
<
0
)
return
res
;
fill_parse_info_header
(
pl_ctx
,
pkt
->
data
,
0xE8
,
pl_ctx
->
frame_size
);
AV_WB32
(
&
pkt
->
data
[
13
],
pl_ctx
->
frame_nr
);
pl_ctx
->
frame_size
=
0
;
return
0
;
}
static
int
vc2hq_handle_packet
(
AVFormatContext
*
ctx
,
PayloadContext
*
pl_ctx
,
AVStream
*
st
,
AVPacket
*
pkt
,
uint32_t
*
timestamp
,
const
uint8_t
*
buf
,
int
len
,
uint16_t
seq
,
int
flags
)
{
uint8_t
parse_code
=
0
;
int
res
=
0
;
if
(
pl_ctx
->
buf
&&
pl_ctx
->
timestamp
!=
*
timestamp
)
{
av_log
(
ctx
,
AV_LOG_WARNING
,
"Dropping buffered RTP/VC2hq packet fragments - non-continuous timestamps
\n
"
);
ffio_free_dyn_buf
(
&
pl_ctx
->
buf
);
pl_ctx
->
frame_size
=
0
;
}
/* sanity check for size of input packet: needed header data as minimum */
if
(
len
<
RTP_VC2HQ_PL_HEADER_SIZE
)
{
av_log
(
ctx
,
AV_LOG_ERROR
,
"Too short RTP/VC2hq packet, got %d bytes
\n
"
,
len
);
return
AVERROR_INVALIDDATA
;
}
parse_code
=
buf
[
3
];
/* wait for next sequence header? */
if
(
pl_ctx
->
seen_sequence_header
||
parse_code
==
DIRAC_PCODE_SEQ_HEADER
)
{
switch
(
parse_code
)
{
/* sequence header */
case
DIRAC_PCODE_SEQ_HEADER
:
res
=
vc2hq_handle_sequence_header
(
pl_ctx
,
st
,
pkt
,
buf
+
RTP_VC2HQ_PL_HEADER_SIZE
,
len
-
RTP_VC2HQ_PL_HEADER_SIZE
);
break
;
/* end of sequence */
case
DIRAC_PCODE_END_SEQ
:
res
=
vc2hq_mark_end_of_sequence
(
pl_ctx
,
st
,
pkt
);
break
;
/* HQ picture fragment */
case
DIRAC_RTP_PCODE_HQ_PIC_FRAGMENT
:
res
=
vc2hq_handle_frame_fragment
(
ctx
,
pl_ctx
,
st
,
pkt
,
timestamp
,
buf
,
len
,
flags
);
break
;
}
}
return
res
;
}
RTPDynamicProtocolHandler
ff_vc2hq_dynamic_handler
=
{
.
enc_name
=
"VC2"
,
.
codec_type
=
AVMEDIA_TYPE_VIDEO
,
.
codec_id
=
AV_CODEC_ID_DIRAC
,
.
priv_data_size
=
sizeof
(
PayloadContext
),
.
parse_packet
=
vc2hq_handle_packet
};
libavformat/version.h
View file @
b4f32c42
...
...
@@ -30,8 +30,8 @@
#include "libavutil/version.h"
#define LIBAVFORMAT_VERSION_MAJOR 57
#define LIBAVFORMAT_VERSION_MINOR 2
8
#define LIBAVFORMAT_VERSION_MICRO 10
2
#define LIBAVFORMAT_VERSION_MINOR 2
9
#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