ts_parser.cpp revision f84ff736ed4e9e3c52a6341f7f2f5f325d8b5bab
1/*-------------------------------------------------------------------------- 2Copyright (c) 2010-2013, The Linux Foundation. All rights reserved. 3 4Redistribution and use in source and binary forms, with or without 5modification, are permitted provided that the following conditions are met: 6 * Redistributions of source code must retain the above copyright 7 notice, this list of conditions and the following disclaimer. 8 * Redistributions in binary form must reproduce the above copyright 9 notice, this list of conditions and the following disclaimer in the 10 documentation and/or other materials provided with the distribution. 11 * Neither the name of The Linux Foundation nor 12 the names of its contributors may be used to endorse or promote 13 products derived from this software without specific prior written 14 permission. 15 16THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 20CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 21EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 22PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 23OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 24WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 25OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 26ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27--------------------------------------------------------------------------*/ 28#include "ts_parser.h" 29 30#define DEBUG ALOGE 31void omx_time_stamp_reorder::set_timestamp_reorder_mode(bool mode) 32{ 33 reorder_ts = mode; 34} 35 36void omx_time_stamp_reorder::enable_debug_print(bool flag) 37{ 38 print_debug = flag; 39} 40 41omx_time_stamp_reorder::~omx_time_stamp_reorder() 42{ 43 delete_list(); 44} 45 46omx_time_stamp_reorder::omx_time_stamp_reorder() 47{ 48 reorder_ts = false; 49 phead = pcurrent = NULL; 50 error = false; 51 print_debug = false; 52} 53 54void omx_time_stamp_reorder::delete_list() 55{ 56 time_stamp_list *ptemp; 57 58 if (!phead) return; 59 60 while (phead->next != phead) { 61 ptemp = phead; 62 phead = phead->next; 63 phead->prev = ptemp->prev; 64 ptemp->prev->next = phead; 65 delete ptemp; 66 } 67 68 delete phead; 69 phead = NULL; 70} 71 72bool omx_time_stamp_reorder::get_current_list() 73{ 74 if (!phead) { 75 if (!add_new_list()) { 76 handle_error(); 77 return false; 78 } 79 } 80 81 pcurrent = phead->prev; 82 return true; 83} 84 85bool omx_time_stamp_reorder::update_head() 86{ 87 time_stamp_list *ptemp; 88 89 if (!phead) return false; 90 91 if (phead->next != phead) { 92 ptemp = phead; 93 phead = ptemp->next; 94 phead->prev = ptemp->prev; 95 ptemp->prev->next = phead; 96 delete ptemp; 97 } 98 99 return true; 100} 101 102bool omx_time_stamp_reorder::add_new_list() 103{ 104 bool status = true; 105 time_stamp_list *ptemp = NULL; 106 107 if (!phead) { 108 ptemp = phead = new time_stamp_list; 109 110 if (!phead) { 111 handle_error(); 112 status = false; 113 return status; 114 } 115 116 phead->prev = phead->next = phead; 117 } else { 118 ptemp = new time_stamp_list; 119 120 if (!ptemp) { 121 handle_error(); 122 status = false; 123 return status; 124 } 125 126 ptemp->prev = phead->prev; 127 ptemp->next = phead; 128 phead->prev->next = ptemp; 129 phead->prev = ptemp; 130 } 131 132 ptemp->entries_filled = 0; 133 134 for (int i=0; i < TIME_SZ; i++) { 135 ptemp->input_timestamps[i].in_use = false; 136 ptemp->input_timestamps[i].timestamps = -1; 137 } 138 139 return status; 140} 141 142bool omx_time_stamp_reorder::insert_timestamp(OMX_BUFFERHEADERTYPE *header) 143{ 144 OMX_TICKS *table_entry = NULL; 145 146 if (!reorder_ts || error || !header) { 147 if (error || !header) 148 DEBUG("\n Invalid condition in insert_timestamp %p", header); 149 150 return false; 151 } 152 153 if (!get_current_list()) { 154 handle_error(); 155 return false; 156 } 157 158 if (pcurrent->entries_filled > (TIME_SZ - 1)) { 159 DEBUG("\n Table full return error"); 160 handle_error(); 161 return false; 162 } 163 164 if (header->nFlags & OMX_BUFFERFLAG_CODECCONFIG) { 165 return true; 166 } 167 168 if ((header->nFlags & OMX_BUFFERFLAG_EOS) && !header->nFilledLen) { 169 DEBUG("\n EOS with zero length recieved"); 170 171 if (!add_new_list()) { 172 handle_error(); 173 return false; 174 } 175 176 return true; 177 } 178 179 for (int i = 0; i < TIME_SZ && !table_entry; i++) { 180 if (!pcurrent->input_timestamps[i].in_use) { 181 table_entry = &pcurrent->input_timestamps[i].timestamps; 182 pcurrent->input_timestamps[i].in_use = true; 183 pcurrent->entries_filled++; 184 } 185 } 186 187 if (!table_entry) { 188 DEBUG("\n All entries in use"); 189 handle_error(); 190 return false; 191 } 192 193 *table_entry = header->nTimeStamp; 194 195 if (print_debug) 196 DEBUG("Time stamp inserted %lld", header->nTimeStamp); 197 198 if (header->nFlags & OMX_BUFFERFLAG_EOS) { 199 if (!add_new_list()) { 200 handle_error(); 201 return false; 202 } 203 } 204 205 return true; 206} 207 208bool omx_time_stamp_reorder::remove_time_stamp(OMX_TICKS ts, bool is_interlaced = false) 209{ 210 unsigned int num_ent_remove = (is_interlaced)?2:1; 211 212 if (!reorder_ts || error) { 213 DEBUG("\n not in avi mode"); 214 return false; 215 } 216 217 if (!phead || !phead->entries_filled) return false; 218 219 for (int i=0; i < TIME_SZ && num_ent_remove; i++) { 220 if (phead->input_timestamps[i].in_use && phead->input_timestamps[i].timestamps == ts) { 221 phead->input_timestamps[i].in_use = false; 222 phead->entries_filled--; 223 num_ent_remove--; 224 225 if (print_debug) 226 DEBUG("Removed TS %lld", ts); 227 } 228 } 229 230 if (!phead->entries_filled) { 231 if (!update_head()) { 232 handle_error(); 233 return false; 234 } 235 } 236 237 return true; 238} 239 240void omx_time_stamp_reorder::flush_timestamp() 241{ 242 delete_list(); 243} 244 245bool omx_time_stamp_reorder::get_next_timestamp(OMX_BUFFERHEADERTYPE *header, bool is_interlaced) 246{ 247 timestamp *element = NULL,*duplicate = NULL; 248 bool status = false; 249 250 if (!reorder_ts || error || !header) { 251 if (error || !header) 252 DEBUG("\n Invalid condition in insert_timestamp %p", header); 253 254 return false; 255 } 256 257 if (!phead || !phead->entries_filled) return false; 258 259 for (int i=0; i < TIME_SZ; i++) { 260 if (phead->input_timestamps[i].in_use) { 261 status = true; 262 263 if (!element) 264 element = &phead->input_timestamps[i]; 265 else { 266 if (element->timestamps > phead->input_timestamps[i].timestamps) { 267 element = &phead->input_timestamps[i]; 268 duplicate = NULL; 269 } else if (element->timestamps == phead->input_timestamps[i].timestamps) 270 duplicate = &phead->input_timestamps[i]; 271 } 272 } 273 } 274 275 if (element) { 276 phead->entries_filled--; 277 header->nTimeStamp = element->timestamps; 278 279 if (print_debug) 280 DEBUG("Getnext Time stamp %lld", header->nTimeStamp); 281 282 element->in_use = false; 283 } 284 285 if (is_interlaced && duplicate) { 286 phead->entries_filled--; 287 duplicate->in_use = false; 288 } else if (is_interlaced && !duplicate) { 289 element = NULL; 290 291 for (int i=0; i < TIME_SZ; i++) { 292 if (phead->input_timestamps[i].in_use) { 293 if (!element) 294 element = &phead->input_timestamps[i]; 295 else if (element->timestamps > phead->input_timestamps[i].timestamps) 296 element = &phead->input_timestamps[i]; 297 } 298 } 299 300 if (element) { 301 phead->entries_filled--; 302 header->nTimeStamp = element->timestamps; 303 element->in_use = false; 304 } 305 } 306 307 if (!phead->entries_filled) { 308 if (!update_head()) { 309 handle_error(); 310 return false; 311 } 312 } 313 314 return status; 315} 316