Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Xiph.Org
aom-rav1e
Commits
a944deae
Commit
a944deae
authored
Nov 19, 2013
by
Tom Finegan
Committed by
Gerrit Code Review
Nov 19, 2013
Browse files
Merge "vpxdec: Relocate WebM input support."
parents
65cee2f0
2abe2d46
Changes
5
Hide whitespace changes
Inline
Side-by-side
examples.mk
View file @
a944deae
...
...
@@ -25,6 +25,7 @@ vpxdec.SRCS += vpx/vpx_integer.h
vpxdec.SRCS
+=
args.c args.h
vpxdec.SRCS
+=
ivfdec.c ivfdec.h
vpxdec.SRCS
+=
tools_common.c tools_common.h
vpxdec.SRCS
+=
webmdec.c webmdec.h
vpxdec.SRCS
+=
nestegg/halloc/halloc.h
vpxdec.SRCS
+=
nestegg/halloc/src/align.h
vpxdec.SRCS
+=
nestegg/halloc/src/halloc.c
...
...
tools_common.h
View file @
a944deae
...
...
@@ -92,11 +92,11 @@ struct VpxInputContext {
off_t
length
;
struct
FileTypeDetectionBuffer
detect
;
enum
VideoFileType
file_type
;
u
nsigned
in
t
width
;
u
nsigned
in
t
height
;
u
int32_
t
width
;
u
int32_
t
height
;
int
use_i420
;
int
only_i420
;
u
nsigned
in
t
fourcc
;
u
int32_
t
fourcc
;
struct
VpxRational
framerate
;
#if CONFIG_ENCODERS
y4m_input
y4m
;
...
...
vpxdec.c
View file @
a944deae
...
...
@@ -15,6 +15,9 @@
#include
<string.h>
#include
<limits.h>
#include
"third_party/libyuv/include/libyuv/scale.h"
#include
"./args.h"
#include
"./ivfdec.h"
#define VPX_CODEC_DISABLE_COMPAT 1
...
...
@@ -27,20 +30,19 @@
#endif
#if CONFIG_MD5
#include
"md5_utils.h"
#include
"
./
md5_utils.h"
#endif
#include
"./tools_common.h"
#include
"nestegg/include/nestegg/nestegg.h"
#include
"third_party/libyuv/include/libyuv/scale.h"
#include
"./webmdec.h"
static
const
char
*
exec_name
;
static
const
struct
{
char
const
*
name
;
const
vpx_codec_iface_t
*
(
*
iface
)(
void
);
u
nsigned
int
fourcc
;
u
nsigned
int
fourcc_mask
;
u
int32_t
fourcc
;
u
int32_t
fourcc_mask
;
}
ifaces
[]
=
{
#if CONFIG_VP8_DECODER
{
"vp8"
,
vpx_codec_vp8_dx
,
VP8_FOURCC_MASK
,
0x00FFFFFF
},
...
...
@@ -50,7 +52,11 @@ static const struct {
#endif
};
#include
"args.h"
struct
VpxDecInputContext
{
struct
VpxInputContext
*
vpx_input_ctx
;
struct
WebmInputContext
*
webm_ctx
;
};
static
const
arg_def_t
looparg
=
ARG_DEF
(
NULL
,
"loops"
,
1
,
"Number of times to decode the file"
);
static
const
arg_def_t
codecarg
=
ARG_DEF
(
NULL
,
"codec"
,
1
,
...
...
@@ -162,15 +168,6 @@ void usage_exit() {
exit
(
EXIT_FAILURE
);
}
struct
VpxDecInputContext
{
nestegg
*
nestegg_ctx
;
nestegg_packet
*
pkt
;
unsigned
int
chunk
;
unsigned
int
chunks
;
unsigned
int
video_track
;
struct
VpxInputContext
*
vpx_input_ctx
;
};
static
int
read_frame
(
struct
VpxDecInputContext
*
input
,
uint8_t
**
buf
,
size_t
*
bytes_in_buffer
,
...
...
@@ -180,30 +177,8 @@ static int read_frame(struct VpxDecInputContext *input,
FILE
*
infile
=
input
->
vpx_input_ctx
->
file
;
enum
VideoFileType
kind
=
input
->
vpx_input_ctx
->
file_type
;
if
(
kind
==
FILE_TYPE_WEBM
)
{
if
(
input
->
chunk
>=
input
->
chunks
)
{
unsigned
int
track
;
do
{
/* End of this packet, get another. */
if
(
input
->
pkt
)
nestegg_free_packet
(
input
->
pkt
);
if
(
nestegg_read_packet
(
input
->
nestegg_ctx
,
&
input
->
pkt
)
<=
0
||
nestegg_packet_track
(
input
->
pkt
,
&
track
))
return
1
;
}
while
(
track
!=
input
->
video_track
);
if
(
nestegg_packet_count
(
input
->
pkt
,
&
input
->
chunks
))
return
1
;
input
->
chunk
=
0
;
}
if
(
nestegg_packet_data
(
input
->
pkt
,
input
->
chunk
,
buf
,
bytes_in_buffer
))
return
1
;
input
->
chunk
++
;
return
0
;
return
webm_read_frame
(
input
->
webm_ctx
,
buf
,
bytes_in_buffer
,
buffer_size
);
}
else
if
(
kind
==
FILE_TYPE_RAW
)
{
if
(
fread
(
raw_hdr
,
RAW_FRAME_HDR_SZ
,
1
,
infile
)
!=
1
)
{
if
(
!
feof
(
infile
))
...
...
@@ -333,161 +308,12 @@ int file_is_raw(struct VpxInputContext *input) {
return
is_raw
;
}
static
int
nestegg_read_cb
(
void
*
buffer
,
size_t
length
,
void
*
userdata
)
{
FILE
*
f
=
userdata
;
if
(
fread
(
buffer
,
1
,
length
,
f
)
<
length
)
{
if
(
ferror
(
f
))
return
-
1
;
if
(
feof
(
f
))
return
0
;
}
return
1
;
}
static
int
nestegg_seek_cb
(
int64_t
offset
,
int
whence
,
void
*
userdata
)
{
switch
(
whence
)
{
case
NESTEGG_SEEK_SET
:
whence
=
SEEK_SET
;
break
;
case
NESTEGG_SEEK_CUR
:
whence
=
SEEK_CUR
;
break
;
case
NESTEGG_SEEK_END
:
whence
=
SEEK_END
;
break
;
};
return
fseek
(
userdata
,
(
long
)
offset
,
whence
)
?
-
1
:
0
;
}
static
int64_t
nestegg_tell_cb
(
void
*
userdata
)
{
return
ftell
(
userdata
);
}
static
void
nestegg_log_cb
(
nestegg
*
context
,
unsigned
int
severity
,
char
const
*
format
,
...)
{
va_list
ap
;
va_start
(
ap
,
format
);
vfprintf
(
stderr
,
format
,
ap
);
fprintf
(
stderr
,
"
\n
"
);
va_end
(
ap
);
}
static
int
webm_guess_framerate
(
struct
VpxDecInputContext
*
input
)
{
unsigned
int
i
;
uint64_t
tstamp
=
0
;
/* Check to see if we can seek before we parse any data. */
if
(
nestegg_track_seek
(
input
->
nestegg_ctx
,
input
->
video_track
,
0
))
{
warn
(
"WARNING: Failed to guess framerate (no Cues), set to 30fps.
\n
"
);
input
->
vpx_input_ctx
->
framerate
.
numerator
=
30
;
input
->
vpx_input_ctx
->
framerate
.
denominator
=
1
;
return
0
;
}
/* Guess the framerate. Read up to 1 second, or 50 video packets,
* whichever comes first.
*/
for
(
i
=
0
;
tstamp
<
1000000000
&&
i
<
50
;)
{
nestegg_packet
*
pkt
;
unsigned
int
track
;
if
(
nestegg_read_packet
(
input
->
nestegg_ctx
,
&
pkt
)
<=
0
)
break
;
nestegg_packet_track
(
pkt
,
&
track
);
if
(
track
==
input
->
video_track
)
{
nestegg_packet_tstamp
(
pkt
,
&
tstamp
);
i
++
;
}
nestegg_free_packet
(
pkt
);
}
if
(
nestegg_track_seek
(
input
->
nestegg_ctx
,
input
->
video_track
,
0
))
goto
fail
;
input
->
vpx_input_ctx
->
framerate
.
numerator
=
(
i
-
1
)
*
1000000
;
input
->
vpx_input_ctx
->
framerate
.
denominator
=
(
int
)(
tstamp
/
1000
);
return
0
;
fail:
nestegg_destroy
(
input
->
nestegg_ctx
);
input
->
nestegg_ctx
=
NULL
;
rewind
(
input
->
vpx_input_ctx
->
file
);
return
1
;
}
static
int
file_is_webm
(
struct
VpxDecInputContext
*
input
)
{
unsigned
int
i
,
n
;
int
track_type
=
-
1
;
int
codec_id
;
nestegg_io
io
=
{
nestegg_read_cb
,
nestegg_seek_cb
,
nestegg_tell_cb
,
0
};
nestegg_video_params
params
;
io
.
userdata
=
input
->
vpx_input_ctx
->
file
;
if
(
nestegg_init
(
&
input
->
nestegg_ctx
,
io
,
NULL
))
goto
fail
;
if
(
nestegg_track_count
(
input
->
nestegg_ctx
,
&
n
))
goto
fail
;
for
(
i
=
0
;
i
<
n
;
i
++
)
{
track_type
=
nestegg_track_type
(
input
->
nestegg_ctx
,
i
);
if
(
track_type
==
NESTEGG_TRACK_VIDEO
)
break
;
else
if
(
track_type
<
0
)
goto
fail
;
}
codec_id
=
nestegg_track_codec_id
(
input
->
nestegg_ctx
,
i
);
if
(
codec_id
==
NESTEGG_CODEC_VP8
)
{
input
->
vpx_input_ctx
->
fourcc
=
VP8_FOURCC_MASK
;
}
else
if
(
codec_id
==
NESTEGG_CODEC_VP9
)
{
input
->
vpx_input_ctx
->
fourcc
=
VP9_FOURCC_MASK
;
}
else
{
fprintf
(
stderr
,
"Not VPx video, quitting.
\n
"
);
exit
(
1
);
}
input
->
video_track
=
i
;
if
(
nestegg_track_video_params
(
input
->
nestegg_ctx
,
i
,
&
params
))
goto
fail
;
input
->
vpx_input_ctx
->
framerate
.
denominator
=
0
;
input
->
vpx_input_ctx
->
framerate
.
numerator
=
0
;
input
->
vpx_input_ctx
->
width
=
params
.
width
;
input
->
vpx_input_ctx
->
height
=
params
.
height
;
return
1
;
fail:
input
->
nestegg_ctx
=
NULL
;
rewind
(
input
->
vpx_input_ctx
->
file
);
return
0
;
}
void
show_progress
(
int
frame_in
,
int
frame_out
,
unsigned
long
dx_time
)
{
fprintf
(
stderr
,
"%d decoded frames/%d showed frames in %lu us (%.2f fps)
\r
"
,
frame_in
,
frame_out
,
dx_time
,
(
float
)
frame_out
*
1000000
.
0
/
(
float
)
dx_time
);
}
void
generate_filename
(
const
char
*
pattern
,
char
*
out
,
size_t
q_len
,
unsigned
int
d_w
,
unsigned
int
d_h
,
unsigned
int
frame_in
)
{
...
...
@@ -606,7 +432,9 @@ int main_loop(int argc, const char **argv_) {
struct
VpxDecInputContext
input
=
{
0
};
struct
VpxInputContext
vpx_input_ctx
=
{
0
};
struct
WebmInputContext
webm_ctx
=
{
0
};
input
.
vpx_input_ctx
=
&
vpx_input_ctx
;
input
.
webm_ctx
=
&
webm_ctx
;
/* Parse command line */
exec_name
=
argv_
[
0
];
...
...
@@ -748,7 +576,7 @@ int main_loop(int argc, const char **argv_) {
input
.
vpx_input_ctx
->
file
=
infile
;
if
(
file_is_ivf
(
input
.
vpx_input_ctx
))
input
.
vpx_input_ctx
->
file_type
=
FILE_TYPE_IVF
;
else
if
(
file_is_webm
(
&
input
))
else
if
(
file_is_webm
(
input
.
webm_ctx
,
input
.
vpx_
input
_ctx
))
input
.
vpx_input_ctx
->
file_type
=
FILE_TYPE_WEBM
;
else
if
(
file_is_raw
(
input
.
vpx_input_ctx
))
input
.
vpx_input_ctx
->
file_type
=
FILE_TYPE_RAW
;
...
...
@@ -792,7 +620,7 @@ int main_loop(int argc, const char **argv_) {
}
if
(
vpx_input_ctx
.
file_type
==
FILE_TYPE_WEBM
)
if
(
webm_guess_framerate
(
&
input
))
{
if
(
webm_guess_framerate
(
input
.
webm_ctx
,
input
.
vpx_
input
_ctx
))
{
fprintf
(
stderr
,
"Failed to guess framerate -- error parsing "
"webm file?
\n
"
);
return
EXIT_FAILURE
;
...
...
@@ -1036,10 +864,11 @@ fail:
if
(
single_file
&&
!
noblit
)
out_close
(
out
,
outfile
,
do_md5
);
if
(
input
.
nestegg_ctx
)
nestegg_destroy
(
input
.
nestegg
_ctx
);
if
(
input
.
vpx_input_ctx
->
file_type
!=
FILE_TYPE_WEBM
)
if
(
input
.
vpx_input_ctx
->
file_type
==
FILE_TYPE_WEBM
)
webm_free
(
input
.
webm
_ctx
);
else
free
(
buf
);
fclose
(
infile
);
free
(
argv
);
...
...
webmdec.c
0 → 100644
View file @
a944deae
/*
* Copyright (c) 2013 The WebM project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include
"./webmdec.h"
#include
<stdarg.h>
#include
"nestegg/include/nestegg/nestegg.h"
static
int
nestegg_read_cb
(
void
*
buffer
,
size_t
length
,
void
*
userdata
)
{
FILE
*
f
=
userdata
;
if
(
fread
(
buffer
,
1
,
length
,
f
)
<
length
)
{
if
(
ferror
(
f
))
return
-
1
;
if
(
feof
(
f
))
return
0
;
}
return
1
;
}
static
int
nestegg_seek_cb
(
int64_t
offset
,
int
whence
,
void
*
userdata
)
{
switch
(
whence
)
{
case
NESTEGG_SEEK_SET
:
whence
=
SEEK_SET
;
break
;
case
NESTEGG_SEEK_CUR
:
whence
=
SEEK_CUR
;
break
;
case
NESTEGG_SEEK_END
:
whence
=
SEEK_END
;
break
;
};
return
fseek
(
userdata
,
(
int32_t
)
offset
,
whence
)
?
-
1
:
0
;
}
static
int64_t
nestegg_tell_cb
(
void
*
userdata
)
{
return
ftell
(
userdata
);
}
static
void
nestegg_log_cb
(
nestegg
*
context
,
unsigned
int
severity
,
char
const
*
format
,
...)
{
va_list
ap
;
va_start
(
ap
,
format
);
vfprintf
(
stderr
,
format
,
ap
);
fprintf
(
stderr
,
"
\n
"
);
va_end
(
ap
);
}
int
file_is_webm
(
struct
WebmInputContext
*
webm_ctx
,
struct
VpxInputContext
*
vpx_ctx
)
{
uint32_t
i
,
n
;
int
track_type
=
-
1
;
int
codec_id
;
nestegg_io
io
=
{
nestegg_read_cb
,
nestegg_seek_cb
,
nestegg_tell_cb
,
0
};
nestegg_video_params
params
;
io
.
userdata
=
vpx_ctx
->
file
;
if
(
nestegg_init
(
&
webm_ctx
->
nestegg_ctx
,
io
,
NULL
))
goto
fail
;
if
(
nestegg_track_count
(
webm_ctx
->
nestegg_ctx
,
&
n
))
goto
fail
;
for
(
i
=
0
;
i
<
n
;
i
++
)
{
track_type
=
nestegg_track_type
(
webm_ctx
->
nestegg_ctx
,
i
);
if
(
track_type
==
NESTEGG_TRACK_VIDEO
)
break
;
else
if
(
track_type
<
0
)
goto
fail
;
}
codec_id
=
nestegg_track_codec_id
(
webm_ctx
->
nestegg_ctx
,
i
);
if
(
codec_id
==
NESTEGG_CODEC_VP8
)
{
vpx_ctx
->
fourcc
=
VP8_FOURCC_MASK
;
}
else
if
(
codec_id
==
NESTEGG_CODEC_VP9
)
{
vpx_ctx
->
fourcc
=
VP9_FOURCC_MASK
;
}
else
{
fatal
(
"Not VPx video, quitting.
\n
"
);
}
webm_ctx
->
video_track
=
i
;
if
(
nestegg_track_video_params
(
webm_ctx
->
nestegg_ctx
,
i
,
&
params
))
goto
fail
;
vpx_ctx
->
framerate
.
denominator
=
0
;
vpx_ctx
->
framerate
.
numerator
=
0
;
vpx_ctx
->
width
=
params
.
width
;
vpx_ctx
->
height
=
params
.
height
;
return
1
;
fail:
webm_ctx
->
nestegg_ctx
=
NULL
;
rewind
(
vpx_ctx
->
file
);
return
0
;
}
int
webm_read_frame
(
struct
WebmInputContext
*
webm_ctx
,
uint8_t
**
buffer
,
size_t
*
bytes_in_buffer
,
size_t
*
buffer_size
)
{
if
(
webm_ctx
->
chunk
>=
webm_ctx
->
chunks
)
{
uint32_t
track
;
do
{
/* End of this packet, get another. */
if
(
webm_ctx
->
pkt
)
nestegg_free_packet
(
webm_ctx
->
pkt
);
if
(
nestegg_read_packet
(
webm_ctx
->
nestegg_ctx
,
&
webm_ctx
->
pkt
)
<=
0
||
nestegg_packet_track
(
webm_ctx
->
pkt
,
&
track
))
{
return
1
;
}
}
while
(
track
!=
webm_ctx
->
video_track
);
if
(
nestegg_packet_count
(
webm_ctx
->
pkt
,
&
webm_ctx
->
chunks
))
return
1
;
webm_ctx
->
chunk
=
0
;
}
if
(
nestegg_packet_data
(
webm_ctx
->
pkt
,
webm_ctx
->
chunk
,
buffer
,
bytes_in_buffer
))
{
return
1
;
}
webm_ctx
->
chunk
++
;
return
0
;
}
int
webm_guess_framerate
(
struct
WebmInputContext
*
webm_ctx
,
struct
VpxInputContext
*
vpx_ctx
)
{
uint32_t
i
;
uint64_t
tstamp
=
0
;
/* Check to see if we can seek before we parse any data. */
if
(
nestegg_track_seek
(
webm_ctx
->
nestegg_ctx
,
webm_ctx
->
video_track
,
0
))
{
warn
(
"Failed to guess framerate (no Cues), set to 30fps.
\n
"
);
vpx_ctx
->
framerate
.
numerator
=
30
;
vpx_ctx
->
framerate
.
denominator
=
1
;
return
0
;
}
/* Guess the framerate. Read up to 1 second, or 50 video packets,
* whichever comes first.
*/
for
(
i
=
0
;
tstamp
<
1000000000
&&
i
<
50
;)
{
nestegg_packet
*
pkt
;
uint32_t
track
;
if
(
nestegg_read_packet
(
webm_ctx
->
nestegg_ctx
,
&
pkt
)
<=
0
)
break
;
nestegg_packet_track
(
pkt
,
&
track
);
if
(
track
==
webm_ctx
->
video_track
)
{
nestegg_packet_tstamp
(
pkt
,
&
tstamp
);
++
i
;
}
nestegg_free_packet
(
pkt
);
}
if
(
nestegg_track_seek
(
webm_ctx
->
nestegg_ctx
,
webm_ctx
->
video_track
,
0
))
goto
fail
;
vpx_ctx
->
framerate
.
numerator
=
(
i
-
1
)
*
1000000
;
vpx_ctx
->
framerate
.
denominator
=
(
int
)(
tstamp
/
1000
);
return
0
;
fail:
nestegg_destroy
(
webm_ctx
->
nestegg_ctx
);
webm_ctx
->
nestegg_ctx
=
NULL
;
rewind
(
vpx_ctx
->
file
);
return
1
;
}
void
webm_free
(
struct
WebmInputContext
*
webm_ctx
)
{
if
(
webm_ctx
&&
webm_ctx
->
nestegg_ctx
)
nestegg_destroy
(
webm_ctx
->
nestegg_ctx
);
}
webmdec.h
0 → 100644
View file @
a944deae
/*
* Copyright (c) 2013 The WebM project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef WEBMDEC_H_
#define WEBMDEC_H_
#include
"./tools_common.h"
struct
nestegg
;
struct
nestegg_packet
;
struct
VpxInputContext
;
struct
WebmInputContext
{
uint32_t
chunk
;
uint32_t
chunks
;
uint32_t
video_track
;
struct
nestegg
*
nestegg_ctx
;
struct
nestegg_packet
*
pkt
;
};
int
file_is_webm
(
struct
WebmInputContext
*
webm_ctx
,
struct
VpxInputContext
*
vpx_ctx
);
int
webm_read_frame
(
struct
WebmInputContext
*
webm_ctx
,
uint8_t
**
buffer
,
size_t
*
bytes_in_buffer
,
size_t
*
buffer_size
);
int
webm_guess_framerate
(
struct
WebmInputContext
*
webm_ctx
,
struct
VpxInputContext
*
vpx_ctx
);
void
webm_free
(
struct
WebmInputContext
*
webm_ctx
);
#endif // WEBMDEC_H_
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new 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