Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
小白菜888
Ffmpeg
提交
7000a175
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,发现更多精彩内容 >>
提交
7000a175
编写于
10月 03, 2004
作者:
M
Michael Niedermayer
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
SCR timestamp fix try #1
Originally committed as revision 3550 to
svn://svn.ffmpeg.org/ffmpeg/trunk
上级
d8b5abfa
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
285 addition
and
71 deletion
+285
-71
libavformat/avformat.h
libavformat/avformat.h
+1
-0
libavformat/mpeg.c
libavformat/mpeg.c
+254
-69
libavformat/utils.c
libavformat/utils.c
+28
-0
tests/libav.regression.ref
tests/libav.regression.ref
+2
-2
未找到文件。
libavformat/avformat.h
浏览文件 @
7000a175
...
...
@@ -524,6 +524,7 @@ void fifo_free(FifoBuffer *f);
int
fifo_size
(
FifoBuffer
*
f
,
uint8_t
*
rptr
);
int
fifo_read
(
FifoBuffer
*
f
,
uint8_t
*
buf
,
int
buf_size
,
uint8_t
**
rptr_ptr
);
void
fifo_write
(
FifoBuffer
*
f
,
uint8_t
*
buf
,
int
size
,
uint8_t
**
wptr_ptr
);
int
put_fifo
(
ByteIOContext
*
pb
,
FifoBuffer
*
f
,
int
buf_size
,
uint8_t
**
rptr_ptr
);
/* media file input */
AVInputFormat
*
av_find_input_format
(
const
char
*
short_name
);
...
...
libavformat/mpeg.c
浏览文件 @
7000a175
...
...
@@ -19,18 +19,29 @@
#include "avformat.h"
#define MAX_PAYLOAD_SIZE 4096
#define PRELOAD 45000 //0.5sec
//#define DEBUG_SEEK
#undef NDEBUG
#include <assert.h>
typedef
struct
PacketDesc
{
int64_t
pts
;
int64_t
dts
;
int
size
;
int
unwritten_size
;
int
flags
;
struct
PacketDesc
*
next
;
}
PacketDesc
;
typedef
struct
{
uint8_t
buffer
[
MAX_PAYLOAD_SIZE
];
int
buffer_ptr
;
int
nb_frames
;
/* number of starting frame encountered (AC3) */
int
frame_start_offset
;
/* starting offset of the frame + 1 (0 if none) */
FifoBuffer
fifo
;
uint8_t
id
;
int
max_buffer_size
;
/* in bytes */
int
buffer_index
;
PacketDesc
*
predecode_packet
;
PacketDesc
*
premux_packet
;
PacketDesc
**
next_packet
;
int
packet_number
;
int64_t
start_pts
;
int64_t
start_dts
;
...
...
@@ -51,8 +62,6 @@ typedef struct {
int
is_mpeg2
;
int
is_vcd
;
int
is_svcd
;
int
scr_stream_index
;
/* stream from which the system clock is
computed (VBR case) */
int64_t
last_scr
;
/* current system clock */
double
vcd_padding_bitrate
;
//FIXME floats
...
...
@@ -127,7 +136,7 @@ static int put_pack_header(AVFormatContext *ctx,
static
int
put_system_header
(
AVFormatContext
*
ctx
,
uint8_t
*
buf
,
int
only_for_stream_id
)
{
MpegMuxContext
*
s
=
ctx
->
priv_data
;
int
size
,
rate_bound
,
i
,
private_stream_coded
,
id
;
int
size
,
i
,
private_stream_coded
,
id
;
PutBitContext
pb
;
init_put_bits
(
&
pb
,
buf
,
128
);
...
...
@@ -136,8 +145,7 @@ static int put_system_header(AVFormatContext *ctx, uint8_t *buf,int only_for_str
put_bits
(
&
pb
,
16
,
0
);
put_bits
(
&
pb
,
1
,
1
);
rate_bound
=
s
->
mux_rate
;
/* maximum bit rate of the multiplexed stream */
put_bits
(
&
pb
,
22
,
rate_bound
);
put_bits
(
&
pb
,
22
,
s
->
mux_rate
);
/* maximum bit rate of the multiplexed stream */
put_bits
(
&
pb
,
1
,
1
);
/* marker */
if
(
s
->
is_vcd
&&
only_for_stream_id
==
VIDEO_ID
)
{
/* This header applies only to the video stream (see VCD standard p. IV-7)*/
...
...
@@ -262,7 +270,6 @@ static int mpeg_mux_init(AVFormatContext *ctx)
dts_id
=
DTS_ID
;
mpv_id
=
VIDEO_ID
;
lpcm_id
=
LPCM_ID
;
s
->
scr_stream_index
=
-
1
;
for
(
i
=
0
;
i
<
ctx
->
nb_streams
;
i
++
)
{
st
=
ctx
->
streams
[
i
];
stream
=
av_mallocz
(
sizeof
(
StreamInfo
));
...
...
@@ -300,9 +307,6 @@ static int mpeg_mux_init(AVFormatContext *ctx)
s
->
audio_bound
++
;
break
;
case
CODEC_TYPE_VIDEO
:
/* by default, video is used for the SCR computation */
if
(
s
->
scr_stream_index
==
-
1
)
s
->
scr_stream_index
=
i
;
stream
->
id
=
mpv_id
++
;
if
(
s
->
is_vcd
)
/* see VCD standard, p. IV-7*/
...
...
@@ -316,24 +320,31 @@ static int mpeg_mux_init(AVFormatContext *ctx)
default:
return
-
1
;
}
fifo_init
(
&
stream
->
fifo
,
2
*
stream
->
max_buffer_size
+
100
*
MAX_PAYLOAD_SIZE
);
//FIXME think about the size maybe dynamically realloc
stream
->
next_packet
=
&
stream
->
premux_packet
;
}
/* if no SCR, use first stream (audio) */
if
(
s
->
scr_stream_index
==
-
1
)
s
->
scr_stream_index
=
0
;
bitrate
=
0
;
audio_bitrate
=
0
;
video_bitrate
=
0
;
for
(
i
=
0
;
i
<
ctx
->
nb_streams
;
i
++
)
{
int
codec_rate
;
st
=
ctx
->
streams
[
i
];
stream
=
(
StreamInfo
*
)
st
->
priv_data
;
bitrate
+=
st
->
codec
.
bit_rate
;
if
(
st
->
codec
.
rc_max_rate
||
stream
->
id
==
VIDEO_ID
)
codec_rate
=
st
->
codec
.
rc_max_rate
;
else
codec_rate
=
st
->
codec
.
bit_rate
;
if
(
!
codec_rate
)
codec_rate
=
(
1
<<
21
)
*
8
*
50
/
ctx
->
nb_streams
;
bitrate
+=
codec_rate
;
if
(
stream
->
id
==
AUDIO_ID
)
audio_bitrate
+=
st
->
codec
.
bit
_rate
;
audio_bitrate
+=
codec
_rate
;
else
if
(
stream
->
id
==
VIDEO_ID
)
video_bitrate
+=
st
->
codec
.
bit
_rate
;
video_bitrate
+=
codec
_rate
;
}
if
(
s
->
is_vcd
)
{
...
...
@@ -367,7 +378,8 @@ static int mpeg_mux_init(AVFormatContext *ctx)
}
else
{
/* we increase slightly the bitrate to take into account the
headers. XXX: compute it exactly */
bitrate
+=
2000
;
bitrate
+=
bitrate
*
5
/
100
;
bitrate
+=
10000
;
s
->
mux_rate
=
(
bitrate
+
(
8
*
50
)
-
1
)
/
(
8
*
50
);
}
...
...
@@ -395,7 +407,6 @@ static int mpeg_mux_init(AVFormatContext *ctx)
for
(
i
=
0
;
i
<
ctx
->
nb_streams
;
i
++
)
{
stream
=
ctx
->
streams
[
i
]
->
priv_data
;
stream
->
buffer_ptr
=
0
;
stream
->
packet_number
=
0
;
stream
->
start_pts
=
AV_NOPTS_VALUE
;
stream
->
start_dts
=
AV_NOPTS_VALUE
;
...
...
@@ -432,7 +443,7 @@ static int get_vcd_padding_size(AVFormatContext *ctx, int64_t pts)
{
int64_t
full_pad_bytes
;
full_pad_bytes
=
(
int64_t
)((
s
->
vcd_padding_bitrate
*
(
pts
/
90000
.
0
))
/
8
.
0
);
full_pad_bytes
=
(
int64_t
)((
s
->
vcd_padding_bitrate
*
(
pts
/
90000
.
0
))
/
8
.
0
);
//FIXME this is wrong
pad_bytes
=
(
int
)
(
full_pad_bytes
-
s
->
vcd_padding_bytes_written
);
if
(
pad_bytes
<
0
)
...
...
@@ -547,10 +558,23 @@ static void put_padding_packet(AVFormatContext *ctx, ByteIOContext *pb,int packe
put_byte
(
pb
,
0xff
);
}
static
int
get_nb_frames
(
AVFormatContext
*
ctx
,
StreamInfo
*
stream
,
int
len
){
int
nb_frames
=
0
;
PacketDesc
*
pkt_desc
=
stream
->
premux_packet
;
while
(
len
>
0
){
if
(
pkt_desc
->
size
==
pkt_desc
->
unwritten_size
)
nb_frames
++
;
len
-=
pkt_desc
->
unwritten_size
;
pkt_desc
=
pkt_desc
->
next
;
}
return
nb_frames
;
}
/* flush the packet on stream stream_index */
static
void
flush_packet
(
AVFormatContext
*
ctx
,
int
stream_index
,
int64_t
pts
,
int64_t
dts
,
int64_t
scr
)
static
int
flush_packet
(
AVFormatContext
*
ctx
,
int
stream_index
,
int64_t
pts
,
int64_t
dts
,
int64_t
scr
,
int
trailer_size
)
{
MpegMuxContext
*
s
=
ctx
->
priv_data
;
StreamInfo
*
stream
=
ctx
->
streams
[
stream_index
]
->
priv_data
;
...
...
@@ -562,6 +586,7 @@ static void flush_packet(AVFormatContext *ctx, int stream_index,
int
pad_packet_bytes
=
0
;
int
pes_flags
;
int
general_pack
=
0
;
/*"general" pack without data specific to one stream?*/
int
nb_frames
;
id
=
stream
->
id
;
...
...
@@ -572,10 +597,11 @@ static void flush_packet(AVFormatContext *ctx, int stream_index,
buf_ptr
=
buffer
;
if
((
(
s
->
packet_number
%
s
->
pack_header_freq
)
==
0
)
)
{
if
((
s
->
packet_number
%
s
->
pack_header_freq
)
==
0
||
s
->
last_scr
!=
scr
)
{
/* output pack and systems header if needed */
size
=
put_pack_header
(
ctx
,
buf_ptr
,
scr
);
buf_ptr
+=
size
;
s
->
last_scr
=
scr
;
if
(
s
->
is_vcd
)
{
/* there is exactly one system header for each stream in a VCD MPEG,
...
...
@@ -652,7 +678,23 @@ static void flush_packet(AVFormatContext *ctx, int stream_index,
startcode
=
0x100
+
id
;
}
stuffing_size
=
payload_size
-
stream
->
buffer_ptr
;
stuffing_size
=
payload_size
-
fifo_size
(
&
stream
->
fifo
,
stream
->
fifo
.
rptr
);
// first byte doesnt fit -> reset pts/dts + stuffing
if
(
payload_size
<=
trailer_size
&&
pts
!=
AV_NOPTS_VALUE
){
int
timestamp_len
=
0
;
if
(
dts
!=
pts
)
timestamp_len
+=
5
;
if
(
pts
!=
AV_NOPTS_VALUE
)
timestamp_len
+=
s
->
is_mpeg2
?
5
:
4
;
pts
=
dts
=
AV_NOPTS_VALUE
;
header_len
-=
timestamp_len
;
payload_size
+=
timestamp_len
;
stuffing_size
+=
timestamp_len
;
if
(
payload_size
>
trailer_size
)
stuffing_size
+=
payload_size
-
trailer_size
;
}
if
(
stuffing_size
<
0
)
stuffing_size
=
0
;
if
(
stuffing_size
>
16
)
{
/*<=16 for MPEG-1, <=32 for MPEG-2*/
...
...
@@ -661,6 +703,8 @@ static void flush_packet(AVFormatContext *ctx, int stream_index,
payload_size
-=
stuffing_size
;
stuffing_size
=
0
;
}
nb_frames
=
get_nb_frames
(
ctx
,
stream
,
payload_size
-
stuffing_size
);
put_be32
(
&
ctx
->
pb
,
startcode
);
...
...
@@ -739,13 +783,17 @@ static void flush_packet(AVFormatContext *ctx, int stream_index,
put_byte
(
&
ctx
->
pb
,
stream
->
lpcm_header
[
2
]);
}
else
{
/* AC3 */
put_byte
(
&
ctx
->
pb
,
stream
->
nb_frames
);
put_be16
(
&
ctx
->
pb
,
stream
->
frame_start_offset
);
put_byte
(
&
ctx
->
pb
,
nb_frames
);
put_be16
(
&
ctx
->
pb
,
trailer_size
+
1
);
}
}
/* output data */
put_buffer
(
&
ctx
->
pb
,
stream
->
buffer
,
payload_size
-
stuffing_size
);
if
(
put_fifo
(
&
ctx
->
pb
,
&
stream
->
fifo
,
payload_size
-
stuffing_size
,
&
stream
->
fifo
.
rptr
)
<
0
)
return
-
1
;
}
else
{
payload_size
=
stuffing_size
=
0
;
}
if
(
pad_packet_bytes
>
0
)
...
...
@@ -763,8 +811,8 @@ static void flush_packet(AVFormatContext *ctx, int stream_index,
or some data.*/
if
(
!
general_pack
)
stream
->
packet_number
++
;
stream
->
nb_frames
=
0
;
stream
->
frame_start_offset
=
0
;
return
payload_size
-
stuffing_size
;
}
static
void
put_vcd_padding_sector
(
AVFormatContext
*
ctx
)
...
...
@@ -832,22 +880,11 @@ static int64_t update_scr(AVFormatContext *ctx,int stream_index,int64_t pts)
/* XXX: system clock should be computed precisely, especially for
CBR case. The current mode gives at least something coherent */
if
(
stream_index
==
s
->
scr_stream_index
if
(
stream_index
==
0
&&
pts
!=
AV_NOPTS_VALUE
)
scr
=
pts
;
else
scr
=
s
->
last_scr
;
/* "Sanity hack": make sure that the SCR does not overtake the pts of
buffered data that is still waiting to be written.*/
for
(
i
=
0
;
i
<
ctx
->
nb_streams
;
i
++
)
{
stream
=
ctx
->
streams
[
i
]
->
priv_data
;
if
(
scr
>
stream
->
start_pts
&&
stream
->
start_pts
!=
AV_NOPTS_VALUE
)
{
/* av_log(ctx, AV_LOG_DEBUG, "mpeg: restricting scr to stream pts (scr=%0.3f, stream index=%d, stream_pts=%0.3f).\n", scr/90000.0, i, stream->start_pts / 90000.0); */
scr
=
stream
->
start_pts
;
}
}
}
s
->
last_scr
=
scr
;
...
...
@@ -855,6 +892,135 @@ static int64_t update_scr(AVFormatContext *ctx,int stream_index,int64_t pts)
return
scr
;
}
static
int
remove_decoded_packets
(
AVFormatContext
*
ctx
,
int64_t
scr
){
// MpegMuxContext *s = ctx->priv_data;
int
i
;
for
(
i
=
0
;
i
<
ctx
->
nb_streams
;
i
++
){
AVStream
*
st
=
ctx
->
streams
[
i
];
StreamInfo
*
stream
=
st
->
priv_data
;
PacketDesc
*
pkt_desc
=
stream
->
predecode_packet
;
while
(
pkt_desc
&&
scr
>
pkt_desc
->
dts
){
//FIXME > vs >=
if
(
stream
->
buffer_index
<
pkt_desc
->
size
||
stream
->
predecode_packet
==
stream
->
premux_packet
){
av_log
(
ctx
,
AV_LOG_ERROR
,
"buffer underflow
\n
"
);
break
;
}
stream
->
buffer_index
-=
pkt_desc
->
size
;
stream
->
predecode_packet
=
pkt_desc
->
next
;
av_freep
(
&
pkt_desc
);
}
}
return
0
;
}
static
int
output_packet
(
AVFormatContext
*
ctx
,
int
flush
){
MpegMuxContext
*
s
=
ctx
->
priv_data
;
AVStream
*
st
;
StreamInfo
*
stream
;
int
i
,
avail_space
,
es_size
,
trailer_size
;
int
best_i
=
-
1
;
int
best_score
=
INT_MIN
;
int
ignore_constraints
=
0
;
int64_t
scr
=
s
->
last_scr
;
retry:
for
(
i
=
0
;
i
<
ctx
->
nb_streams
;
i
++
){
AVStream
*
st
=
ctx
->
streams
[
i
];
StreamInfo
*
stream
=
st
->
priv_data
;
const
int
avail_data
=
fifo_size
(
&
stream
->
fifo
,
stream
->
fifo
.
rptr
);
const
int
space
=
stream
->
max_buffer_size
-
stream
->
buffer_index
;
int
rel_space
=
1024
*
space
/
stream
->
max_buffer_size
;
if
(
s
->
packet_size
>
avail_data
&&
!
flush
)
return
0
;
if
(
avail_data
==
0
)
continue
;
assert
(
avail_data
>
0
);
if
(
space
<
s
->
packet_size
&&
!
ignore_constraints
)
continue
;
if
(
rel_space
>
best_score
){
best_score
=
rel_space
;
best_i
=
i
;
avail_space
=
space
;
}
}
if
(
best_i
<
0
){
int64_t
best_dts
=
INT64_MAX
;
for
(
i
=
0
;
i
<
ctx
->
nb_streams
;
i
++
){
AVStream
*
st
=
ctx
->
streams
[
i
];
StreamInfo
*
stream
=
st
->
priv_data
;
PacketDesc
*
pkt_desc
=
stream
->
predecode_packet
;
if
(
pkt_desc
&&
pkt_desc
->
dts
<
best_dts
)
best_dts
=
pkt_desc
->
dts
;
}
#if 0
av_log(ctx, AV_LOG_DEBUG, "bumping scr, scr:%f, dts:%f\n",
scr/90000.0, best_dts/90000.0);
#endif
if
(
best_dts
==
INT64_MAX
)
return
0
;
if
(
scr
>=
best_dts
+
1
&&
!
ignore_constraints
){
av_log
(
ctx
,
AV_LOG_ERROR
,
"packet too large, ignoring buffer limits to mux it
\n
"
);
ignore_constraints
=
1
;
}
scr
=
FFMAX
(
best_dts
+
1
,
scr
);
if
(
remove_decoded_packets
(
ctx
,
scr
)
<
0
)
return
-
1
;
goto
retry
;
}
assert
(
best_i
>=
0
);
st
=
ctx
->
streams
[
best_i
];
stream
=
st
->
priv_data
;
assert
(
fifo_size
(
&
stream
->
fifo
,
stream
->
fifo
.
rptr
)
>
0
);
assert
(
avail_space
>=
s
->
packet_size
||
ignore_constraints
);
if
(
stream
->
premux_packet
->
unwritten_size
==
stream
->
premux_packet
->
size
)
trailer_size
=
0
;
else
trailer_size
=
stream
->
premux_packet
->
unwritten_size
;
es_size
=
flush_packet
(
ctx
,
best_i
,
stream
->
premux_packet
->
pts
,
stream
->
premux_packet
->
dts
,
scr
,
trailer_size
);
if
(
s
->
is_vcd
)
{
/* Write one or more padding sectors, if necessary, to reach
the constant overall bitrate.*/
int
vcd_pad_bytes
;
while
((
vcd_pad_bytes
=
get_vcd_padding_size
(
ctx
,
stream
->
start_pts
)
)
>=
s
->
packet_size
){
//FIXME pts cannot be correct here
put_vcd_padding_sector
(
ctx
);
s
->
last_scr
+=
s
->
packet_size
*
90000LL
/
(
s
->
mux_rate
*
50LL
);
//FIXME rounding and first few bytes of each packet
}
}
stream
->
buffer_index
+=
es_size
;
s
->
last_scr
+=
s
->
packet_size
*
90000LL
/
(
s
->
mux_rate
*
50LL
);
//FIXME rounding and first few bytes of each packet
while
(
stream
->
premux_packet
&&
stream
->
premux_packet
->
unwritten_size
<=
es_size
){
es_size
-=
stream
->
premux_packet
->
unwritten_size
;
stream
->
premux_packet
=
stream
->
premux_packet
->
next
;
}
if
(
es_size
)
stream
->
premux_packet
->
unwritten_size
-=
es_size
;
if
(
remove_decoded_packets
(
ctx
,
s
->
last_scr
)
<
0
)
return
-
1
;
return
1
;
}
static
int
mpeg_mux_write_packet
(
AVFormatContext
*
ctx
,
AVPacket
*
pkt
)
{
...
...
@@ -866,6 +1032,7 @@ static int mpeg_mux_write_packet(AVFormatContext *ctx, AVPacket *pkt)
StreamInfo
*
stream
=
st
->
priv_data
;
int64_t
pts
,
dts
,
new_start_pts
,
new_start_dts
;
int
len
,
avail_size
;
PacketDesc
*
pkt_desc
;
pts
=
pkt
->
pts
;
dts
=
pkt
->
dts
;
...
...
@@ -891,17 +1058,36 @@ static int mpeg_mux_write_packet(AVFormatContext *ctx, AVPacket *pkt)
So the real data starts at SCR 36000+3*1200. */
pts
=
(
pts
+
36000
+
3600
)
&
((
1LL
<<
33
)
-
1
);
dts
=
(
dts
+
36000
+
3600
)
&
((
1LL
<<
33
)
-
1
);
}
else
{
pts
=
(
pts
+
PRELOAD
)
&
((
1LL
<<
33
)
-
1
);
dts
=
(
dts
+
PRELOAD
)
&
((
1LL
<<
33
)
-
1
);
}
#if 0
update_scr(ctx,stream_index,pts);
*
stream
->
next_packet
=
pkt_desc
=
av_mallocz
(
sizeof
(
PacketDesc
));
pkt_desc
->
pts
=
pts
;
pkt_desc
->
dts
=
dts
;
pkt_desc
->
unwritten_size
=
pkt_desc
->
size
=
size
;
if
(
!
stream
->
predecode_packet
)
stream
->
predecode_packet
=
pkt_desc
;
stream
->
next_packet
=
&
pkt_desc
->
next
;
if
(
stream
->
fifo
.
end
-
stream
->
fifo
.
buffer
-
fifo_size
(
&
stream
->
fifo
,
stream
->
fifo
.
rptr
)
<
size
){
av_log
(
ctx
,
AV_LOG_ERROR
,
"fifo overflow
\n
"
);
return
-
1
;
}
fifo_write
(
&
stream
->
fifo
,
buf
,
size
,
&
stream
->
fifo
.
wptr
);
printf("%d: pts=%0.3f dts=%0.3f scr=%0.3f\n",
stream_index,
pts / 90000.0,
dts / 90000.0,
s->last_scr / 90000.0);
#endif
for
(;;){
int
ret
=
output_packet
(
ctx
,
0
);
if
(
ret
<
0
)
return
ret
;
else
if
(
ret
==
0
)
break
;
}
#if 0
/* we assume here that pts != AV_NOPTS_VALUE */
new_start_pts = stream->start_pts;
...
...
@@ -931,8 +1117,6 @@ static int mpeg_mux_write_packet(AVFormatContext *ctx, AVPacket *pkt)
stream->start_pts = new_start_pts;
stream->start_dts = new_start_dts;
stream->nb_frames++;
if
(
stream
->
frame_start_offset
==
0
)
stream
->
frame_start_offset
=
stream
->
buffer_ptr
+
1
;
while (size > 0) {
avail_size = get_packet_payload_size(ctx, stream_index,
stream->start_pts,
...
...
@@ -968,27 +1152,22 @@ static int mpeg_mux_write_packet(AVFormatContext *ctx, AVPacket *pkt)
stream->start_dts = AV_NOPTS_VALUE;
}
}
#endif
return
0
;
}
static
int
mpeg_mux_end
(
AVFormatContext
*
ctx
)
{
MpegMuxContext
*
s
=
ctx
->
priv_data
;
//
MpegMuxContext *s = ctx->priv_data;
StreamInfo
*
stream
;
int
i
;
/* flush each packet */
for
(
i
=
0
;
i
<
ctx
->
nb_streams
;
i
++
)
{
stream
=
ctx
->
streams
[
i
]
->
priv_data
;
if
(
stream
->
buffer_ptr
>
0
)
{
update_scr
(
ctx
,
i
,
stream
->
start_pts
);
/* NOTE: we can always write the remaining data as it was
tested before in mpeg_mux_write_packet() */
flush_packet
(
ctx
,
i
,
stream
->
start_pts
,
stream
->
start_dts
,
s
->
last_scr
);
}
for
(;;){
int
ret
=
output_packet
(
ctx
,
1
);
if
(
ret
<
0
)
return
ret
;
else
if
(
ret
==
0
)
break
;
}
/* End header according to MPEG1 systems standard. We do not write
...
...
@@ -997,6 +1176,12 @@ static int mpeg_mux_end(AVFormatContext *ctx)
//put_be32(&ctx->pb, ISO_11172_END_CODE);
//put_flush_packet(&ctx->pb);
for
(
i
=
0
;
i
<
ctx
->
nb_streams
;
i
++
)
{
stream
=
ctx
->
streams
[
i
]
->
priv_data
;
assert
(
fifo_size
(
&
stream
->
fifo
,
stream
->
fifo
.
rptr
)
==
0
);
fifo_free
(
&
stream
->
fifo
);
}
return
0
;
}
#endif //CONFIG_ENCODERS
...
...
libavformat/utils.c
浏览文件 @
7000a175
...
...
@@ -264,6 +264,34 @@ void fifo_write(FifoBuffer *f, uint8_t *buf, int size, uint8_t **wptr_ptr)
*
wptr_ptr
=
wptr
;
}
/* get data from the fifo (return -1 if not enough data) */
int
put_fifo
(
ByteIOContext
*
pb
,
FifoBuffer
*
f
,
int
buf_size
,
uint8_t
**
rptr_ptr
)
{
uint8_t
*
rptr
=
*
rptr_ptr
;
int
size
,
len
;
if
(
f
->
wptr
>=
rptr
)
{
size
=
f
->
wptr
-
rptr
;
}
else
{
size
=
(
f
->
end
-
rptr
)
+
(
f
->
wptr
-
f
->
buffer
);
}
if
(
size
<
buf_size
)
return
-
1
;
while
(
buf_size
>
0
)
{
len
=
f
->
end
-
rptr
;
if
(
len
>
buf_size
)
len
=
buf_size
;
put_buffer
(
pb
,
rptr
,
len
);
rptr
+=
len
;
if
(
rptr
>=
f
->
end
)
rptr
=
f
->
buffer
;
buf_size
-=
len
;
}
*
rptr_ptr
=
rptr
;
return
0
;
}
int
filename_number_test
(
const
char
*
filename
)
{
char
buf
[
1024
];
...
...
tests/libav.regression.ref
浏览文件 @
7000a175
...
...
@@ -7,9 +7,9 @@ ffmpeg regression test
./data/b-libav.asf CRC=750f18c7
1cbf838e659d7fc3d3e33f4187b91f6c *./data/b-libav.rm
360251 ./data/b-libav.rm
e0a9ed22a34e0277ec77c84e8b64afd9
*./data/b-libav.mpg
82d8794cc5eaf220b2f260ceacaf3a3b
*./data/b-libav.mpg
387072 ./data/b-libav.mpg
./data/b-libav.mpg CRC=
c0b6
4225
./data/b-libav.mpg CRC=
16c7
4225
57a8dfc7926802bb337a9d8918de94a8 *./data/b-libav.swf
41816 ./data/b-libav.swf
./data/b-libav.swf CRC=2b273fea
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录