Branch data Line data Source code
1 : : /*
2 : : * This library is licensed under 2 different licenses and you
3 : : * can choose to use it under the terms of either one of them. The
4 : : * two licenses are the MPL 1.1 and the LGPL.
5 : : *
6 : : * MPL:
7 : : *
8 : : * The contents of this file are subject to the Mozilla Public License
9 : : * Version 1.1 (the "License"); you may not use this file except in
10 : : * compliance with the License. You may obtain a copy of the License at
11 : : * http://www.mozilla.org/MPL/.
12 : : *
13 : : * Software distributed under the License is distributed on an "AS IS"
14 : : * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
15 : : * License for the specific language governing rights and limitations
16 : : * under the License.
17 : : *
18 : : * LGPL:
19 : : *
20 : : * This library is free software; you can redistribute it and/or
21 : : * modify it under the terms of the GNU Library General Public
22 : : * License as published by the Free Software Foundation; either
23 : : * version 2 of the License, or (at your option) any later version.
24 : : *
25 : : * This library is distributed in the hope that it will be useful,
26 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
27 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
28 : : * Library General Public License for more details.
29 : : *
30 : : * You should have received a copy of the GNU Library General Public
31 : : * License along with this library; if not, write to the
32 : : * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
33 : : * Boston, MA 02111-1307, USA.
34 : : *
35 : : * The Original Code is Fluendo MPEG Demuxer plugin.
36 : : *
37 : : * The Initial Developer of the Original Code is Fluendo, S.L.
38 : : * Portions created by Fluendo, S.L. are Copyright (C) 2005
39 : : * Fluendo, S.L. All Rights Reserved.
40 : : *
41 : : * Contributor(s): Wim Taymans <wim@fluendo.com>
42 : : */
43 : :
44 : : #ifdef HAVE_CONFIG_H
45 : : #include "config.h"
46 : : #endif
47 : :
48 : : #include "gstsectionfilter.h"
49 : :
50 : : #ifndef __always_inline
51 : : #if (__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)
52 : : #define __always_inline inline __attribute__((always_inline))
53 : : #else
54 : : #define __always_inline inline
55 : : #endif
56 : : #endif
57 : :
58 : : #ifndef DISABLE_INLINE
59 : : #define FORCE_INLINE __always_inline
60 : : #else
61 : : #define FORCE_INLINE
62 : : #endif
63 : :
64 : : GST_DEBUG_CATEGORY (gstflusectionfilter_debug);
65 : : #define GST_CAT_DEFAULT (gstflusectionfilter_debug)
66 : :
67 : : void
68 : 0 : gst_section_filter_init (GstSectionFilter * filter)
69 : : {
70 [ # # ]: 0 : g_return_if_fail (filter != NULL);
71 : 0 : filter->adapter = gst_adapter_new ();
72 : : /* continuity counter can at max be 15
73 : : * we make 255 as an indication that
74 : : * there is no last continuity counter */
75 : 0 : filter->last_continuity_counter = 255;
76 : 0 : filter->section_length = G_MAXUINT16;
77 : : }
78 : :
79 : : void
80 : 0 : gst_section_filter_uninit (GstSectionFilter * filter)
81 : : {
82 [ # # ]: 0 : g_return_if_fail (filter != NULL);
83 [ # # ]: 0 : if (filter->adapter)
84 : 0 : g_object_unref (filter->adapter);
85 : 0 : filter->adapter = NULL;
86 : : }
87 : :
88 : : void
89 : 0 : gst_section_filter_clear (GstSectionFilter * filter)
90 : : {
91 [ # # ]: 0 : g_return_if_fail (filter != NULL);
92 [ # # ]: 0 : if (filter->adapter) {
93 : 0 : gst_adapter_clear (filter->adapter);
94 : 0 : filter->last_continuity_counter = 255;
95 : 0 : filter->section_length = G_MAXUINT16;
96 : : }
97 : : }
98 : :
99 : : static FORCE_INLINE gboolean
100 : : gst_section_is_complete (GstSectionFilter * filter)
101 : : {
102 : : /* section length measures size of section from 3 bytes into section
103 : : * (ie after section length field finished) until end of section)
104 : : */
105 : 0 : guint avail_bytes = gst_adapter_available (filter->adapter);
106 [ # # # # ]: 0 : if (filter->section_length == avail_bytes - 3) {
107 : 0 : return TRUE;
108 [ # # ][ # # ]: 0 : } else if (filter->section_length < (int) (avail_bytes - 3)) {
109 [ # # ][ # # ]: 0 : GST_DEBUG ("section length seems to be less than available bytes for "
110 : : "rest of section.");
111 : 0 : return TRUE;
112 : : }
113 : 0 : return FALSE;
114 : : }
115 : :
116 : : /* returns True when section finished and ready to parse */
117 : : /* FIXME: especially for multi-section tables, we need to handle pusi correctly
118 : : * and handle cases where a new section starts in the same transport packet.
119 : : */
120 : : gboolean
121 : 0 : gst_section_filter_push (GstSectionFilter * filter, gboolean pusi, /* determines whether start or not */
122 : : guint8 continuity_counter, GstBuffer * buf)
123 : : {
124 [ # # ]: 0 : g_return_val_if_fail (filter != NULL, FALSE);
125 : :
126 : : /* check if it's the first packet of a section or
127 : : * if it continues the section */
128 [ # # ]: 0 : if (pusi) {
129 : 0 : const guint8 *data = GST_BUFFER_DATA (buf);
130 [ # # ]: 0 : if (filter->last_continuity_counter != 255) {
131 [ # # ]: 0 : GST_WARNING ("section lost, last continuity counter: %d, "
132 : : "we now have a pusi at continuity counter: %d",
133 : : filter->last_continuity_counter, continuity_counter);
134 : 0 : gst_section_filter_clear (filter);
135 : : }
136 : 0 : filter->section_length = GST_READ_UINT16_BE (data + 1);
137 : 0 : filter->section_length &= 0x0fff;
138 [ # # ]: 0 : if (filter->section_length > 4093) {
139 [ # # ]: 0 : GST_DEBUG ("section length too big");
140 : 0 : goto failure;
141 : : }
142 : 0 : gst_adapter_push (filter->adapter, buf);
143 : 0 : filter->last_continuity_counter = continuity_counter;
144 : 0 : return gst_section_is_complete (filter);
145 [ # # ][ # # ]: 0 : } else if (filter->last_continuity_counter == continuity_counter - 1 ||
146 [ # # ]: 0 : (filter->last_continuity_counter == 15 && continuity_counter == 0)) {
147 [ # # ]: 0 : GST_DEBUG ("section still going, no pusi");
148 : 0 : gst_adapter_push (filter->adapter, buf);
149 : 0 : filter->last_continuity_counter = continuity_counter;
150 : 0 : return gst_section_is_complete (filter);
151 : : }
152 : : /* we have lost the section and we are not a start
153 : : * section, so clear what was in it */
154 : : else {
155 [ # # ]: 0 : GST_WARNING ("section lost, last continuity counter: %d, "
156 : : "new continuity counter but not pusi: %d",
157 : : filter->last_continuity_counter, continuity_counter);
158 : 0 : gst_section_filter_clear (filter);
159 : 0 : goto failure;
160 : : }
161 : : failure:
162 : 0 : gst_buffer_unref (buf);
163 : 0 : return FALSE;
164 : : }
|