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
a19e9f2d
Commit
a19e9f2d
authored
Jun 15, 2012
by
Clément Bœsch
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
lavf/microdvd: rewrite using subtitles queue API.
parent
0ef28e11
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
58 additions
and
89 deletions
+58
-89
microdvddec.c
libavformat/microdvddec.c
+58
-89
No files found.
libavformat/microdvddec.c
View file @
a19e9f2d
/*
* MicroDVD subtitle demuxer
* Copyright (c) 2010 Aurelien Jacobs <aurel@gnuage.org>
* Copyright (c) 2012 Clément Bœsch <ubitux@gmail.com>
*
* This file is part of FFmpeg.
*
...
...
@@ -21,16 +22,14 @@
#include "avformat.h"
#include "internal.h"
#include "subtitles.h"
#include "libavutil/intreadwrite.h"
#define MAX_LINESIZE 2048
typedef
struct
{
uint8_t
lines
[
3
][
MAX_LINESIZE
];
int64_t
pos
[
3
];
AVPacket
last_pkt
;
int
last_pkt_ready
;
FFDemuxSubtitlesQueue
q
;
}
MicroDVDContext
;
...
...
@@ -52,36 +51,6 @@ static int microdvd_probe(AVProbeData *p)
return
AVPROBE_SCORE_MAX
;
}
static
int
microdvd_read_header
(
AVFormatContext
*
s
)
{
AVRational
pts_info
=
(
AVRational
){
2997
,
125
};
/* default: 23.976 fps */
MicroDVDContext
*
microdvd
=
s
->
priv_data
;
AVStream
*
st
=
avformat_new_stream
(
s
,
NULL
);
int
i
,
frame
;
double
fps
;
char
c
;
if
(
!
st
)
return
AVERROR
(
ENOMEM
);
for
(
i
=
0
;
i
<
FF_ARRAY_ELEMS
(
microdvd
->
lines
);
i
++
)
{
microdvd
->
pos
[
i
]
=
avio_tell
(
s
->
pb
);
ff_get_line
(
s
->
pb
,
microdvd
->
lines
[
i
],
sizeof
(
microdvd
->
lines
[
i
]));
if
((
sscanf
(
microdvd
->
lines
[
i
],
"{%d}{}%6lf"
,
&
frame
,
&
fps
)
==
2
||
sscanf
(
microdvd
->
lines
[
i
],
"{%d}{%*d}%6lf"
,
&
frame
,
&
fps
)
==
2
)
&&
frame
<=
1
&&
fps
>
3
&&
fps
<
100
)
pts_info
=
av_d2q
(
fps
,
100000
);
if
(
sscanf
(
microdvd
->
lines
[
i
],
"{DEFAULT}{}%c"
,
&
c
)
==
1
)
{
st
->
codec
->
extradata
=
av_strdup
(
microdvd
->
lines
[
i
]
+
11
);
st
->
codec
->
extradata_size
=
strlen
(
st
->
codec
->
extradata
);
i
--
;
}
}
avpriv_set_pts_info
(
st
,
64
,
pts_info
.
den
,
pts_info
.
num
);
st
->
codec
->
codec_type
=
AVMEDIA_TYPE_SUBTITLE
;
st
->
codec
->
codec_id
=
CODEC_ID_MICRODVD
;
return
0
;
}
static
int64_t
get_pts
(
const
char
*
buf
)
{
int
frame
;
...
...
@@ -101,68 +70,67 @@ static int get_duration(const char *buf)
return
-
1
;
}
static
int
microdvd_read_
packet
(
AVFormatContext
*
s
,
AVPacket
*
pkt
)
static
int
microdvd_read_
header
(
AVFormatContext
*
s
)
{
AVRational
pts_info
=
(
AVRational
){
2997
,
125
};
/* default: 23.976 fps */
MicroDVDContext
*
microdvd
=
s
->
priv_data
;
char
buffer
[
MAX_LINESIZE
];
int64_t
pos
=
avio_tell
(
s
->
pb
);
int
i
,
len
=
0
,
res
=
AVERROR_EOF
;
// last packet has its duration set but couldn't be raised earlier
if
(
microdvd
->
last_pkt_ready
)
{
*
pkt
=
microdvd
->
last_pkt
;
microdvd
->
last_pkt_ready
=
0
;
return
0
;
}
AVStream
*
st
=
avformat_new_stream
(
s
,
NULL
);
int
i
=
0
;
char
line
[
MAX_LINESIZE
];
if
(
!
st
)
return
AVERROR
(
ENOMEM
);
while
(
!
url_feof
(
s
->
pb
))
{
AVPacket
*
sub
;
int64_t
pos
=
avio_tell
(
s
->
pb
);
int
len
=
ff_get_line
(
s
->
pb
,
line
,
sizeof
(
line
));
for
(
i
=
0
;
i
<
FF_ARRAY_ELEMS
(
microdvd
->
lines
);
i
++
)
{
if
(
microdvd
->
lines
[
i
][
0
])
{
strcpy
(
buffer
,
microdvd
->
lines
[
i
]);
pos
=
microdvd
->
pos
[
i
];
len
=
strlen
(
buffer
);
microdvd
->
lines
[
i
][
0
]
=
0
;
if
(
!
len
)
break
;
}
}
if
(
!
len
)
len
=
ff_get_line
(
s
->
pb
,
buffer
,
sizeof
(
buffer
));
if
(
microdvd
->
last_pkt
.
duration
==
-
1
&&
!
buffer
[
0
])
{
// if the previous subtitle line had no duration, last until the end of
// the presentation
microdvd
->
last_pkt
.
duration
=
0
;
*
pkt
=
microdvd
->
last_pkt
;
pkt
->
duration
=
-
1
;
res
=
0
;
}
else
if
(
buffer
[
0
]
&&
!
(
res
=
av_new_packet
(
pkt
,
len
)))
{
memcpy
(
pkt
->
data
,
buffer
,
len
);
pkt
->
flags
|=
AV_PKT_FLAG_KEY
;
pkt
->
pos
=
pos
;
pkt
->
pts
=
pkt
->
dts
=
get_pts
(
buffer
);
if
(
pkt
->
pts
!=
AV_NOPTS_VALUE
)
{
pkt
->
duration
=
get_duration
(
buffer
);
if
(
microdvd
->
last_pkt
.
duration
==
-
1
)
{
// previous packet wasn't raised because it was lacking the
// duration info, so set its duration with the new packet pts
// and raise it
AVPacket
tmp_pkt
;
tmp_pkt
=
microdvd
->
last_pkt
;
tmp_pkt
.
duration
=
pkt
->
pts
-
tmp_pkt
.
pts
;
microdvd
->
last_pkt
=
*
pkt
;
microdvd
->
last_pkt_ready
=
pkt
->
duration
!=
-
1
;
*
pkt
=
tmp_pkt
;
}
else
if
(
pkt
->
duration
==
-
1
)
{
// no packet without duration queued, and current one is
// lacking the duration info, we need to parse another subtitle
// event.
microdvd
->
last_pkt
=
*
pkt
;
res
=
AVERROR
(
EAGAIN
);
if
(
i
<
3
)
{
int
frame
;
double
fps
;
char
c
;
i
++
;
if
((
sscanf
(
line
,
"{%d}{}%6lf"
,
&
frame
,
&
fps
)
==
2
||
sscanf
(
line
,
"{%d}{%*d}%6lf"
,
&
frame
,
&
fps
)
==
2
)
&&
frame
<=
1
&&
fps
>
3
&&
fps
<
100
)
pts_info
=
av_d2q
(
fps
,
100000
);
if
(
!
st
->
codec
->
extradata
&&
sscanf
(
line
,
"{DEFAULT}{}%c"
,
&
c
)
==
1
)
{
st
->
codec
->
extradata
=
av_strdup
(
line
+
11
);
if
(
!
st
->
codec
->
extradata
)
return
AVERROR
(
ENOMEM
);
st
->
codec
->
extradata_size
=
strlen
(
st
->
codec
->
extradata
)
+
1
;
continue
;
}
}
sub
=
ff_subtitles_queue_insert
(
&
microdvd
->
q
,
line
,
len
,
0
);
if
(
!
sub
)
return
AVERROR
(
ENOMEM
);
sub
->
pos
=
pos
;
sub
->
pts
=
get_pts
(
sub
->
data
);
sub
->
duration
=
get_duration
(
sub
->
data
);
}
return
res
;
ff_subtitles_queue_finalize
(
&
microdvd
->
q
);
avpriv_set_pts_info
(
st
,
64
,
pts_info
.
den
,
pts_info
.
num
);
st
->
codec
->
codec_type
=
AVMEDIA_TYPE_SUBTITLE
;
st
->
codec
->
codec_id
=
CODEC_ID_MICRODVD
;
return
0
;
}
static
int
microdvd_read_packet
(
AVFormatContext
*
s
,
AVPacket
*
pkt
)
{
MicroDVDContext
*
microdvd
=
s
->
priv_data
;
return
ff_subtitles_queue_read_packet
(
&
microdvd
->
q
,
pkt
);
}
static
int
microdvd_read_close
(
AVFormatContext
*
s
)
{
MicroDVDContext
*
microdvd
=
s
->
priv_data
;
ff_subtitles_queue_clean
(
&
microdvd
->
q
);
return
0
;
}
AVInputFormat
ff_microdvd_demuxer
=
{
...
...
@@ -172,5 +140,6 @@ AVInputFormat ff_microdvd_demuxer = {
.
read_probe
=
microdvd_probe
,
.
read_header
=
microdvd_read_header
,
.
read_packet
=
microdvd_read_packet
,
.
read_close
=
microdvd_read_close
,
.
flags
=
AVFMT_GENERIC_INDEX
,
};
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