Index: media/filters/ffmpeg_demuxer.cc |
diff --git a/media/filters/ffmpeg_demuxer.cc b/media/filters/ffmpeg_demuxer.cc |
index 3d7a5fe7eac35ec9440d475a07f44c4bf23d0a12..16c5447ae65ffa122e9c4887d36dd6f5290545d2 100644 |
--- a/media/filters/ffmpeg_demuxer.cc |
+++ b/media/filters/ffmpeg_demuxer.cc |
@@ -16,7 +16,7 @@ |
#include "base/string_util.h" |
#include "base/time.h" |
#include "media/base/audio_decoder_config.h" |
-#include "media/base/data_buffer.h" |
+#include "media/base/decoder_buffer.h" |
#include "media/base/limits.h" |
#include "media/base/media_switches.h" |
#include "media/base/video_decoder_config.h" |
@@ -28,37 +28,6 @@ |
namespace media { |
// |
-// AVPacketBuffer |
-// |
-class AVPacketBuffer : public Buffer { |
- public: |
- AVPacketBuffer(scoped_ptr_malloc<AVPacket, ScopedPtrAVFreePacket> packet, |
- const base::TimeDelta& timestamp, |
- const base::TimeDelta& duration) |
- : Buffer(timestamp, duration), |
- packet_(packet.Pass()) { |
- } |
- |
- // Buffer implementation. |
- virtual const uint8* GetData() const { |
- return reinterpret_cast<const uint8*>(packet_->data); |
- } |
- |
- virtual int GetDataSize() const { |
- return packet_->size; |
- } |
- |
- protected: |
- virtual ~AVPacketBuffer() {} |
- |
- private: |
- scoped_ptr_malloc<AVPacket, ScopedPtrAVFreePacket> packet_; |
- |
- DISALLOW_COPY_AND_ASSIGN(AVPacketBuffer); |
-}; |
- |
- |
-// |
// FFmpegDemuxerStream |
// |
FFmpegDemuxerStream::FFmpegDemuxerStream(FFmpegDemuxer* demuxer, |
@@ -100,10 +69,6 @@ bool FFmpegDemuxerStream::HasPendingReads() { |
void FFmpegDemuxerStream::EnqueuePacket( |
scoped_ptr_malloc<AVPacket, ScopedPtrAVFreePacket> packet) { |
DCHECK_EQ(MessageLoop::current(), demuxer_->message_loop()); |
- base::TimeDelta timestamp = |
- ConvertStreamTimestamp(stream_->time_base, packet->pts); |
- base::TimeDelta duration = |
- ConvertStreamTimestamp(stream_->time_base, packet->duration); |
base::AutoLock auto_lock(lock_); |
if (stopped_) { |
@@ -111,19 +76,26 @@ void FFmpegDemuxerStream::EnqueuePacket( |
return; |
} |
- // Convert if the packet if there is bitstream filter. |
- if (packet->data && bitstream_converter_.get() && |
- !bitstream_converter_->ConvertPacket(packet.get())) { |
- LOG(ERROR) << "Format converstion failed."; |
- } |
+ scoped_refptr<DecoderBuffer> buffer; |
+ if (!packet.get()) { |
+ buffer = DecoderBuffer::CreateEOSBuffer(); |
+ } else { |
+ // Convert the packet if there is a bitstream filter. |
+ if (packet->data && bitstream_converter_.get() && |
+ !bitstream_converter_->ConvertPacket(packet.get())) { |
+ LOG(ERROR) << "Format converstion failed."; |
+ } |
- // Enqueue the callback and attempt to satisfy a read immediately. |
- scoped_refptr<Buffer> buffer( |
- new AVPacketBuffer(packet.Pass(), timestamp, duration)); |
- if (!buffer) { |
- NOTREACHED() << "Unable to allocate AVPacketBuffer"; |
- return; |
+ // If a packet is returned by FFmpeg's av_parser_parse2() the packet will |
+ // reference inner memory of FFmpeg. As such we should transfer the packet |
+ // into memory we control. |
+ buffer = DecoderBuffer::CopyFrom(packet->data, packet->size); |
+ buffer->SetTimestamp(ConvertStreamTimestamp( |
+ stream_->time_base, packet->pts)); |
+ buffer->SetDuration(ConvertStreamTimestamp( |
+ stream_->time_base, packet->duration)); |
} |
+ |
buffer_queue_.push_back(buffer); |
FulfillPendingRead(); |
return; |
@@ -142,7 +114,7 @@ void FFmpegDemuxerStream::Stop() { |
buffer_queue_.clear(); |
for (ReadQueue::iterator it = read_queue_.begin(); |
it != read_queue_.end(); ++it) { |
- it->Run(scoped_refptr<Buffer>(new DataBuffer(0))); |
+ it->Run(scoped_refptr<DecoderBuffer>(DecoderBuffer::CreateEOSBuffer())); |
} |
read_queue_.clear(); |
stopped_ = true; |
@@ -165,7 +137,7 @@ void FFmpegDemuxerStream::Read(const ReadCB& read_cb) { |
// |
// TODO(scherkus): it would be cleaner if we replied with an error message. |
if (stopped_) { |
- read_cb.Run(scoped_refptr<Buffer>(new DataBuffer(0))); |
+ read_cb.Run(scoped_refptr<DecoderBuffer>(DecoderBuffer::CreateEOSBuffer())); |
return; |
} |
@@ -179,7 +151,7 @@ void FFmpegDemuxerStream::Read(const ReadCB& read_cb) { |
} |
// Send the oldest buffer back. |
- scoped_refptr<Buffer> buffer = buffer_queue_.front(); |
+ scoped_refptr<DecoderBuffer> buffer = buffer_queue_.front(); |
buffer_queue_.pop_front(); |
read_cb.Run(buffer); |
} |
@@ -192,7 +164,7 @@ void FFmpegDemuxerStream::ReadTask(const ReadCB& read_cb) { |
// |
// TODO(scherkus): it would be cleaner if we replied with an error message. |
if (stopped_) { |
- read_cb.Run(scoped_refptr<Buffer>(new DataBuffer(0))); |
+ read_cb.Run(scoped_refptr<DecoderBuffer>(DecoderBuffer::CreateEOSBuffer())); |
return; |
} |
@@ -214,7 +186,7 @@ void FFmpegDemuxerStream::FulfillPendingRead() { |
} |
// Dequeue a buffer and pending read pair. |
- scoped_refptr<Buffer> buffer = buffer_queue_.front(); |
+ scoped_refptr<DecoderBuffer> buffer = buffer_queue_.front(); |
ReadCB read_cb(read_queue_.front()); |
buffer_queue_.pop_front(); |
read_queue_.pop_front(); |
@@ -233,22 +205,12 @@ void FFmpegDemuxerStream::EnableBitstreamConverter() { |
bitstream_converter_.reset( |
new FFmpegH264BitstreamConverter(stream_->codec)); |
CHECK(bitstream_converter_->Initialize()); |
- return; |
- } |
- |
- const char* filter_name = NULL; |
- if (stream_->codec->codec_id == CODEC_ID_MPEG4) { |
- filter_name = "mpeg4video_es"; |
- } else if (stream_->codec->codec_id == CODEC_ID_WMV3) { |
- filter_name = "vc1_asftorcv"; |
- } else if (stream_->codec->codec_id == CODEC_ID_VC1) { |
- filter_name = "vc1_asftoannexg"; |
- } |
- |
- if (filter_name) { |
+ } else if (stream_->codec->codec_id == CODEC_ID_MPEG4) { |
bitstream_converter_.reset( |
- new FFmpegBitstreamConverter(filter_name, stream_->codec)); |
+ new FFmpegBitstreamConverter("mpeg4video_es", stream_->codec)); |
CHECK(bitstream_converter_->Initialize()); |
+ } else { |
+ NOTREACHED() << "Unsupported bitstream format."; |
} |
} |
@@ -676,15 +638,6 @@ void FFmpegDemuxer::DemuxTask() { |
(!audio_disabled_ || |
streams_[packet->stream_index]->type() != DemuxerStream::AUDIO)) { |
FFmpegDemuxerStream* demuxer_stream = streams_[packet->stream_index]; |
- |
- // If a packet is returned by FFmpeg's av_parser_parse2() |
- // the packet will reference an inner memory of FFmpeg. |
- // In this case, the packet's "destruct" member is NULL, |
- // and it MUST be duplicated. This fixes issue with MP3 and possibly |
- // other codecs. It is safe to call this function even if the packet does |
- // not refer to inner memory from FFmpeg. |
- av_dup_packet(packet.get()); |
- |
demuxer_stream->EnqueuePacket(packet.Pass()); |
} |
@@ -739,9 +692,8 @@ void FFmpegDemuxer::StreamHasEnded() { |
(audio_disabled_ && (*iter)->type() == DemuxerStream::AUDIO)) { |
continue; |
} |
- scoped_ptr_malloc<AVPacket, ScopedPtrAVFreePacket> packet(new AVPacket()); |
- memset(packet.get(), 0, sizeof(*packet.get())); |
- (*iter)->EnqueuePacket(packet.Pass()); |
+ (*iter)->EnqueuePacket( |
+ scoped_ptr_malloc<AVPacket, ScopedPtrAVFreePacket>()); |
} |
} |