2 * Copyright (C) 2008 David Schleef <ds@schleef.org>
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
26 #include "gstbasevideoutils.h"
30 gst_base_video_convert_bytes_to_frames (GstVideoState
*state
,
33 return gst_util_uint64_scale_int (bytes
, 1, state
->bytes_per_picture
);
37 gst_base_video_convert_frames_to_bytes (GstVideoState
*state
,
40 return frames
* state
->bytes_per_picture
;
45 gst_base_video_rawvideo_convert (GstVideoState
*state
,
46 GstFormat src_format
, gint64 src_value
,
47 GstFormat
* dest_format
, gint64
*dest_value
)
51 if (src_format
== *dest_format
) {
52 *dest_value
= src_value
;
56 if (src_format
== GST_FORMAT_BYTES
&&
57 *dest_format
== GST_FORMAT_DEFAULT
) {
58 /* convert bytes to frames */
59 *dest_value
= gst_util_uint64_scale_int (src_value
, 1,
60 state
->bytes_per_picture
);
62 } else if (src_format
== GST_FORMAT_DEFAULT
&&
63 *dest_format
== GST_FORMAT_BYTES
) {
64 /* convert bytes to frames */
65 *dest_value
= src_value
* state
->bytes_per_picture
;
67 } else if (src_format
== GST_FORMAT_DEFAULT
&&
68 *dest_format
== GST_FORMAT_TIME
) {
69 /* convert frames to time */
70 /* FIXME add segment time? */
71 *dest_value
= gst_util_uint64_scale (src_value
,
72 GST_SECOND
* state
->fps_d
, state
->fps_n
);
74 } else if (src_format
== GST_FORMAT_TIME
&&
75 *dest_format
== GST_FORMAT_DEFAULT
) {
76 /* convert time to frames */
77 /* FIXME subtract segment time? */
78 *dest_value
= gst_util_uint64_scale (src_value
, state
->fps_n
,
79 GST_SECOND
* state
->fps_d
);
83 /* FIXME add bytes <--> time */
89 gst_base_video_encoded_video_convert (GstVideoState
*state
,
90 GstFormat src_format
, gint64 src_value
,
91 GstFormat
* dest_format
, gint64
*dest_value
)
95 if (src_format
== *dest_format
) {
96 *dest_value
= src_value
;
100 GST_ERROR("src convert");
103 if (src_format
== GST_FORMAT_DEFAULT
&& *dest_format
== GST_FORMAT_TIME
) {
104 if (dec
->fps_d
!= 0) {
105 *dest_value
= gst_util_uint64_scale (granulepos_to_frame (src_value
),
106 dec
->fps_d
* GST_SECOND
, dec
->fps_n
);
112 GST_ERROR("unhandled conversion from %d to %d", src_format
, *dest_format
);
121 gst_base_video_state_from_caps (GstVideoState
*state
, GstCaps
*caps
)
124 gst_video_format_parse_caps (caps
, &state
->format
,
125 &state
->width
, &state
->height
);
127 gst_video_parse_caps_framerate (caps
, &state
->fps_n
, &state
->fps_d
);
131 gst_video_parse_caps_pixel_aspect_ratio (caps
, &state
->par_n
,
134 /* FIXME handle this stuff some day */
135 state
->interlaced
= FALSE
;
137 state
->clean_width
= state
->width
;
138 state
->clean_height
= state
->height
;
139 state
->clean_offset_left
= 0;
140 state
->clean_offset_top
= 0;
142 /* FIXME need better error handling */
147 gst_video_state_get_timestamp (const GstVideoState
*state
, int frame_number
)
149 if (frame_number
< 0) {
150 return state
->segment
.start
-
151 (gint64
)gst_util_uint64_scale (-frame_number
,
152 state
->fps_d
* GST_SECOND
, state
->fps_n
);
154 return state
->segment
.start
+
155 gst_util_uint64_scale (frame_number
,
156 state
->fps_d
* GST_SECOND
, state
->fps_n
);
163 get_chunk (GstAdapter
*adapter
, int offset
, int *skip
)
171 g_return_val_if_fail (offset
>= 0, NULL
);
172 g_return_val_if_fail (offset
< adapter
->size
, NULL
);
174 offset
+= adapter
->skip
;
175 g
= adapter
->buflist
;
177 if (offset
< GST_BUFFER_SIZE(GST_BUFFER(g
->data
))) {
178 if (skip
) *skip
= offset
;
181 offset
-= GST_BUFFER_SIZE (GST_BUFFER(g
->data
));
185 g_assert_not_reached ();
189 gst_adapter_copy_full (GstAdapter
*adapter
, void *dest
, int offset
,
193 guint8
*cdest
= dest
;
197 g_return_if_fail (offset
>= 0);
198 g_return_if_fail (offset
+ size
<= adapter
->size
);
200 g
= get_chunk (adapter
, offset
, &skip
);
202 n_bytes
= MIN (GST_BUFFER_SIZE(GST_BUFFER(g
->data
)) - skip
,
205 memcpy (cdest
, GST_BUFFER_DATA(GST_BUFFER(g
->data
)) + skip
,
217 scan_fast (guint8
*data
, guint32 pattern
, guint32 mask
, int n
)
221 if ((GST_READ_UINT32_BE (data
+ i
) & mask
) == pattern
) {
229 scan_slow (GstAdapter
*adapter
, GSList
*g
, int skip
, guint32 pattern
,
236 tmp
[j
] = ((guint8
*)GST_BUFFER_DATA(GST_BUFFER(g
->data
)))[skip
];
238 if (skip
>= GST_BUFFER_SIZE (GST_BUFFER(g
->data
))) {
244 return ((GST_READ_UINT32_BE (tmp
) & mask
) == pattern
);
249 gst_adapter_masked_scan_uint32 (GstAdapter
*adapter
,
250 guint32 pattern
, guint32 mask
, int offset
, int n
)
258 g_return_val_if_fail (n
>= 0, 0);
259 g_return_val_if_fail (offset
>= 0, 0);
260 g_return_val_if_fail (offset
+ n
+ 4 <= adapter
->size
, 0);
262 g
= get_chunk (adapter
, offset
, &skip
);
265 m
= MIN (GST_BUFFER_SIZE(GST_BUFFER(g
->data
)) - skip
- 4, 0);
267 k
= scan_fast (GST_BUFFER_DATA(GST_BUFFER(g
->data
)) + skip
,
275 if (scan_slow (adapter
, g
, skip
, pattern
, mask
)) {
281 if (skip
>= GST_BUFFER_SIZE (GST_BUFFER(g
->data
))) {
291 gst_adapter_get_buffer (GstAdapter
*adapter
)
293 return gst_buffer_ref (GST_BUFFER(adapter
->buflist
->data
));