Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
小白菜888
Ffmpeg
提交
50a4d5cf
F
Ffmpeg
项目概览
小白菜888
/
Ffmpeg
通知
3
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
F
Ffmpeg
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
50a4d5cf
编写于
8月 23, 2014
作者:
T
ThomasVolkert
提交者:
Michael Niedermayer
8月 24, 2014
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Add support for H.261 RTP payload format (RFC 4587)
上级
ab1e4312
变更
9
隐藏空白更改
内联
并排
Showing
9 changed file
with
279 addition
and
0 deletion
+279
-0
MAINTAINERS
MAINTAINERS
+1
-0
libavcodec/mpegvideo_enc.c
libavcodec/mpegvideo_enc.c
+3
-0
libavformat/Makefile
libavformat/Makefile
+2
-0
libavformat/rtpdec.c
libavformat/rtpdec.c
+1
-0
libavformat/rtpdec_formats.h
libavformat/rtpdec_formats.h
+5
-0
libavformat/rtpdec_h261.c
libavformat/rtpdec_h261.c
+205
-0
libavformat/rtpenc.c
libavformat/rtpenc.c
+4
-0
libavformat/rtpenc.h
libavformat/rtpenc.h
+1
-0
libavformat/rtpenc_h261.c
libavformat/rtpenc_h261.c
+57
-0
未找到文件。
MAINTAINERS
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
;
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录