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
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
* MicroDVD subtitle demuxer
* Copyright (c) 2010 Aurelien Jacobs <aurel@gnuage.org>
* Copyright (c) 2010 Aurelien Jacobs <aurel@gnuage.org>
* Copyright (c) 2012 Clément Bœsch <ubitux@gmail.com>
*
*
* This file is part of FFmpeg.
* This file is part of FFmpeg.
*
*
...
@@ -21,16 +22,14 @@
...
@@ -21,16 +22,14 @@
#include "avformat.h"
#include "avformat.h"
#include "internal.h"
#include "internal.h"
#include "subtitles.h"
#include "libavutil/intreadwrite.h"
#include "libavutil/intreadwrite.h"
#define MAX_LINESIZE 2048
#define MAX_LINESIZE 2048
typedef
struct
{
typedef
struct
{
uint8_t
lines
[
3
][
MAX_LINESIZE
];
FFDemuxSubtitlesQueue
q
;
int64_t
pos
[
3
];
AVPacket
last_pkt
;
int
last_pkt_ready
;
}
MicroDVDContext
;
}
MicroDVDContext
;
...
@@ -52,36 +51,6 @@ static int microdvd_probe(AVProbeData *p)
...
@@ -52,36 +51,6 @@ static int microdvd_probe(AVProbeData *p)
return
AVPROBE_SCORE_MAX
;
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
)
static
int64_t
get_pts
(
const
char
*
buf
)
{
{
int
frame
;
int
frame
;
...
@@ -101,68 +70,67 @@ static int get_duration(const char *buf)
...
@@ -101,68 +70,67 @@ static int get_duration(const char *buf)
return
-
1
;
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
;
MicroDVDContext
*
microdvd
=
s
->
priv_data
;
char
buffer
[
MAX_LINESIZE
];
AVStream
*
st
=
avformat_new_stream
(
s
,
NULL
);
int64_t
pos
=
avio_tell
(
s
->
pb
);
int
i
=
0
;
int
i
,
len
=
0
,
res
=
AVERROR_EOF
;
char
line
[
MAX_LINESIZE
];
// last packet has its duration set but couldn't be raised earlier
if
(
!
st
)
if
(
microdvd
->
last_pkt_ready
)
{
return
AVERROR
(
ENOMEM
);
*
pkt
=
microdvd
->
last_pkt
;
microdvd
->
last_pkt_ready
=
0
;
while
(
!
url_feof
(
s
->
pb
))
{
return
0
;
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
(
!
len
)
if
(
microdvd
->
lines
[
i
][
0
])
{
strcpy
(
buffer
,
microdvd
->
lines
[
i
]);
pos
=
microdvd
->
pos
[
i
];
len
=
strlen
(
buffer
);
microdvd
->
lines
[
i
][
0
]
=
0
;
break
;
break
;
}
if
(
i
<
3
)
{
}
int
frame
;
if
(
!
len
)
double
fps
;
len
=
ff_get_line
(
s
->
pb
,
buffer
,
sizeof
(
buffer
));
char
c
;
if
(
microdvd
->
last_pkt
.
duration
==
-
1
&&
!
buffer
[
0
])
{
i
++
;
// if the previous subtitle line had no duration, last until the end of
if
((
sscanf
(
line
,
"{%d}{}%6lf"
,
&
frame
,
&
fps
)
==
2
||
// the presentation
sscanf
(
line
,
"{%d}{%*d}%6lf"
,
&
frame
,
&
fps
)
==
2
)
microdvd
->
last_pkt
.
duration
=
0
;
&&
frame
<=
1
&&
fps
>
3
&&
fps
<
100
)
*
pkt
=
microdvd
->
last_pkt
;
pts_info
=
av_d2q
(
fps
,
100000
);
pkt
->
duration
=
-
1
;
if
(
!
st
->
codec
->
extradata
&&
sscanf
(
line
,
"{DEFAULT}{}%c"
,
&
c
)
==
1
)
{
res
=
0
;
st
->
codec
->
extradata
=
av_strdup
(
line
+
11
);
}
else
if
(
buffer
[
0
]
&&
!
(
res
=
av_new_packet
(
pkt
,
len
)))
{
if
(
!
st
->
codec
->
extradata
)
memcpy
(
pkt
->
data
,
buffer
,
len
);
return
AVERROR
(
ENOMEM
);
pkt
->
flags
|=
AV_PKT_FLAG_KEY
;
st
->
codec
->
extradata_size
=
strlen
(
st
->
codec
->
extradata
)
+
1
;
pkt
->
pos
=
pos
;
continue
;
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
);
}
}
}
}
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
=
{
AVInputFormat
ff_microdvd_demuxer
=
{
...
@@ -172,5 +140,6 @@ AVInputFormat ff_microdvd_demuxer = {
...
@@ -172,5 +140,6 @@ AVInputFormat ff_microdvd_demuxer = {
.
read_probe
=
microdvd_probe
,
.
read_probe
=
microdvd_probe
,
.
read_header
=
microdvd_read_header
,
.
read_header
=
microdvd_read_header
,
.
read_packet
=
microdvd_read_packet
,
.
read_packet
=
microdvd_read_packet
,
.
read_close
=
microdvd_read_close
,
.
flags
=
AVFMT_GENERIC_INDEX
,
.
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