| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "media/base/stream_parser.h" | 5 #include "media/base/stream_parser.h" |
| 6 | 6 |
| 7 #include "media/base/buffers.h" | 7 #include "media/base/buffers.h" |
| 8 #include "media/base/stream_parser_buffer.h" | 8 #include "media/base/stream_parser_buffer.h" |
| 9 | 9 |
| 10 namespace media { | 10 namespace media { |
| (...skipping 30 matching lines...) Expand all Loading... |
| 41 // for being appended to |merged_buffers|. | 41 // for being appended to |merged_buffers|. |
| 42 size_t num_itrs = buffer_queues.size(); | 42 size_t num_itrs = buffer_queues.size(); |
| 43 std::vector<StreamParser::BufferQueue::const_iterator> itrs(num_itrs); | 43 std::vector<StreamParser::BufferQueue::const_iterator> itrs(num_itrs); |
| 44 for (size_t i = 0; i < num_itrs; ++i) | 44 for (size_t i = 0; i < num_itrs; ++i) |
| 45 itrs[i] = buffer_queues[i]->begin(); | 45 itrs[i] = buffer_queues[i]->begin(); |
| 46 | 46 |
| 47 // |last_decode_timestamp| tracks the lower bound, if any, that all candidate | 47 // |last_decode_timestamp| tracks the lower bound, if any, that all candidate |
| 48 // buffers must not be less than. If |merged_buffers| already has buffers, | 48 // buffers must not be less than. If |merged_buffers| already has buffers, |
| 49 // initialize |last_decode_timestamp| to the decode timestamp of the last | 49 // initialize |last_decode_timestamp| to the decode timestamp of the last |
| 50 // buffer in it. | 50 // buffer in it. |
| 51 base::TimeDelta last_decode_timestamp = kNoTimestamp(); | 51 DecodeTimestamp last_decode_timestamp = kNoDecodeTimestamp(); |
| 52 if (!merged_buffers->empty()) | 52 if (!merged_buffers->empty()) |
| 53 last_decode_timestamp = merged_buffers->back()->GetDecodeTimestamp(); | 53 last_decode_timestamp = merged_buffers->back()->GetDecodeTimestamp(); |
| 54 | 54 |
| 55 // Repeatedly select and append the next buffer from the candidate buffers | 55 // Repeatedly select and append the next buffer from the candidate buffers |
| 56 // until either: | 56 // until either: |
| 57 // 1) returning false, to indicate detection of decreasing DTS in some queue, | 57 // 1) returning false, to indicate detection of decreasing DTS in some queue, |
| 58 // when a candidate buffer has decode timestamp below | 58 // when a candidate buffer has decode timestamp below |
| 59 // |last_decode_timestamp|, which means either an input buffer wasn't | 59 // |last_decode_timestamp|, which means either an input buffer wasn't |
| 60 // sorted correctly or had a buffer with decode timestamp below the last | 60 // sorted correctly or had a buffer with decode timestamp below the last |
| 61 // buffer, if any, in |merged_buffers|, or | 61 // buffer, if any, in |merged_buffers|, or |
| 62 // 2) returning true when all buffers have been merged successfully; | 62 // 2) returning true when all buffers have been merged successfully; |
| 63 // equivalently, when all of the iterators in |itrs| have reached the end | 63 // equivalently, when all of the iterators in |itrs| have reached the end |
| 64 // of their respective queue from |buffer_queues|. | 64 // of their respective queue from |buffer_queues|. |
| 65 // TODO(wolenetz/acolwell): Ideally, we would use a heap to store the head of | 65 // TODO(wolenetz/acolwell): Ideally, we would use a heap to store the head of |
| 66 // all queues and pop the head with lowest decode timestamp in log(N) time. | 66 // all queues and pop the head with lowest decode timestamp in log(N) time. |
| 67 // However, N will typically be small and usage of this implementation is | 67 // However, N will typically be small and usage of this implementation is |
| 68 // meant to be short-term. See http://crbug.com/338484. | 68 // meant to be short-term. See http://crbug.com/338484. |
| 69 while (true) { | 69 while (true) { |
| 70 // Tracks which queue's iterator is pointing to the candidate buffer to | 70 // Tracks which queue's iterator is pointing to the candidate buffer to |
| 71 // append next, or -1 if no candidate buffers found. This indexes |itrs|. | 71 // append next, or -1 if no candidate buffers found. This indexes |itrs|. |
| 72 int index_of_queue_with_next_decode_timestamp = -1; | 72 int index_of_queue_with_next_decode_timestamp = -1; |
| 73 base::TimeDelta next_decode_timestamp = kNoTimestamp(); | 73 DecodeTimestamp next_decode_timestamp = kNoDecodeTimestamp(); |
| 74 | 74 |
| 75 // Scan each of the iterators for |buffer_queues| to find the candidate | 75 // Scan each of the iterators for |buffer_queues| to find the candidate |
| 76 // buffer, if any, that has the lowest decode timestamp. | 76 // buffer, if any, that has the lowest decode timestamp. |
| 77 for (size_t i = 0; i < num_itrs; ++i) { | 77 for (size_t i = 0; i < num_itrs; ++i) { |
| 78 if (itrs[i] == buffer_queues[i]->end()) | 78 if (itrs[i] == buffer_queues[i]->end()) |
| 79 continue; | 79 continue; |
| 80 | 80 |
| 81 // Extract the candidate buffer's decode timestamp. | 81 // Extract the candidate buffer's decode timestamp. |
| 82 base::TimeDelta ts = (*itrs[i])->GetDecodeTimestamp(); | 82 DecodeTimestamp ts = (*itrs[i])->GetDecodeTimestamp(); |
| 83 | 83 |
| 84 if (last_decode_timestamp != kNoTimestamp() && | 84 if (last_decode_timestamp != kNoDecodeTimestamp() && |
| 85 ts < last_decode_timestamp) | 85 ts < last_decode_timestamp) |
| 86 return false; | 86 return false; |
| 87 | 87 |
| 88 if (ts < next_decode_timestamp || | 88 if (ts < next_decode_timestamp || |
| 89 next_decode_timestamp == kNoTimestamp()) { | 89 next_decode_timestamp == kNoDecodeTimestamp()) { |
| 90 // Remember the decode timestamp and queue iterator index for this | 90 // Remember the decode timestamp and queue iterator index for this |
| 91 // potentially winning candidate buffer. | 91 // potentially winning candidate buffer. |
| 92 next_decode_timestamp = ts; | 92 next_decode_timestamp = ts; |
| 93 index_of_queue_with_next_decode_timestamp = i; | 93 index_of_queue_with_next_decode_timestamp = i; |
| 94 } | 94 } |
| 95 } | 95 } |
| 96 | 96 |
| 97 // All done if no further candidate buffers exist. | 97 // All done if no further candidate buffers exist. |
| 98 if (index_of_queue_with_next_decode_timestamp == -1) | 98 if (index_of_queue_with_next_decode_timestamp == -1) |
| 99 return true; | 99 return true; |
| (...skipping 28 matching lines...) Expand all Loading... |
| 128 map_itr++) { | 128 map_itr++) { |
| 129 if (!map_itr->second.empty()) | 129 if (!map_itr->second.empty()) |
| 130 buffer_queues.push_back(&(map_itr->second)); | 130 buffer_queues.push_back(&(map_itr->second)); |
| 131 } | 131 } |
| 132 | 132 |
| 133 // Do the merge. | 133 // Do the merge. |
| 134 return MergeBufferQueuesInternal(buffer_queues, merged_buffers); | 134 return MergeBufferQueuesInternal(buffer_queues, merged_buffers); |
| 135 } | 135 } |
| 136 | 136 |
| 137 } // namespace media | 137 } // namespace media |
| OLD | NEW |