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

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

Issue 113611: Handle end of stream for media... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' 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 | Annotate | Revision Log
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 #include "base/scoped_ptr.h" 5 #include "base/scoped_ptr.h"
6 #include "base/string_util.h" 6 #include "base/string_util.h"
7 #include "base/time.h" 7 #include "base/time.h"
8 #include "media/base/filter_host.h" 8 #include "media/base/filter_host.h"
9 #include "media/filters/ffmpeg_common.h" 9 #include "media/filters/ffmpeg_common.h"
10 #include "media/filters/ffmpeg_demuxer.h" 10 #include "media/filters/ffmpeg_demuxer.h"
11 #include "media/filters/ffmpeg_glue.h" 11 #include "media/filters/ffmpeg_glue.h"
12 12
13 namespace media { 13 namespace media {
14 14
15 // 15 //
16 // AVPacketBuffer 16 // AVPacketBuffer
17 // 17 //
18 class AVPacketBuffer : public Buffer { 18 class AVPacketBuffer : public Buffer {
19 public: 19 public:
20 AVPacketBuffer(AVPacket* packet, const base::TimeDelta& timestamp, 20 AVPacketBuffer(AVPacket* packet, const base::TimeDelta& timestamp,
21 const base::TimeDelta& duration) 21 const base::TimeDelta& duration)
22 : packet_(packet) { 22 : packet_(packet) {
23 DCHECK(packet);
24 SetTimestamp(timestamp); 23 SetTimestamp(timestamp);
25 SetDuration(duration); 24 SetDuration(duration);
26 } 25 }
27 26
28 virtual ~AVPacketBuffer() { 27 virtual ~AVPacketBuffer() {
29 av_free_packet(packet_.get()); 28 av_free_packet(packet_.get());
30 } 29 }
31 30
32 // Buffer implementation. 31 // Buffer implementation.
33 virtual const uint8* GetData() const { 32 virtual const uint8* GetData() const {
(...skipping 277 matching lines...) Expand 10 before | Expand all | Expand 10 after
311 void FFmpegDemuxer::DemuxTask() { 310 void FFmpegDemuxer::DemuxTask() {
312 // Make sure we have work to do before demuxing. 311 // Make sure we have work to do before demuxing.
313 if (!StreamsHavePendingReads()) { 312 if (!StreamsHavePendingReads()) {
314 return; 313 return;
315 } 314 }
316 315
317 // Allocate and read an AVPacket from the media. 316 // Allocate and read an AVPacket from the media.
318 scoped_ptr<AVPacket> packet(new AVPacket()); 317 scoped_ptr<AVPacket> packet(new AVPacket());
319 int result = av_read_frame(format_context_.get(), packet.get()); 318 int result = av_read_frame(format_context_.get(), packet.get());
320 if (result < 0) { 319 if (result < 0) {
321 // TODO(scherkus): handle end of stream by marking Buffer with the end 320 // If we have reached the end of stream, tell the downstream filters about
322 // of stream flag. 321 // the event.
323 NOTIMPLEMENTED(); 322 StreamHasEnded();
324 return; 323 return;
325 } 324 }
326 325
327 // Queue the packet with the appropriate stream. 326 // Queue the packet with the appropriate stream.
328 // TODO(scherkus): should we post this back to the pipeline thread? I'm 327 // TODO(scherkus): should we post this back to the pipeline thread? I'm
329 // worried about downstream filters (i.e., decoders) executing on this 328 // worried about downstream filters (i.e., decoders) executing on this
330 // thread. 329 // thread.
331 DCHECK(packet->stream_index >= 0); 330 DCHECK(packet->stream_index >= 0);
332 DCHECK(packet->stream_index < static_cast<int>(packet_streams_.size())); 331 DCHECK(packet->stream_index < static_cast<int>(packet_streams_.size()));
333 FFmpegDemuxerStream* demuxer_stream = packet_streams_[packet->stream_index]; 332 FFmpegDemuxerStream* demuxer_stream = packet_streams_[packet->stream_index];
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
366 bool FFmpegDemuxer::StreamsHavePendingReads() { 365 bool FFmpegDemuxer::StreamsHavePendingReads() {
367 StreamVector::iterator iter; 366 StreamVector::iterator iter;
368 for (iter = streams_.begin(); iter != streams_.end(); ++iter) { 367 for (iter = streams_.begin(); iter != streams_.end(); ++iter) {
369 if ((*iter)->HasPendingReads()) { 368 if ((*iter)->HasPendingReads()) {
370 return true; 369 return true;
371 } 370 }
372 } 371 }
373 return false; 372 return false;
374 } 373 }
375 374
375 void FFmpegDemuxer::StreamHasEnded() {
376 StreamVector::iterator iter;
377 for (iter = streams_.begin(); iter != streams_.end(); ++iter) {
378 AVPacket* packet = new AVPacket();
379 memset(packet, 0, sizeof(*packet));
380 (*iter)->EnqueuePacket(packet);
381 }
382 }
383
376 AVPacket* FFmpegDemuxer::ClonePacket(AVPacket* packet) { 384 AVPacket* FFmpegDemuxer::ClonePacket(AVPacket* packet) {
377 scoped_ptr<AVPacket> clone(new AVPacket()); 385 scoped_ptr<AVPacket> clone(new AVPacket());
378 if (!clone.get() || av_new_packet(clone.get(), packet->size) < 0) { 386 if (!clone.get() || av_new_packet(clone.get(), packet->size) < 0) {
379 return NULL; 387 return NULL;
380 } 388 }
381 DCHECK_EQ(clone->size, packet->size); 389 DCHECK_EQ(clone->size, packet->size);
382 clone->dts = packet->dts; 390 clone->dts = packet->dts;
383 clone->pts = packet->pts; 391 clone->pts = packet->pts;
384 clone->duration = packet->duration; 392 clone->duration = packet->duration;
385 memcpy(clone->data, packet->data, clone->size); 393 memcpy(clone->data, packet->data, clone->size);
386 return clone.release(); 394 return clone.release();
387 } 395 }
388 396
389 } // namespace media 397 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698