FFmpeg
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
Examples
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
libavformat
oggparsevp8.c
Go to the documentation of this file.
1
/*
2
* On2 VP8 parser for Ogg
3
* Copyright (C) 2013 James Almer
4
*
5
* This file is part of FFmpeg.
6
*
7
* FFmpeg is free software; you can redistribute it and/or
8
* modify it under the terms of the GNU Lesser General Public
9
* License as published by the Free Software Foundation; either
10
* version 2.1 of the License, or (at your option) any later version.
11
*
12
* FFmpeg is distributed in the hope that it will be useful,
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15
* Lesser General Public License for more details.
16
*
17
* You should have received a copy of the GNU Lesser General Public
18
* License along with FFmpeg; if not, write to the Free Software
19
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20
*/
21
22
#include "
libavutil/intreadwrite.h
"
23
24
#include "
avformat.h
"
25
#include "
internal.h
"
26
#include "
oggdec.h
"
27
28
#define VP8_HEADER_SIZE 26
29
30
static
int
vp8_header
(
AVFormatContext
*
s
,
int
idx)
31
{
32
struct
ogg
*
ogg
= s->
priv_data
;
33
struct
ogg_stream
*os = ogg->
streams
+ idx;
34
uint8_t
*p = os->
buf
+ os->
pstart
;
35
AVStream
*st = s->
streams
[idx];
36
AVRational
framerate;
37
38
if
(os->
psize
< 7 || p[0] != 0x4f)
39
return
0;
40
41
switch
(p[5]){
42
case
0x01:
43
if
(os->
psize
<
VP8_HEADER_SIZE
) {
44
av_log
(s,
AV_LOG_ERROR
,
"Invalid OggVP8 header packet"
);
45
return
AVERROR_INVALIDDATA
;
46
}
47
48
if
(p[6] != 1) {
49
av_log
(s,
AV_LOG_WARNING
,
50
"Unknown OggVP8 version %d.%d\n"
, p[6], p[7]);
51
return
AVERROR_INVALIDDATA
;
52
}
53
54
st->
codec
->
width
=
AV_RB16
(p + 8);
55
st->
codec
->
height
=
AV_RB16
(p + 10);
56
st->
sample_aspect_ratio
.
num
=
AV_RB24
(p + 12);
57
st->
sample_aspect_ratio
.
den
=
AV_RB24
(p + 15);
58
framerate.
num
=
AV_RB32
(p + 18);
59
framerate.
den
=
AV_RB32
(p + 22);
60
61
avpriv_set_pts_info
(st, 64, framerate.
den
, framerate.
num
);
62
st->
codec
->
codec_type
=
AVMEDIA_TYPE_VIDEO
;
63
st->
codec
->
codec_id
=
AV_CODEC_ID_VP8
;
64
st->
need_parsing
=
AVSTREAM_PARSE_HEADERS
;
65
break
;
66
case
0x02:
67
if
(p[6] != 0x20)
68
return
AVERROR_INVALIDDATA
;
69
ff_vorbis_stream_comment
(s, st, p + 7, os->
psize
- 7);
70
break
;
71
default
:
72
av_log
(s,
AV_LOG_ERROR
,
"Unknown VP8 header type 0x%02X\n"
, p[5]);
73
return
AVERROR_INVALIDDATA
;
74
}
75
76
return
1;
77
}
78
79
static
uint64_t
vp8_gptopts
(
AVFormatContext
*
s
,
int
idx,
80
uint64_t
granule
, int64_t *dts)
81
{
82
struct
ogg
*
ogg
= s->
priv_data
;
83
struct
ogg_stream
*os = ogg->
streams
+ idx;
84
85
uint64_t
pts
= (granule >> 32);
86
uint32_t dist = (granule >> 3) & 0x07ffffff;
87
88
if
(!dist)
89
os->
pflags
|=
AV_PKT_FLAG_KEY
;
90
91
if
(dts)
92
*dts =
pts
;
93
94
return
pts
;
95
}
96
97
static
int
vp8_packet
(
AVFormatContext
*
s
,
int
idx)
98
{
99
struct
ogg
*
ogg
= s->
priv_data
;
100
struct
ogg_stream
*os = ogg->
streams
+ idx;
101
uint8_t
*p = os->
buf
+ os->
pstart
;
102
103
if
((!os->
lastpts
|| os->
lastpts
==
AV_NOPTS_VALUE
) &&
104
!(os->
flags
&
OGG_FLAG_EOS
)) {
105
int
seg;
106
int
duration
;
107
uint8_t
*last_pkt = p;
108
uint8_t
*next_pkt;
109
110
seg = os->
segp
;
111
duration = (last_pkt[0] >> 4) & 1;
112
next_pkt = last_pkt += os->
psize
;
113
for
(; seg < os->
nsegs
; seg++) {
114
if
(os->
segments
[seg] < 255) {
115
duration += (last_pkt[0] >> 4) & 1;
116
last_pkt = next_pkt + os->
segments
[seg];
117
}
118
next_pkt += os->
segments
[seg];
119
}
120
os->
lastpts
=
121
os->
lastdts
=
vp8_gptopts
(s, idx, os->
granule
,
NULL
) -
duration
;
122
if
(s->
streams
[idx]->
start_time
==
AV_NOPTS_VALUE
) {
123
s->
streams
[idx]->
start_time
= os->
lastpts
;
124
if
(s->
streams
[idx]->
duration
)
125
s->
streams
[idx]->
duration
-= s->
streams
[idx]->
start_time
;
126
}
127
}
128
129
if
(os->
psize
> 0)
130
os->
pduration
= (p[0] >> 4) & 1;
131
132
return
0;
133
}
134
135
const
struct
ogg_codec
ff_vp8_codec
= {
136
.
magic
=
"OVP80"
,
137
.magicsize = 5,
138
.header =
vp8_header
,
139
.packet =
vp8_packet
,
140
.gptopts =
vp8_gptopts
,
141
.nb_header = 1,
142
};
Generated on Sun Mar 8 2015 02:35:11 for FFmpeg by
1.8.2