12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file. 42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "media/filters/blocking_url_protocol.h" 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/bind.h" 82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "media/base/data_source.h" 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "media/ffmpeg/ffmpeg_common.h" 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace media { 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)BlockingUrlProtocol::BlockingUrlProtocol( 14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DataSource* data_source, 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::Closure& error_cb) 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : data_source_(data_source), 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) error_cb_(error_cb), 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) aborted_(true, false), // We never want to reset |aborted_|. 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) read_complete_(false, false), 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) last_read_bytes_(0), 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) read_position_(0) { 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)BlockingUrlProtocol::~BlockingUrlProtocol() {} 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void BlockingUrlProtocol::Abort() { 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) aborted_.Signal(); 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int BlockingUrlProtocol::Read(int size, uint8* data) { 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Read errors are unrecoverable. 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (aborted_.IsSignaled()) 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return AVERROR(EIO); 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Even though FFmpeg defines AVERROR_EOF, it's not to be used with I/O 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // routines. Instead return 0 for any read at or past EOF. 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int64 file_size; 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (data_source_->GetSize(&file_size) && read_position_ >= file_size) 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return 0; 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Blocking read from data source until either: 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // 1) |last_read_bytes_| is set and |read_complete_| is signalled 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // 2) |aborted_| is signalled 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) data_source_->Read(read_position_, size, data, base::Bind( 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &BlockingUrlProtocol::SignalReadCompleted, base::Unretained(this))); 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::WaitableEvent* events[] = { &aborted_, &read_complete_ }; 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) size_t index = base::WaitableEvent::WaitMany(events, arraysize(events)); 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (events[index] == &aborted_) 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return AVERROR(EIO); 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (last_read_bytes_ == DataSource::kReadError) { 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) aborted_.Signal(); 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) error_cb_.Run(); 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return AVERROR(EIO); 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) read_position_ += last_read_bytes_; 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return last_read_bytes_; 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool BlockingUrlProtocol::GetPosition(int64* position_out) { 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *position_out = read_position_; 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool BlockingUrlProtocol::SetPosition(int64 position) { 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int64 file_size; 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if ((data_source_->GetSize(&file_size) && position >= file_size) || 712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) position < 0) { 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) read_position_ = position; 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool BlockingUrlProtocol::GetSize(int64* size_out) { 802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return data_source_->GetSize(size_out); 812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool BlockingUrlProtocol::IsStreaming() { 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return data_source_->IsStreaming(); 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void BlockingUrlProtocol::SignalReadCompleted(int size) { 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) last_read_bytes_ = size; 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) read_complete_.Signal(); 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace media 93