| 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 |