Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(185)

Side by Side Diff: media/filters/ffmpeg_demuxer.h

Issue 131092: FFmpegDemuxerStream::Read() now functions properly while stopped. (Closed)
Patch Set: Albert's comments Created 11 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | media/filters/ffmpeg_demuxer.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 // Implements the Demuxer interface using FFmpeg's libavformat. At this time 5 // Implements the Demuxer interface using FFmpeg's libavformat. At this time
6 // will support demuxing any audio/video format thrown at it. The streams 6 // will support demuxing any audio/video format thrown at it. The streams
7 // output mime types audio/x-ffmpeg and video/x-ffmpeg and include an integer 7 // output mime types audio/x-ffmpeg and video/x-ffmpeg and include an integer
8 // key FFmpegCodecID which contains the CodecID enumeration value. The CodecIDs 8 // key FFmpegCodecID which contains the CodecID enumeration value. The CodecIDs
9 // can be used to create and initialize the corresponding FFmpeg decoder. 9 // can be used to create and initialize the corresponding FFmpeg decoder.
10 // 10 //
11 // FFmpegDemuxer sets the duration of pipeline during initialization by using 11 // FFmpegDemuxer sets the duration of pipeline during initialization by using
12 // the duration of the longest audio/video stream. 12 // the duration of the longest audio/video stream.
13 // 13 //
14 // NOTE: since FFmpegDemuxer reads packets sequentially without seeking, media 14 // NOTE: since FFmpegDemuxer reads packets sequentially without seeking, media
15 // files with very large drift between audio/video streams may result in 15 // files with very large drift between audio/video streams may result in
16 // excessive memory consumption. 16 // excessive memory consumption.
17 //
18 // When stopped, FFmpegDemuxer and FFmpegDemuxerStream release all callbacks
19 // and buffered packets and shuts down its internal thread. Reads from a
20 // stopped FFmpegDemuxerStream will not be replied to.
17 21
18 #ifndef MEDIA_FILTERS_FFMPEG_DEMUXER_H_ 22 #ifndef MEDIA_FILTERS_FFMPEG_DEMUXER_H_
19 #define MEDIA_FILTERS_FFMPEG_DEMUXER_H_ 23 #define MEDIA_FILTERS_FFMPEG_DEMUXER_H_
20 24
21 #include <deque> 25 #include <deque>
22 #include <vector> 26 #include <vector>
23 27
24 #include "base/lock.h" 28 #include "base/lock.h"
25 #include "base/thread.h" 29 #include "base/thread.h"
26 #include "base/waitable_event.h" 30 #include "base/waitable_event.h"
(...skipping 27 matching lines...) Expand all
54 58
55 // Returns true is this stream has pending reads, false otherwise. 59 // Returns true is this stream has pending reads, false otherwise.
56 // 60 //
57 // Safe to call on any thread. 61 // Safe to call on any thread.
58 bool HasPendingReads(); 62 bool HasPendingReads();
59 63
60 // Enqueues and takes ownership over the given AVPacket, returns the timestamp 64 // Enqueues and takes ownership over the given AVPacket, returns the timestamp
61 // of the enqueued packet. 65 // of the enqueued packet.
62 base::TimeDelta EnqueuePacket(AVPacket* packet); 66 base::TimeDelta EnqueuePacket(AVPacket* packet);
63 67
64 // Signals to empty queue and mark next packet as discontinuous. 68 // Signals to empty the buffer queue and mark next packet as discontinuous.
65 void FlushBuffers(); 69 void FlushBuffers();
66 70
71 // Empties the queues and ignores any additional calls to Read().
72 void Stop();
73
67 // Returns the duration of this stream. 74 // Returns the duration of this stream.
68 base::TimeDelta duration() { return duration_; } 75 base::TimeDelta duration() { return duration_; }
69 76
70 // DemuxerStream implementation. 77 // DemuxerStream implementation.
71 virtual const MediaFormat& media_format(); 78 virtual const MediaFormat& media_format();
72 virtual void Read(Callback1<Buffer*>::Type* read_callback); 79 virtual void Read(Callback1<Buffer*>::Type* read_callback);
73 80
74 // AVStreamProvider implementation. 81 // AVStreamProvider implementation.
75 virtual AVStream* GetAVStream() { return stream_; } 82 virtual AVStream* GetAVStream() { return stream_; }
76 83
77 protected: 84 protected:
78 virtual void* QueryInterface(const char* interface_id); 85 virtual void* QueryInterface(const char* interface_id);
79 86
80 private: 87 private:
81 // Returns true if there are still pending reads. 88 // Returns true if there are still pending reads.
82 bool FulfillPendingReads(); 89 bool FulfillPendingReads();
83 90
84 // Converts an FFmpeg stream timestamp into a base::TimeDelta. 91 // Converts an FFmpeg stream timestamp into a base::TimeDelta.
85 base::TimeDelta ConvertTimestamp(int64 timestamp); 92 base::TimeDelta ConvertTimestamp(int64 timestamp);
86 93
87 FFmpegDemuxer* demuxer_; 94 FFmpegDemuxer* demuxer_;
88 AVStream* stream_; 95 AVStream* stream_;
89 MediaFormat media_format_; 96 MediaFormat media_format_;
90 base::TimeDelta duration_; 97 base::TimeDelta duration_;
91 bool discontinuous_; 98 bool discontinuous_;
99 bool stopped_;
92 100
93 Lock lock_; 101 Lock lock_;
94 102
95 typedef std::deque< scoped_refptr<Buffer> > BufferQueue; 103 typedef std::deque< scoped_refptr<Buffer> > BufferQueue;
96 BufferQueue buffer_queue_; 104 BufferQueue buffer_queue_;
97 105
98 typedef std::deque<Callback1<Buffer*>::Type*> ReadQueue; 106 typedef std::deque<Callback1<Buffer*>::Type*> ReadQueue;
99 ReadQueue read_queue_; 107 ReadQueue read_queue_;
100 108
101 DISALLOW_COPY_AND_ASSIGN(FFmpegDemuxerStream); 109 DISALLOW_COPY_AND_ASSIGN(FFmpegDemuxerStream);
(...skipping 29 matching lines...) Expand all
131 139
132 // Carries out initialization on the demuxer thread. 140 // Carries out initialization on the demuxer thread.
133 void InititalizeTask(DataSource* data_source); 141 void InititalizeTask(DataSource* data_source);
134 142
135 // Carries out a seek on the demuxer thread. 143 // Carries out a seek on the demuxer thread.
136 void SeekTask(base::TimeDelta time); 144 void SeekTask(base::TimeDelta time);
137 145
138 // Carries out demuxing and satisfying stream reads on the demuxer thread. 146 // Carries out demuxing and satisfying stream reads on the demuxer thread.
139 void DemuxTask(); 147 void DemuxTask();
140 148
149 // Carries out stopping the demuxer streams on the demuxer thread.
150 void StopTask();
151
141 // Returns true if any of the streams have pending reads. Since we lazily 152 // Returns true if any of the streams have pending reads. Since we lazily
142 // post a DemuxTask() for every read, we use this method to quickly terminate 153 // post a DemuxTask() for every read, we use this method to quickly terminate
143 // the tasks if there is no work to do. 154 // the tasks if there is no work to do.
144 // 155 //
145 // Safe to call on any thread. 156 // Must be called on the demuxer thread.
146 bool StreamsHavePendingReads(); 157 bool StreamsHavePendingReads();
147 158
148 // Signal all FFmpegDemuxerStream that the stream has ended. 159 // Signal all FFmpegDemuxerStream that the stream has ended.
160 //
161 // Must be called on the demuxer thread.
149 void StreamHasEnded(); 162 void StreamHasEnded();
150 163
151 // Helper function to deep copy an AVPacket's data, size and timestamps.
152 // Returns NULL if a packet could not be cloned (i.e., out of memory).
153 AVPacket* ClonePacket(AVPacket* packet);
154
155 // FFmpeg context handle. 164 // FFmpeg context handle.
156 scoped_ptr_malloc<AVFormatContext, ScopedPtrAVFree> format_context_; 165 scoped_ptr_malloc<AVFormatContext, ScopedPtrAVFree> format_context_;
157 166
158 // Latest timestamp read on the demuxer thread. 167 // Latest timestamp read on the demuxer thread.
159 base::TimeDelta current_timestamp_; 168 base::TimeDelta current_timestamp_;
160 169
161 // Two vector of streams: 170 // Two vector of streams:
162 // - |streams_| is indexed for the Demuxer interface GetStream(), which only 171 // - |streams_| is indexed for the Demuxer interface GetStream(), which only
163 // contains supported streams and no NULL entries. 172 // contains supported streams and no NULL entries.
164 // - |packet_streams_| is indexed to mirror AVFormatContext when dealing 173 // - |packet_streams_| is indexed to mirror AVFormatContext when dealing
165 // with AVPackets returned from av_read_frame() and contain NULL entries 174 // with AVPackets returned from av_read_frame() and contain NULL entries
166 // representing unsupported streams where we throw away the data. 175 // representing unsupported streams where we throw away the data.
167 // 176 //
168 // Ownership is handled via reference counting. 177 // Ownership is handled via reference counting.
178 //
179 // Once initialized, operations on FFmpegDemuxerStreams should be carried out
180 // on the demuxer thread.
169 typedef std::vector< scoped_refptr<FFmpegDemuxerStream> > StreamVector; 181 typedef std::vector< scoped_refptr<FFmpegDemuxerStream> > StreamVector;
170 StreamVector streams_; 182 StreamVector streams_;
171 StreamVector packet_streams_; 183 StreamVector packet_streams_;
172 184
173 // Thread handle. 185 // Thread handle.
174 base::Thread thread_; 186 base::Thread thread_;
175 187
176 DISALLOW_COPY_AND_ASSIGN(FFmpegDemuxer); 188 DISALLOW_COPY_AND_ASSIGN(FFmpegDemuxer);
177 }; 189 };
178 190
179 } // namespace media 191 } // namespace media
180 192
181 #endif // MEDIA_FILTERS_FFMPEG_DEMUXER_H_ 193 #endif // MEDIA_FILTERS_FFMPEG_DEMUXER_H_
OLDNEW
« no previous file with comments | « no previous file | media/filters/ffmpeg_demuxer.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698