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

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

Issue 174027: Fix Issue 160529 in a nice way (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 11 years, 4 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
« no previous file with comments | « media/base/mock_ffmpeg.cc ('k') | media/filters/ffmpeg_demuxer_unittest.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 #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/filters/ffmpeg_common.h" 10 #include "media/filters/ffmpeg_common.h"
11 #include "media/filters/ffmpeg_demuxer.h" 11 #include "media/filters/ffmpeg_demuxer.h"
12 #include "media/filters/ffmpeg_glue.h" 12 #include "media/filters/ffmpeg_glue.h"
13 13
14 namespace {
15
16 // Helper function to deep copy an AVPacket's data, size and timestamps.
17 // Returns NULL if a packet could not be cloned (i.e., out of memory).
18 AVPacket* ClonePacket(AVPacket* packet) {
19 scoped_ptr<AVPacket> clone(new AVPacket());
20 if (!clone.get() || av_new_packet(clone.get(), packet->size) < 0) {
21 return NULL;
22 }
23 DCHECK_EQ(clone->size, packet->size);
24 clone->dts = packet->dts;
25 clone->pts = packet->pts;
26 clone->duration = packet->duration;
27 memcpy(clone->data, packet->data, clone->size);
28 return clone.release();
29 }
30
31 } // namespace
32
33 namespace media { 14 namespace media {
34 15
35 // 16 //
36 // AVPacketBuffer 17 // AVPacketBuffer
37 // 18 //
38 class AVPacketBuffer : public Buffer { 19 class AVPacketBuffer : public Buffer {
39 public: 20 public:
40 AVPacketBuffer(AVPacket* packet, const base::TimeDelta& timestamp, 21 AVPacketBuffer(AVPacket* packet, const base::TimeDelta& timestamp,
41 const base::TimeDelta& duration) 22 const base::TimeDelta& duration)
42 : packet_(packet) { 23 : packet_(packet) {
(...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after
291 message_loop()->PostTask(FROM_HERE, 272 message_loop()->PostTask(FROM_HERE,
292 NewRunnableMethod(this, &FFmpegDemuxer::InitializeTask, data_source, 273 NewRunnableMethod(this, &FFmpegDemuxer::InitializeTask, data_source,
293 callback)); 274 callback));
294 } 275 }
295 276
296 size_t FFmpegDemuxer::GetNumberOfStreams() { 277 size_t FFmpegDemuxer::GetNumberOfStreams() {
297 return streams_.size(); 278 return streams_.size();
298 } 279 }
299 280
300 scoped_refptr<DemuxerStream> FFmpegDemuxer::GetStream(int stream) { 281 scoped_refptr<DemuxerStream> FFmpegDemuxer::GetStream(int stream) {
301 DCHECK(stream >= 0); 282 DCHECK_GE(stream, 0);
302 DCHECK(stream < static_cast<int>(streams_.size())); 283 DCHECK_LT(stream, static_cast<int>(streams_.size()));
303 return streams_[stream].get(); 284 return streams_[stream].get();
304 } 285 }
305 286
306 int FFmpegDemuxer::Read(int size, uint8* data) { 287 int FFmpegDemuxer::Read(int size, uint8* data) {
307 DCHECK(data_source_); 288 DCHECK(data_source_);
308 289
309 // If read has ever failed, return with an error. 290 // If read has ever failed, return with an error.
310 // TODO(hclam): use a more meaningful constant as error. 291 // TODO(hclam): use a more meaningful constant as error.
311 if (read_has_failed_) 292 if (read_has_failed_)
312 return AVERROR_IO; 293 return AVERROR_IO;
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
484 // If we have reached the end of stream, tell the downstream filters about 465 // If we have reached the end of stream, tell the downstream filters about
485 // the event. 466 // the event.
486 StreamHasEnded(); 467 StreamHasEnded();
487 return; 468 return;
488 } 469 }
489 470
490 // Queue the packet with the appropriate stream. 471 // Queue the packet with the appropriate stream.
491 // TODO(scherkus): should we post this back to the pipeline thread? I'm 472 // TODO(scherkus): should we post this back to the pipeline thread? I'm
492 // worried about downstream filters (i.e., decoders) executing on this 473 // worried about downstream filters (i.e., decoders) executing on this
493 // thread. 474 // thread.
494 DCHECK(packet->stream_index >= 0); 475 DCHECK_GE(packet->stream_index, 0);
495 DCHECK(packet->stream_index < static_cast<int>(packet_streams_.size())); 476 DCHECK_LT(packet->stream_index, static_cast<int>(packet_streams_.size()));
496 FFmpegDemuxerStream* demuxer_stream = packet_streams_[packet->stream_index]; 477 FFmpegDemuxerStream* demuxer_stream = packet_streams_[packet->stream_index];
497 if (demuxer_stream) { 478 if (demuxer_stream) {
498 // Duplicate the entire packet to avoid aliasing. 479 // If a packet is returned by FFmpeg's av_parser_parse2()
499 // Directly affects MP3, but do all formats to be safe. 480 // the packet will reference an inner memory of FFmpeg.
500 scoped_ptr<AVPacket> clone(ClonePacket(packet.get())); 481 // In this case, the packet's "destruct" member is NULL,
501 if (!clone.get()) { 482 // and it MUST be duplicated. Fixes issue with MP3.
502 NOTREACHED(); 483 av_dup_packet(packet.get());
503 return;
504 }
505 // Free FFmpeg-allocated memory and swap original packet into |clone| so
506 // that it gets deleted as |clone| goes out of scope.
507 av_free_packet(packet.get());
508 packet.swap(clone);
509 484
510 // Queue the packet with the appropriate stream. The stream takes 485 // Queue the packet with the appropriate stream. The stream takes
511 // ownership of the AVPacket. 486 // ownership of the AVPacket.
512 current_timestamp_ = demuxer_stream->EnqueuePacket(packet.release()); 487 current_timestamp_ = demuxer_stream->EnqueuePacket(packet.release());
513 } else { 488 } else {
514 av_free_packet(packet.get()); 489 av_free_packet(packet.get());
515 } 490 }
516 491
517 // Create a loop by posting another task. This allows seek and message loop 492 // Create a loop by posting another task. This allows seek and message loop
518 // quit tasks to get processed. 493 // quit tasks to get processed.
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
576 read_event_.Wait(); 551 read_event_.Wait();
577 return last_read_bytes_; 552 return last_read_bytes_;
578 } 553 }
579 554
580 void FFmpegDemuxer::SignalReadCompleted(size_t size) { 555 void FFmpegDemuxer::SignalReadCompleted(size_t size) {
581 last_read_bytes_ = size; 556 last_read_bytes_ = size;
582 read_event_.Signal(); 557 read_event_.Signal();
583 } 558 }
584 559
585 } // namespace media 560 } // namespace media
OLDNEW
« no previous file with comments | « media/base/mock_ffmpeg.cc ('k') | media/filters/ffmpeg_demuxer_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698