Chromium Code Reviews| 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/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) { | |
|
fbarchard
2009/08/18 22:34:16
removing this breaks the unittest
C:\chrome-svn\sr
| |
| 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 445 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 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(packet->stream_index >= 0); |
| 495 DCHECK(packet->stream_index < static_cast<int>(packet_streams_.size())); | 476 DCHECK(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 packets 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, it MUST be duplicat ed. |
|
fbarchard
2009/08/18 22:34:16
nit more than 80 columns... break comment into 2 l
ffmpeg
2009/08/19 01:05:25
OK, Let's focus on issue: 174027 which is the enha
| |
| 501 if (!clone.get()) { | 482 av_dup_packet(packet.get()); |
| 502 NOTREACHED(); | |
| 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 | 483 |
| 510 // Queue the packet with the appropriate stream. The stream takes | 484 // Queue the packet with the appropriate stream. The stream takes |
| 511 // ownership of the AVPacket. | 485 // ownership of the AVPacket. |
| 512 current_timestamp_ = demuxer_stream->EnqueuePacket(packet.release()); | 486 current_timestamp_ = demuxer_stream->EnqueuePacket(packet.release()); |
| 513 } else { | 487 } else { |
| 514 av_free_packet(packet.get()); | 488 av_free_packet(packet.get()); |
| 515 } | 489 } |
| 516 | 490 |
| 517 // Create a loop by posting another task. This allows seek and message loop | 491 // Create a loop by posting another task. This allows seek and message loop |
| 518 // quit tasks to get processed. | 492 // quit tasks to get processed. |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 576 read_event_.Wait(); | 550 read_event_.Wait(); |
| 577 return last_read_bytes_; | 551 return last_read_bytes_; |
| 578 } | 552 } |
| 579 | 553 |
| 580 void FFmpegDemuxer::SignalReadCompleted(size_t size) { | 554 void FFmpegDemuxer::SignalReadCompleted(size_t size) { |
| 581 last_read_bytes_ = size; | 555 last_read_bytes_ = size; |
| 582 read_event_.Signal(); | 556 read_event_.Signal(); |
| 583 } | 557 } |
| 584 | 558 |
| 585 } // namespace media | 559 } // namespace media |
| OLD | NEW |