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