| OLD | NEW | 
|---|
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 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 "base/scoped_ptr.h" | 5 #include "base/scoped_ptr.h" | 
| 6 #include "base/stl_util-inl.h" | 6 #include "base/stl_util-inl.h" | 
| 7 #include "base/string_util.h" | 7 #include "base/string_util.h" | 
| 8 #include "base/time.h" | 8 #include "base/time.h" | 
| 9 #include "media/base/filter_host.h" | 9 #include "media/base/filter_host.h" | 
|  | 10 #include "media/ffmpeg/ffmpeg_util.h" | 
| 10 #include "media/filters/ffmpeg_common.h" | 11 #include "media/filters/ffmpeg_common.h" | 
| 11 #include "media/filters/ffmpeg_demuxer.h" | 12 #include "media/filters/ffmpeg_demuxer.h" | 
| 12 #include "media/filters/ffmpeg_glue.h" | 13 #include "media/filters/ffmpeg_glue.h" | 
| 13 | 14 | 
| 14 namespace media { | 15 namespace media { | 
| 15 | 16 | 
| 16 // | 17 // | 
| 17 // AVPacketBuffer | 18 // AVPacketBuffer | 
| 18 // | 19 // | 
| 19 class AVPacketBuffer : public Buffer { | 20 class AVPacketBuffer : public Buffer { | 
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 69                                 mime_type::kFFmpegVideo); | 70                                 mime_type::kFFmpegVideo); | 
| 70       media_format_.SetAsInteger(MediaFormat::kFFmpegCodecID, | 71       media_format_.SetAsInteger(MediaFormat::kFFmpegCodecID, | 
| 71                                  stream->codec->codec_id); | 72                                  stream->codec->codec_id); | 
| 72       break; | 73       break; | 
| 73     default: | 74     default: | 
| 74       NOTREACHED(); | 75       NOTREACHED(); | 
| 75       break; | 76       break; | 
| 76   } | 77   } | 
| 77 | 78 | 
| 78   // Calculate the duration. | 79   // Calculate the duration. | 
| 79   duration_ = ConvertTimestamp(stream->duration); | 80   duration_ = ConvertStreamTimestamp(stream->time_base, stream->duration); | 
| 80 } | 81 } | 
| 81 | 82 | 
| 82 FFmpegDemuxerStream::~FFmpegDemuxerStream() { | 83 FFmpegDemuxerStream::~FFmpegDemuxerStream() { | 
| 83   DCHECK(stopped_); | 84   DCHECK(stopped_); | 
| 84   DCHECK(read_queue_.empty()); | 85   DCHECK(read_queue_.empty()); | 
| 85   DCHECK(buffer_queue_.empty()); | 86   DCHECK(buffer_queue_.empty()); | 
| 86 } | 87 } | 
| 87 | 88 | 
| 88 void* FFmpegDemuxerStream::QueryInterface(const char* id) { | 89 void* FFmpegDemuxerStream::QueryInterface(const char* id) { | 
| 89   DCHECK(id); | 90   DCHECK(id); | 
| 90   AVStreamProvider* interface_ptr = NULL; | 91   AVStreamProvider* interface_ptr = NULL; | 
| 91   if (0 == strcmp(id, AVStreamProvider::interface_id())) { | 92   if (0 == strcmp(id, AVStreamProvider::interface_id())) { | 
| 92     interface_ptr = this; | 93     interface_ptr = this; | 
| 93   } | 94   } | 
| 94   return interface_ptr; | 95   return interface_ptr; | 
| 95 } | 96 } | 
| 96 | 97 | 
| 97 bool FFmpegDemuxerStream::HasPendingReads() { | 98 bool FFmpegDemuxerStream::HasPendingReads() { | 
| 98   DCHECK_EQ(MessageLoop::current(), demuxer_->message_loop()); | 99   DCHECK_EQ(MessageLoop::current(), demuxer_->message_loop()); | 
| 99   DCHECK(!stopped_ || read_queue_.empty()) | 100   DCHECK(!stopped_ || read_queue_.empty()) | 
| 100       << "Read queue should have been emptied if demuxing stream is stopped"; | 101       << "Read queue should have been emptied if demuxing stream is stopped"; | 
| 101   return !read_queue_.empty(); | 102   return !read_queue_.empty(); | 
| 102 } | 103 } | 
| 103 | 104 | 
| 104 base::TimeDelta FFmpegDemuxerStream::EnqueuePacket(AVPacket* packet) { | 105 base::TimeDelta FFmpegDemuxerStream::EnqueuePacket(AVPacket* packet) { | 
| 105   DCHECK_EQ(MessageLoop::current(), demuxer_->message_loop()); | 106   DCHECK_EQ(MessageLoop::current(), demuxer_->message_loop()); | 
| 106   base::TimeDelta timestamp = ConvertTimestamp(packet->pts); | 107   base::TimeDelta timestamp = | 
| 107   base::TimeDelta duration = ConvertTimestamp(packet->duration); | 108       ConvertStreamTimestamp(stream_->time_base, packet->pts); | 
|  | 109   base::TimeDelta duration = | 
|  | 110       ConvertStreamTimestamp(stream_->time_base, packet->duration); | 
| 108   if (stopped_) { | 111   if (stopped_) { | 
| 109     NOTREACHED() << "Attempted to enqueue packet on a stopped stream"; | 112     NOTREACHED() << "Attempted to enqueue packet on a stopped stream"; | 
| 110     return timestamp; | 113     return timestamp; | 
| 111   } | 114   } | 
| 112 | 115 | 
| 113   // Enqueue the callback and attempt to satisfy a read immediately. | 116   // Enqueue the callback and attempt to satisfy a read immediately. | 
| 114   scoped_refptr<Buffer> buffer = | 117   scoped_refptr<Buffer> buffer = | 
| 115       new AVPacketBuffer(packet, timestamp, duration); | 118       new AVPacketBuffer(packet, timestamp, duration); | 
| 116   if (!buffer) { | 119   if (!buffer) { | 
| 117     NOTREACHED() << "Unable to allocate AVPacketBuffer"; | 120     NOTREACHED() << "Unable to allocate AVPacketBuffer"; | 
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 184   // TODO(scherkus): get rid of |discontinuous_| and use buffer flags. | 187   // TODO(scherkus): get rid of |discontinuous_| and use buffer flags. | 
| 185   if (discontinuous_) { | 188   if (discontinuous_) { | 
| 186     buffer->SetDiscontinuous(true); | 189     buffer->SetDiscontinuous(true); | 
| 187     discontinuous_ = false; | 190     discontinuous_ = false; | 
| 188   } | 191   } | 
| 189 | 192 | 
| 190   // Execute the callback. | 193   // Execute the callback. | 
| 191   read_callback->Run(buffer); | 194   read_callback->Run(buffer); | 
| 192 } | 195 } | 
| 193 | 196 | 
| 194 base::TimeDelta FFmpegDemuxerStream::ConvertTimestamp(int64 timestamp) { | 197 // static | 
|  | 198 base::TimeDelta FFmpegDemuxerStream::ConvertStreamTimestamp( | 
|  | 199     const AVRational& time_base, int64 timestamp) { | 
| 195   if (timestamp == static_cast<int64>(AV_NOPTS_VALUE)) | 200   if (timestamp == static_cast<int64>(AV_NOPTS_VALUE)) | 
| 196     return StreamSample::kInvalidTimestamp; | 201     return StreamSample::kInvalidTimestamp; | 
| 197   AVRational time_base = { 1, base::Time::kMicrosecondsPerSecond }; | 202 | 
| 198   int64 microseconds = av_rescale_q(timestamp, stream_->time_base, time_base); | 203   return ConvertTimestamp(time_base, timestamp); | 
| 199   return base::TimeDelta::FromMicroseconds(microseconds); |  | 
| 200 } | 204 } | 
| 201 | 205 | 
| 202 // | 206 // | 
| 203 // FFmpegDemuxer | 207 // FFmpegDemuxer | 
| 204 // | 208 // | 
| 205 FFmpegDemuxer::FFmpegDemuxer() | 209 FFmpegDemuxer::FFmpegDemuxer() | 
| 206     : format_context_(NULL), | 210     : format_context_(NULL), | 
| 207       read_event_(false, false), | 211       read_event_(false, false), | 
| 208       read_has_failed_(false), | 212       read_has_failed_(false), | 
| 209       last_read_bytes_(0), | 213       last_read_bytes_(0), | 
| (...skipping 350 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 560   read_event_.Wait(); | 564   read_event_.Wait(); | 
| 561   return last_read_bytes_; | 565   return last_read_bytes_; | 
| 562 } | 566 } | 
| 563 | 567 | 
| 564 void FFmpegDemuxer::SignalReadCompleted(size_t size) { | 568 void FFmpegDemuxer::SignalReadCompleted(size_t size) { | 
| 565   last_read_bytes_ = size; | 569   last_read_bytes_ = size; | 
| 566   read_event_.Signal(); | 570   read_event_.Signal(); | 
| 567 } | 571 } | 
| 568 | 572 | 
| 569 }  // namespace media | 573 }  // namespace media | 
| OLD | NEW | 
|---|