Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gst-plugins-base
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Service Desk
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Incidents
Environments
Packages & Registries
Packages & Registries
Container Registry
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Sebastian Dröge
gst-plugins-base
Commits
3cb94849
Commit
3cb94849
authored
Jul 31, 2009
by
David Schleef
Committed by
Benjamin Otte
Oct 15, 2009
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
theora: Convert theoradec to libtheora 1.0 API
https://bugzilla.gnome.org/show_bug.cgi?id=594729
parent
7e15bb66
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
80 additions
and
82 deletions
+80
-82
ext/theora/gsttheoradec.h
ext/theora/gsttheoradec.h
+6
-4
ext/theora/theoradec.c
ext/theora/theoradec.c
+74
-78
No files found.
ext/theora/gsttheoradec.h
View file @
3cb94849
...
...
@@ -25,7 +25,7 @@
#endif
#include <gst/gst.h>
#include <theora/theora.h>
#include <theora/theora
dec
.h>
#include <string.h>
G_BEGIN_DECLS
...
...
@@ -58,9 +58,11 @@ struct _GstTheoraDec
GstPad
*
srcpad
;
/* theora decoder state */
theora_state
state
;
theora_info
info
;
theora_comment
comment
;
th_dec_ctx
*
decoder
;
//theora_state state;
th_setup_info
*
setup
;
th_info
info
;
th_comment
comment
;
gboolean
have_header
;
gboolean
is_old_bitstream
;
...
...
ext/theora/theoradec.c
View file @
3cb94849
...
...
@@ -202,18 +202,6 @@ gst_theora_dec_reset (GstTheoraDec * dec)
}
}
static
int
_theora_ilog
(
unsigned
int
v
)
{
int
ret
=
0
;
while
(
v
)
{
ret
++
;
v
>>=
1
;
}
return
(
ret
);
}
/* Return the frame number (starting from zero) corresponding to this
* granulepos */
static
gint64
...
...
@@ -347,7 +335,7 @@ theora_dec_src_convert (GstPad * pad,
switch
(
*
dest_format
)
{
case
GST_FORMAT_DEFAULT
:
*
dest_value
=
gst_util_uint64_scale_int
(
src_value
,
8
,
dec
->
info
.
height
*
dec
->
info
.
width
*
dec
->
output_bpp
);
dec
->
info
.
pic_height
*
dec
->
info
.
pic_
width
*
dec
->
output_bpp
);
break
;
case
GST_FORMAT_TIME
:
/* seems like a rather silly conversion, implement me if you like */
...
...
@@ -358,7 +346,9 @@ theora_dec_src_convert (GstPad * pad,
case
GST_FORMAT_TIME
:
switch
(
*
dest_format
)
{
case
GST_FORMAT_BYTES
:
scale
=
dec
->
output_bpp
*
(
dec
->
info
.
width
*
dec
->
info
.
height
)
/
8
;
scale
=
dec
->
output_bpp
*
(
dec
->
info
.
pic_width
*
dec
->
info
.
pic_height
)
/
8
;
case
GST_FORMAT_DEFAULT
:
*
dest_value
=
scale
*
gst_util_uint64_scale
(
src_value
,
dec
->
info
.
fps_numerator
,
dec
->
info
.
fps_denominator
*
GST_SECOND
);
...
...
@@ -375,7 +365,7 @@ theora_dec_src_convert (GstPad * pad,
break
;
case
GST_FORMAT_BYTES
:
*
dest_value
=
gst_util_uint64_scale_int
(
src_value
,
dec
->
output_bpp
*
dec
->
info
.
width
*
dec
->
info
.
height
,
8
);
dec
->
output_bpp
*
dec
->
info
.
pic_width
*
dec
->
info
.
pic_
height
,
8
);
break
;
default:
res
=
FALSE
;
...
...
@@ -437,7 +427,7 @@ theora_dec_sink_convert (GstPad * pad,
dec
->
info
.
fps_numerator
,
GST_SECOND
*
dec
->
info
.
fps_denominator
);
/* funny way of calculating granulepos in theora */
rest
=
*
dest_value
/
dec
->
info
.
keyframe_
frequency_force
;
rest
=
*
dest_value
/
dec
->
info
.
keyframe_
granule_shift
;
*
dest_value
-=
rest
;
*
dest_value
<<=
dec
->
granule_shift
;
*
dest_value
+=
rest
;
...
...
@@ -895,47 +885,45 @@ theora_handle_type_packet (GstTheoraDec * dec, ogg_packet * packet)
/* theora has:
*
* width/height : dimension of the encoded frame
*
frame_width/frame
_height : dimension of the visible part
*
offset_x/offset
_y : offset in encoded frame where visible part starts
*
pic_width/pic
_height : dimension of the visible part
*
pic_x/pic
_y : offset in encoded frame where visible part starts
*/
GST_DEBUG_OBJECT
(
dec
,
"dimension %dx%d, PAR %d/%d"
,
dec
->
info
.
width
,
dec
->
info
.
height
,
par_num
,
par_den
);
GST_DEBUG_OBJECT
(
dec
,
"dimension %dx%d, PAR %d/%d"
,
dec
->
info
.
pic_
width
,
dec
->
info
.
pic_
height
,
par_num
,
par_den
);
GST_DEBUG_OBJECT
(
dec
,
"frame dimension %dx%d, offset %d:%d"
,
dec
->
info
.
frame_width
,
dec
->
info
.
frame
_height
,
dec
->
info
.
offset_x
,
dec
->
info
.
offset
_y
);
dec
->
info
.
pic_width
,
dec
->
info
.
pic
_height
,
dec
->
info
.
pic_x
,
dec
->
info
.
pic
_y
);
if
(
dec
->
info
.
pixel
format
==
OC
_PF_420
)
{
if
(
dec
->
info
.
pixel
_fmt
==
TH
_PF_420
)
{
dec
->
output_bpp
=
12
;
/* Average bits per pixel. */
fourcc
=
GST_MAKE_FOURCC
(
'I'
,
'4'
,
'2'
,
'0'
);
}
else
if
(
dec
->
info
.
pixel
format
==
OC
_PF_422
)
{
}
else
if
(
dec
->
info
.
pixel
_fmt
==
TH
_PF_422
)
{
dec
->
output_bpp
=
16
;
fourcc
=
GST_MAKE_FOURCC
(
'Y'
,
'4'
,
'2'
,
'B'
);
}
else
if
(
dec
->
info
.
pixel
format
==
OC
_PF_444
)
{
}
else
if
(
dec
->
info
.
pixel
_fmt
==
TH
_PF_444
)
{
dec
->
output_bpp
=
24
;
fourcc
=
GST_MAKE_FOURCC
(
'Y'
,
'4'
,
'4'
,
'4'
);
}
else
{
GST_ERROR_OBJECT
(
dec
,
"Invalid pixel format %d"
,
dec
->
info
.
pixel
forma
t
);
GST_ERROR_OBJECT
(
dec
,
"Invalid pixel format %d"
,
dec
->
info
.
pixel
_fm
t
);
return
GST_FLOW_ERROR
;
}
if
(
dec
->
crop
)
{
/* add black borders to make width/height/offsets even. we need this because
* we cannot express an offset to the peer plugin. */
dec
->
width
=
GST_ROUND_UP_2
(
dec
->
info
.
frame_width
+
(
dec
->
info
.
offset_x
&
1
));
dec
->
height
=
GST_ROUND_UP_2
(
dec
->
info
.
frame_height
+
(
dec
->
info
.
offset_y
&
1
));
dec
->
offset_x
=
dec
->
info
.
offset_x
&
~
1
;
dec
->
offset_y
=
dec
->
info
.
offset_y
&
~
1
;
dec
->
width
=
GST_ROUND_UP_2
(
dec
->
info
.
pic_width
+
(
dec
->
info
.
pic_x
&
1
));
dec
->
height
=
GST_ROUND_UP_2
(
dec
->
info
.
pic_height
+
(
dec
->
info
.
pic_y
&
1
));
dec
->
offset_x
=
dec
->
info
.
pic_x
&
~
1
;
dec
->
offset_y
=
dec
->
info
.
pic_y
&
~
1
;
}
else
{
/* no cropping, use the encoded dimensions */
dec
->
width
=
dec
->
info
.
width
;
dec
->
height
=
dec
->
info
.
height
;
dec
->
width
=
dec
->
info
.
pic_
width
;
dec
->
height
=
dec
->
info
.
pic_
height
;
dec
->
offset_x
=
0
;
dec
->
offset_y
=
0
;
}
dec
->
granule_shift
=
_theora_ilog
(
dec
->
info
.
keyframe_frequency_force
-
1
)
;
dec
->
granule_shift
=
dec
->
info
.
keyframe_granule_shift
;
/* With libtheora-1.0beta1 the granulepos scheme was changed:
* where earlier the granulepos refered to the index/beginning
...
...
@@ -951,7 +939,7 @@ theora_handle_type_packet (GstTheoraDec * dec, ogg_packet * packet)
dec
->
width
,
dec
->
height
,
dec
->
offset_x
,
dec
->
offset_y
);
/* done */
theora_decode_init
(
&
dec
->
state
,
&
dec
->
info
);
dec
->
decoder
=
th_decode_alloc
(
&
dec
->
info
,
dec
->
setup
);
caps
=
gst_caps_new_simple
(
"video/x-raw-yuv"
,
"format"
,
GST_TYPE_FOURCC
,
fourcc
,
...
...
@@ -984,10 +972,12 @@ static GstFlowReturn
theora_handle_header_packet
(
GstTheoraDec
*
dec
,
ogg_packet
*
packet
)
{
GstFlowReturn
res
;
int
ret
;
GST_DEBUG_OBJECT
(
dec
,
"parsing header packet"
);
if
(
theora_decode_header
(
&
dec
->
info
,
&
dec
->
comment
,
packet
))
ret
=
th_decode_headerin
(
&
dec
->
info
,
&
dec
->
comment
,
&
dec
->
setup
,
packet
);
if
(
ret
<
0
)
goto
header_read_error
;
switch
(
packet
->
packet
[
0
])
{
...
...
@@ -1133,7 +1123,8 @@ theora_dec_push_reverse (GstTheoraDec * dec, GstBuffer * buf)
/* Allocate buffer and copy image data into Y444 format */
static
GstFlowReturn
theora_handle_444_image
(
GstTheoraDec
*
dec
,
yuv_buffer
*
yuv
,
GstBuffer
**
out
)
theora_handle_444_image
(
GstTheoraDec
*
dec
,
th_ycbcr_buffer
buf
,
GstBuffer
**
out
)
{
gint
width
=
dec
->
width
;
gint
height
=
dec
->
height
;
...
...
@@ -1145,8 +1136,8 @@ theora_handle_444_image (GstTheoraDec * dec, yuv_buffer * yuv, GstBuffer ** out)
stride
=
GST_ROUND_UP_4
(
width
);
out_size
=
stride
*
height
*
3
;
/* now copy over the area contained in
offset_x,offset
_y,
*
frame_width, frame
_height */
/* now copy over the area contained in
pic_x, pic
_y,
*
pic_width, pic
_height */
result
=
gst_pad_alloc_buffer_and_set_caps
(
dec
->
srcpad
,
GST_BUFFER_OFFSET_NONE
,
out_size
,
GST_PAD_CAPS
(
dec
->
srcpad
),
out
);
...
...
@@ -1159,14 +1150,13 @@ theora_handle_444_image (GstTheoraDec * dec, yuv_buffer * yuv, GstBuffer ** out)
for
(
plane
=
0
;
plane
<
3
;
plane
++
)
{
dest
=
GST_BUFFER_DATA
(
*
out
)
+
plane
*
stride
*
height
;
src
=
(
plane
==
0
?
yuv
->
y
:
(
plane
==
1
?
yuv
->
u
:
yuv
->
v
))
+
dec
->
offset_x
+
dec
->
offset_y
*
yuv
->
y_stride
;
src
=
buf
[
plane
].
data
+
dec
->
offset_x
+
dec
->
offset_y
*
buf
[
plane
].
stride
;
for
(
i
=
0
;
i
<
height
;
i
++
)
{
memcpy
(
dest
,
src
,
width
);
dest
+=
stride
;
src
+=
yuv
->
y_
stride
;
src
+=
buf
[
0
].
stride
;
}
}
}
...
...
@@ -1182,7 +1172,8 @@ no_buffer:
/* Allocate buffer and copy image data into Y42B format */
static
GstFlowReturn
theora_handle_422_image
(
GstTheoraDec
*
dec
,
yuv_buffer
*
yuv
,
GstBuffer
**
out
)
theora_handle_422_image
(
GstTheoraDec
*
dec
,
th_ycbcr_buffer
buf
,
GstBuffer
**
out
)
{
gint
width
=
dec
->
width
;
gint
uvwidth
=
dec
->
width
/
2
;
...
...
@@ -1197,8 +1188,8 @@ theora_handle_422_image (GstTheoraDec * dec, yuv_buffer * yuv, GstBuffer ** out)
uvstride
=
GST_ROUND_UP_8
(
width
)
/
2
;
out_size
=
ystride
*
height
+
uvstride
*
height
*
2
;
/* now copy over the area contained in
offset_x,offset
_y,
*
frame_width, frame
_height */
/* now copy over the area contained in
pic_x, pic
_y,
*
pic_width, pic
_height */
result
=
gst_pad_alloc_buffer_and_set_caps
(
dec
->
srcpad
,
GST_BUFFER_OFFSET_NONE
,
out_size
,
GST_PAD_CAPS
(
dec
->
srcpad
),
out
);
...
...
@@ -1207,24 +1198,24 @@ theora_handle_422_image (GstTheoraDec * dec, yuv_buffer * yuv, GstBuffer ** out)
dst
=
GST_BUFFER_DATA
(
*
out
);
src
=
yuv
->
y
;
src
=
buf
[
0
].
data
;
for
(
i
=
0
;
i
<
height
;
i
++
)
{
memcpy
(
dst
,
src
,
width
);
src
+=
yuv
->
y_
stride
;
src
+=
buf
[
0
].
stride
;
dst
+=
ystride
;
}
src
=
yuv
->
u
;
src
=
buf
[
1
].
data
;
for
(
i
=
0
;
i
<
height
;
i
++
)
{
memcpy
(
dst
,
src
,
uvwidth
);
src
+=
yuv
->
uv_
stride
;
src
+=
buf
[
1
].
stride
;
dst
+=
uvstride
;
}
src
=
yuv
->
v
;
src
=
buf
[
2
].
data
;
for
(
i
=
0
;
i
<
height
;
i
++
)
{
memcpy
(
dst
,
src
,
uvwidth
);
src
+=
yuv
->
uv_
stride
;
src
+=
buf
[
2
].
stride
;
dst
+=
uvstride
;
}
...
...
@@ -1238,7 +1229,8 @@ no_buffer:
/* Allocate buffer and copy image data into I420 format */
static
GstFlowReturn
theora_handle_420_image
(
GstTheoraDec
*
dec
,
yuv_buffer
*
yuv
,
GstBuffer
**
out
)
theora_handle_420_image
(
GstTheoraDec
*
dec
,
th_ycbcr_buffer
buf
,
GstBuffer
**
out
)
{
gint
width
=
dec
->
width
;
gint
height
=
dec
->
height
;
...
...
@@ -1258,8 +1250,8 @@ theora_handle_420_image (GstTheoraDec * dec, yuv_buffer * yuv, GstBuffer ** out)
out_size
=
stride_y
*
GST_ROUND_UP_2
(
height
)
+
stride_uv
*
GST_ROUND_UP_2
(
height
);
/* now copy over the area contained in
offset_x,offset
_y,
*
frame_width, frame
_height */
/* now copy over the area contained in
pic_x, pic
_y,
*
pic_width, pic
_height */
result
=
gst_pad_alloc_buffer_and_set_caps
(
dec
->
srcpad
,
GST_BUFFER_OFFSET_NONE
,
out_size
,
GST_PAD_CAPS
(
dec
->
srcpad
),
out
);
...
...
@@ -1289,28 +1281,28 @@ theora_handle_420_image (GstTheoraDec * dec, yuv_buffer * yuv, GstBuffer ** out)
GST_LOG_OBJECT
(
dec
,
"plane 2, offset %"
G_GINT64_FORMAT
,
(
gint64
)
(
dest_v
-
dest_y
));
src_y
=
yuv
->
y
+
dec
->
offset_x
+
dec
->
offset_y
*
yuv
->
y_
stride
;
src_y
=
buf
[
0
].
data
+
dec
->
offset_x
+
dec
->
offset_y
*
buf
[
0
].
stride
;
for
(
i
=
0
;
i
<
height
;
i
++
)
{
memcpy
(
dest_y
,
src_y
,
width
);
dest_y
+=
stride_y
;
src_y
+=
yuv
->
y_
stride
;
src_y
+=
buf
[
0
].
stride
;
}
offset
=
dec
->
offset_x
/
2
+
dec
->
offset_y
/
2
*
yuv
->
uv_
stride
;
offset
=
dec
->
offset_x
/
2
+
dec
->
offset_y
/
2
*
buf
[
1
].
stride
;
src_u
=
yuv
->
u
+
offset
;
src_v
=
yuv
->
v
+
offset
;
src_u
=
buf
[
1
].
data
+
offset
;
src_v
=
buf
[
2
].
data
+
offset
;
for
(
i
=
0
;
i
<
cheight
;
i
++
)
{
memcpy
(
dest_u
,
src_u
,
cwidth
);
memcpy
(
dest_v
,
src_v
,
cwidth
);
dest_u
+=
stride_uv
;
src_u
+=
yuv
->
uv_
stride
;
src_u
+=
buf
[
1
].
stride
;
dest_v
+=
stride_uv
;
src_v
+=
yuv
->
uv_
stride
;
src_v
+=
buf
[
2
].
stride
;
}
}
return
result
;
...
...
@@ -1329,10 +1321,11 @@ theora_handle_data_packet (GstTheoraDec * dec, ogg_packet * packet,
GstClockTime
outtime
)
{
/* normal data packet */
yuv_buffer
yuv
;
th_ycbcr_buffer
buf
;
GstBuffer
*
out
;
gboolean
keyframe
;
GstFlowReturn
result
;
ogg_int64_t
gp
;
if
(
G_UNLIKELY
(
!
dec
->
have_header
))
goto
not_initialized
;
...
...
@@ -1350,7 +1343,7 @@ theora_handle_data_packet (GstTheoraDec * dec, ogg_packet * packet,
GST_DEBUG_OBJECT
(
dec
,
"parsing data packet"
);
/* this does the decoding */
if
(
G_UNLIKELY
(
th
eora_decode_packetin
(
&
dec
->
state
,
packet
)
))
if
(
G_UNLIKELY
(
th
_decode_packetin
(
dec
->
decoder
,
packet
,
&
gp
)
<
0
))
goto
decode_error
;
if
(
outtime
!=
-
1
)
{
...
...
@@ -1375,19 +1368,19 @@ theora_handle_data_packet (GstTheoraDec * dec, ogg_packet * packet,
/* this does postprocessing and set up the decoded frame
* pointers in our yuv variable */
if
(
G_UNLIKELY
(
th
eora_decode_YUVout
(
&
dec
->
state
,
&
yuv
)
<
0
))
if
(
G_UNLIKELY
(
th
_decode_ycbcr_out
(
dec
->
decoder
,
buf
)
<
0
))
goto
no_yuv
;
if
(
G_UNLIKELY
((
yuv
.
y_width
!=
dec
->
info
.
width
)
||
(
yuv
.
y_height
!=
dec
->
info
.
height
)))
if
(
G_UNLIKELY
((
buf
[
0
].
width
!=
dec
->
info
.
frame_
width
)
||
(
buf
[
0
].
height
!=
dec
->
info
.
frame_
height
)))
goto
wrong_dimensions
;
if
(
dec
->
info
.
pixel
format
==
OC
_PF_420
)
{
result
=
theora_handle_420_image
(
dec
,
&
yuv
,
&
out
);
}
else
if
(
dec
->
info
.
pixel
format
==
OC
_PF_422
)
{
result
=
theora_handle_422_image
(
dec
,
&
yuv
,
&
out
);
}
else
if
(
dec
->
info
.
pixel
format
==
OC
_PF_444
)
{
result
=
theora_handle_444_image
(
dec
,
&
yuv
,
&
out
);
if
(
dec
->
info
.
pixel
_fmt
==
TH
_PF_420
)
{
result
=
theora_handle_420_image
(
dec
,
buf
,
&
out
);
}
else
if
(
dec
->
info
.
pixel
_fmt
==
TH
_PF_422
)
{
result
=
theora_handle_422_image
(
dec
,
buf
,
&
out
);
}
else
if
(
dec
->
info
.
pixel
_fmt
==
TH
_PF_444
)
{
result
=
theora_handle_444_image
(
dec
,
buf
,
&
out
);
}
else
{
g_assert_not_reached
();
}
...
...
@@ -1718,8 +1711,8 @@ theora_dec_change_state (GstElement * element, GstStateChange transition)
case
GST_STATE_CHANGE_NULL_TO_READY
:
break
;
case
GST_STATE_CHANGE_READY_TO_PAUSED
:
th
eora_info_init
(
&
dec
->
info
);
th
eora_comment_init
(
&
dec
->
comment
);
th
_info_clear
(
&
dec
->
info
);
th
_comment_clear
(
&
dec
->
comment
);
GST_DEBUG_OBJECT
(
dec
,
"Setting have_header to FALSE in READY->PAUSED"
);
dec
->
have_header
=
FALSE
;
dec
->
have_par
=
FALSE
;
...
...
@@ -1737,9 +1730,12 @@ theora_dec_change_state (GstElement * element, GstStateChange transition)
case
GST_STATE_CHANGE_PLAYING_TO_PAUSED
:
break
;
case
GST_STATE_CHANGE_PAUSED_TO_READY
:
theora_clear
(
&
dec
->
state
);
theora_comment_clear
(
&
dec
->
comment
);
theora_info_clear
(
&
dec
->
info
);
th_info_clear
(
&
dec
->
info
);
th_comment_clear
(
&
dec
->
comment
);
th_setup_free
(
dec
->
setup
);
dec
->
setup
=
NULL
;
th_decode_free
(
dec
->
decoder
);
dec
->
decoder
=
NULL
;
gst_theora_dec_reset
(
dec
);
break
;
case
GST_STATE_CHANGE_READY_TO_NULL
:
...
...
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