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
50a4d5cf
Commit
50a4d5cf
authored
Aug 23, 2014
by
ThomasVolkert
Committed by
Michael Niedermayer
Aug 24, 2014
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add support for H.261 RTP payload format (RFC 4587)
parent
ab1e4312
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
279 additions
and
0 deletions
+279
-0
MAINTAINERS
MAINTAINERS
+1
-0
mpegvideo_enc.c
libavcodec/mpegvideo_enc.c
+3
-0
Makefile
libavformat/Makefile
+2
-0
rtpdec.c
libavformat/rtpdec.c
+1
-0
rtpdec_formats.h
libavformat/rtpdec_formats.h
+5
-0
rtpdec_h261.c
libavformat/rtpdec_h261.c
+205
-0
rtpenc.c
libavformat/rtpenc.c
+4
-0
rtpenc.h
libavformat/rtpenc.h
+1
-0
rtpenc_h261.c
libavformat/rtpenc_h261.c
+57
-0
No files found.
MAINTAINERS
View file @
50a4d5cf
...
...
@@ -459,6 +459,7 @@ Muxers/Demuxers:
rmdec.c, rmenc.c Ronald S. Bultje, Kostya Shishkov
rtmp* Kostya Shishkov
rtp.c, rtpenc.c Martin Storsjo
rtpdec_h261.*, rtpenc_h261.* Thomas Volkert
rtpdec_asf.* Ronald S. Bultje
rtpenc_mpv.*, rtpenc_aac.* Martin Storsjo
rtsp.c Luca Barbato
...
...
libavcodec/mpegvideo_enc.c
View file @
50a4d5cf
...
...
@@ -2800,6 +2800,9 @@ static int encode_thread(AVCodecContext *c, void *arg){
if
(
s
->
start_mb_y
==
mb_y
&&
mb_y
>
0
&&
mb_x
==
0
)
is_gob_start
=
1
;
switch
(
s
->
codec_id
){
case
AV_CODEC_ID_H261
:
is_gob_start
=
0
;
//FIXME
break
;
case
AV_CODEC_ID_H263
:
case
AV_CODEC_ID_H263P
:
if
(
!
s
->
h263_slice_structured
)
...
...
libavformat/Makefile
View file @
50a4d5cf
...
...
@@ -33,6 +33,7 @@ OBJS-$(CONFIG_RTPDEC) += rdt.o \
rtpdec_amr.o
\
rtpdec_asf.o
\
rtpdec_g726.o
\
rtpdec_h261.o
\
rtpdec_h263.o
\
rtpdec_h263_rfc2190.o
\
rtpdec_h264.o
\
...
...
@@ -362,6 +363,7 @@ OBJS-$(CONFIG_RTP_MUXER) += rtp.o \
rtpenc_aac.o
\
rtpenc_latm.o
\
rtpenc_amr.o
\
rtpenc_h261.o
\
rtpenc_h263.o
\
rtpenc_h263_rfc2190.o
\
rtpenc_jpeg.o
\
...
...
libavformat/rtpdec.c
View file @
50a4d5cf
...
...
@@ -72,6 +72,7 @@ void ff_register_rtp_dynamic_payload_handlers(void)
ff_register_dynamic_payload_handler
(
&
ff_g726_24_dynamic_handler
);
ff_register_dynamic_payload_handler
(
&
ff_g726_32_dynamic_handler
);
ff_register_dynamic_payload_handler
(
&
ff_g726_40_dynamic_handler
);
ff_register_dynamic_payload_handler
(
&
ff_h261_dynamic_handler
);
ff_register_dynamic_payload_handler
(
&
ff_h263_1998_dynamic_handler
);
ff_register_dynamic_payload_handler
(
&
ff_h263_2000_dynamic_handler
);
ff_register_dynamic_payload_handler
(
&
ff_h263_rfc2190_dynamic_handler
);
...
...
libavformat/rtpdec_formats.h
View file @
50a4d5cf
...
...
@@ -31,6 +31,10 @@
*/
int
ff_wms_parse_sdp_a_line
(
AVFormatContext
*
s
,
const
char
*
p
);
int
ff_h261_handle_packet
(
AVFormatContext
*
ctx
,
PayloadContext
*
data
,
AVStream
*
st
,
AVPacket
*
pkt
,
uint32_t
*
timestamp
,
const
uint8_t
*
buf
,
int
len
,
uint16_t
seq
,
int
flags
);
int
ff_h263_handle_packet
(
AVFormatContext
*
ctx
,
PayloadContext
*
data
,
AVStream
*
st
,
AVPacket
*
pkt
,
uint32_t
*
timestamp
,
const
uint8_t
*
buf
,
int
len
,
uint16_t
seq
,
int
flags
);
...
...
@@ -41,6 +45,7 @@ extern RTPDynamicProtocolHandler ff_g726_16_dynamic_handler;
extern
RTPDynamicProtocolHandler
ff_g726_24_dynamic_handler
;
extern
RTPDynamicProtocolHandler
ff_g726_32_dynamic_handler
;
extern
RTPDynamicProtocolHandler
ff_g726_40_dynamic_handler
;
extern
RTPDynamicProtocolHandler
ff_h261_dynamic_handler
;
extern
RTPDynamicProtocolHandler
ff_h263_1998_dynamic_handler
;
extern
RTPDynamicProtocolHandler
ff_h263_2000_dynamic_handler
;
extern
RTPDynamicProtocolHandler
ff_h263_rfc2190_dynamic_handler
;
...
...
libavformat/rtpdec_h261.c
0 → 100644
View file @
50a4d5cf
/*
* RTP parser for H.261 payload format (RFC 4587)
* Copyright (c) 2014 Thomas Volkert <thomas@homer-conferencing.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 "avformat.h"
#include "rtpdec_formats.h"
#include "libavcodec/get_bits.h"
#define RTP_H261_PAYLOAD_HEADER_SIZE 4
struct
PayloadContext
{
AVIOContext
*
buf
;
uint8_t
endbyte
;
int
endbyte_bits
;
uint32_t
timestamp
;
};
static
PayloadContext
*
h261_new_context
(
void
)
{
return
av_mallocz
(
sizeof
(
PayloadContext
));
}
static
void
h261_free_dyn_buffer
(
AVIOContext
**
dyn_buf
)
{
uint8_t
*
ptr_dyn_buffer
;
avio_close_dyn_buf
(
*
dyn_buf
,
&
ptr_dyn_buffer
);
av_free
(
ptr_dyn_buffer
);
*
dyn_buf
=
NULL
;
}
static
void
h261_free_context
(
PayloadContext
*
pl_ctx
)
{
/* return if context is invalid */
if
(
!
pl_ctx
)
return
;
/* free buffer if it is valid */
if
(
pl_ctx
->
buf
)
{
h261_free_dyn_buffer
(
&
pl_ctx
->
buf
);
}
/* free context */
av_free
(
pl_ctx
);
}
static
av_cold
int
h261_init
(
AVFormatContext
*
ctx
,
int
st_index
,
PayloadContext
*
data
)
{
//av_log(ctx, AV_LOG_DEBUG, "h261_init() for stream %d\n", st_index);
if
(
st_index
<
0
)
return
0
;
ctx
->
streams
[
st_index
]
->
need_parsing
=
AVSTREAM_PARSE_FULL
;
return
0
;
}
int
ff_h261_handle_packet
(
AVFormatContext
*
ctx
,
PayloadContext
*
data
,
AVStream
*
st
,
AVPacket
*
pkt
,
uint32_t
*
timestamp
,
const
uint8_t
*
buf
,
int
len
,
uint16_t
seq
,
int
flags
)
{
int
sbit
,
ebit
,
gobn
,
mbap
,
quant
;
int
res
;
//av_log(ctx, AV_LOG_DEBUG, "got h261 RTP packet with time: %u\n", timestamp);
/* drop data of previous packets in case of non-continuous (loss) packet stream */
if
(
data
->
buf
&&
data
->
timestamp
!=
*
timestamp
)
{
h261_free_dyn_buffer
(
&
data
->
buf
);
}
/* sanity check for size of input packet */
if
(
len
<
5
/* 4 bytes header and 1 byte payload at least */
)
{
av_log
(
ctx
,
AV_LOG_ERROR
,
"Too short H.261 RTP packet
\n
"
);
return
AVERROR_INVALIDDATA
;
}
/*
decode the H.261 payload header according to section 4.1 of RFC 4587:
(uses 4 bytes between RTP header and H.261 stream per packet)
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|SBIT |EBIT |I|V| GOBN | MBAP | QUANT | HMVD | VMVD |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Start bit position (SBIT): 3 bits
End bit position (EBIT): 3 bits
INTRA-frame encoded data (I): 1 bit
Motion Vector flag (V): 1 bit
GOB number (GOBN): 4 bits
Macroblock address predictor (MBAP): 5 bits
Quantizer (QUANT): 5 bits
Horizontal motion vector data (HMVD): 5 bits
Vertical motion vector data (VMVD): 5 bits
*/
sbit
=
(
buf
[
0
]
>>
5
)
&
0x07
;
ebit
=
(
buf
[
0
]
>>
2
)
&
0x07
;
gobn
=
(
buf
[
1
]
>>
4
)
&
0x0f
;
mbap
=
((
buf
[
1
]
<<
1
)
&
0x1e
)
|
((
buf
[
1
]
>>
7
)
&
0x01
);
quant
=
(
buf
[
1
]
>>
4
)
&
0x0f
;
/* pass the H.261 payload header and continue with the actual payload */
buf
+=
RTP_H261_PAYLOAD_HEADER_SIZE
;
len
-=
RTP_H261_PAYLOAD_HEADER_SIZE
;
/* start frame buffering with new dynamic buffer */
if
(
!
data
->
buf
)
{
/* sanity check: a new frame starts with gobn=0, sbit=0, mbap=0, uqnat=0 */
if
(
!
gobn
&&
!
sbit
&&
!
mbap
&&
!
quant
){
res
=
avio_open_dyn_buf
(
&
data
->
buf
);
if
(
res
<
0
)
return
res
;
/* update the timestamp in the frame packet with the one from the RTP packet */
data
->
timestamp
=
*
timestamp
;
}
else
{
/* frame not started yet, need more packets */
return
AVERROR
(
EAGAIN
);
}
}
/* do the "byte merging" at the boundaries of two consecutive frame fragments */
if
(
data
->
endbyte_bits
||
sbit
)
{
if
(
data
->
endbyte_bits
==
sbit
)
{
data
->
endbyte
|=
buf
[
0
]
&
(
0xff
>>
sbit
);
data
->
endbyte_bits
=
0
;
buf
++
;
len
--
;
avio_w8
(
data
->
buf
,
data
->
endbyte
);
}
else
{
/* ebit/sbit values inconsistent, assuming packet loss */
GetBitContext
gb
;
init_get_bits
(
&
gb
,
buf
,
len
*
8
-
ebit
);
skip_bits
(
&
gb
,
sbit
);
if
(
data
->
endbyte_bits
)
{
data
->
endbyte
|=
get_bits
(
&
gb
,
8
-
data
->
endbyte_bits
);
avio_w8
(
data
->
buf
,
data
->
endbyte
);
}
while
(
get_bits_left
(
&
gb
)
>=
8
)
avio_w8
(
data
->
buf
,
get_bits
(
&
gb
,
8
));
data
->
endbyte_bits
=
get_bits_left
(
&
gb
);
if
(
data
->
endbyte_bits
)
data
->
endbyte
=
get_bits
(
&
gb
,
data
->
endbyte_bits
)
<<
(
8
-
data
->
endbyte_bits
);
ebit
=
0
;
len
=
0
;
}
}
if
(
ebit
)
{
if
(
len
>
0
)
avio_write
(
data
->
buf
,
buf
,
len
-
1
);
data
->
endbyte_bits
=
8
-
ebit
;
data
->
endbyte
=
buf
[
len
-
1
]
&
(
0xff
<<
ebit
);
}
else
{
avio_write
(
data
->
buf
,
buf
,
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
);
/* write the completed last byte from the "byte merging" */
if
(
data
->
endbyte_bits
)
avio_w8
(
data
->
buf
,
data
->
endbyte
);
data
->
endbyte_bits
=
0
;
/* close frame buffering and create resulting A/V packet */
res
=
ff_rtp_finalize_packet
(
pkt
,
&
data
->
buf
,
st
->
index
);
if
(
res
<
0
)
return
res
;
return
0
;
}
RTPDynamicProtocolHandler
ff_h261_dynamic_handler
=
{
.
enc_name
=
"H261"
,
.
codec_type
=
AVMEDIA_TYPE_VIDEO
,
.
codec_id
=
AV_CODEC_ID_H261
,
.
init
=
h261_init
,
.
parse_packet
=
ff_h261_handle_packet
,
.
alloc
=
h261_new_context
,
.
free
=
h261_free_context
,
.
static_payload_id
=
31
,
};
libavformat/rtpenc.c
View file @
50a4d5cf
...
...
@@ -49,6 +49,7 @@ static const AVClass rtp_muxer_class = {
static
int
is_supported
(
enum
AVCodecID
id
)
{
switch
(
id
)
{
case
AV_CODEC_ID_H261
:
case
AV_CODEC_ID_H263
:
case
AV_CODEC_ID_H263P
:
case
AV_CODEC_ID_H264
:
...
...
@@ -556,6 +557,9 @@ static int rtp_write_packet(AVFormatContext *s1, AVPacket *pkt)
case
AV_CODEC_ID_H264
:
ff_rtp_send_h264
(
s1
,
pkt
->
data
,
size
);
break
;
case
AV_CODEC_ID_H261
:
ff_rtp_send_h261
(
s1
,
pkt
->
data
,
size
);
break
;
case
AV_CODEC_ID_H263
:
if
(
s
->
flags
&
FF_RTP_FLAG_RFC2190
)
{
int
mb_info_size
=
0
;
...
...
libavformat/rtpenc.h
View file @
50a4d5cf
...
...
@@ -81,6 +81,7 @@ typedef struct RTPMuxContext RTPMuxContext;
void
ff_rtp_send_data
(
AVFormatContext
*
s1
,
const
uint8_t
*
buf1
,
int
len
,
int
m
);
void
ff_rtp_send_h264
(
AVFormatContext
*
s1
,
const
uint8_t
*
buf1
,
int
size
);
void
ff_rtp_send_h261
(
AVFormatContext
*
s1
,
const
uint8_t
*
buf1
,
int
size
);
void
ff_rtp_send_h263
(
AVFormatContext
*
s1
,
const
uint8_t
*
buf1
,
int
size
);
void
ff_rtp_send_h263_rfc2190
(
AVFormatContext
*
s1
,
const
uint8_t
*
buf1
,
int
size
,
const
uint8_t
*
mb_info
,
int
mb_info_size
);
...
...
libavformat/rtpenc_h261.c
0 → 100644
View file @
50a4d5cf
/*
* RTP packetization for H.261 video (RFC 4587)
* Copyright (c) 2014 Thomas Volkert <thomas@homer-conferencing.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 "avformat.h"
#include "rtpenc.h"
void
ff_rtp_send_h261
(
AVFormatContext
*
s1
,
const
uint8_t
*
frame_buf
,
int
frame_size
)
{
RTPMuxContext
*
rtp_ctx
=
s1
->
priv_data
;
int
processed_frame_size
;
int
last_packet_of_frame
;
uint8_t
*
tmp_buf_ptr
;
/* use the default 90 KHz time stamp */
rtp_ctx
->
timestamp
=
rtp_ctx
->
cur_timestamp
;
/* continue as long as not all frame data is processed */
while
(
frame_size
>
0
)
{
tmp_buf_ptr
=
rtp_ctx
->
buf
;
*
tmp_buf_ptr
++
=
1
;
/* V=1 */
*
tmp_buf_ptr
++
=
0
;
*
tmp_buf_ptr
++
=
0
;
*
tmp_buf_ptr
++
=
0
;
processed_frame_size
=
FFMIN
(
rtp_ctx
->
max_payload_size
-
4
,
frame_size
);
//XXX: parse the h.261 bitstream and improve frame splitting here
last_packet_of_frame
=
(
processed_frame_size
==
frame_size
);
memcpy
(
tmp_buf_ptr
,
frame_buf
,
processed_frame_size
);
tmp_buf_ptr
+=
processed_frame_size
;
ff_rtp_send_data
(
s1
,
rtp_ctx
->
buf
,
tmp_buf_ptr
-
rtp_ctx
->
buf
,
last_packet_of_frame
);
frame_buf
+=
processed_frame_size
;
frame_size
-=
processed_frame_size
;
}
}
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