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