Chromium Code Reviews| Index: media/filters/ffmpeg_demuxer.cc |
| diff --git a/media/filters/ffmpeg_demuxer.cc b/media/filters/ffmpeg_demuxer.cc |
| index 535116ffebd3e4b000f1818ca44d84f8c8f1cc17..07972671b02b00a95fd466961ef1722790ff1ce2 100644 |
| --- a/media/filters/ffmpeg_demuxer.cc |
| +++ b/media/filters/ffmpeg_demuxer.cc |
| @@ -7,6 +7,7 @@ |
| #include <algorithm> |
| #include <string> |
| +#include "base/base64.h" |
| #include "base/bind.h" |
| #include "base/callback.h" |
| #include "base/command_line.h" |
| @@ -20,9 +21,11 @@ |
| #include "media/base/limits.h" |
| #include "media/base/media_switches.h" |
| #include "media/base/video_decoder_config.h" |
| +#include "media/crypto/decryptor_helpers.h" |
| #include "media/ffmpeg/ffmpeg_common.h" |
| #include "media/filters/ffmpeg_glue.h" |
| #include "media/filters/ffmpeg_h264_to_annex_b_bitstream_converter.h" |
| +#include "media/webm/webm_crypt_helpers.h" |
| namespace media { |
| @@ -56,6 +59,22 @@ FFmpegDemuxerStream::FFmpegDemuxerStream( |
| // Calculate the duration. |
| duration_ = ConvertStreamTimestamp(stream->time_base, stream->duration); |
| + |
| + // *** DEBUG Until FFmpeg metadata "enck_key_id" is added for windows. *** |
| + //av_dict_set(stream->metadata, "enc_key_id", "DEBUG_KEY_ID_REMOVE", 0); |
| + // *** DEBUG Until FFmpeg metadata "enck_key_id" is added for windows. *** |
| + |
| + // Only supports WebM for now. |
| + AVDictionaryEntry *key = av_dict_get(stream->metadata, "enc_key_id", NULL, 0); |
| + if (key) { |
| + CHECK(key->value); |
|
xhwang
2012/08/29 05:08:14
Can a malformed file generate a |key| without valu
fgalligan1
2013/03/09 01:10:59
Done.
|
| + base::StringPiece base64_key_id(key->value); |
| + std::string enc_key_id; |
| + base::Base64Decode(base64_key_id, &enc_key_id); |
| + CHECK(!enc_key_id.empty()); |
|
xhwang
2012/08/29 05:08:14
Same as above, add error handling code instead of
fgalligan1
2013/03/09 01:10:59
Done.
fgalligan1
2013/03/09 01:10:59
Done.
|
| + demuxer_->NeedKey(enc_key_id); |
| + current_key_id_.assign(enc_key_id); |
| + } |
| } |
| bool FFmpegDemuxerStream::HasPendingReads() { |
| @@ -86,10 +105,14 @@ void FFmpegDemuxerStream::EnqueuePacket( |
| LOG(ERROR) << "Format converstion failed."; |
| } |
| - // 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); |
| + // TODO (fgalligan): Remove the WebM specific code to process an encrypted |
| + // buffer. Create a generalized class or function that can be called that |
| + // will work for all encrypted formats. |
| + buffer = WebMCopyBufferCheckIfEncrypted( |
| + packet->data, |
| + packet->size, |
| + reinterpret_cast<const uint8*>(current_key_id_.data()), |
| + current_key_id_.size()); |
| buffer->SetTimestamp(ConvertStreamTimestamp( |
| stream_->time_base, packet->pts)); |
| buffer->SetDuration(ConvertStreamTimestamp( |
| @@ -257,7 +280,8 @@ base::TimeDelta FFmpegDemuxerStream::ConvertStreamTimestamp( |
| // |
| FFmpegDemuxer::FFmpegDemuxer( |
| const scoped_refptr<base::MessageLoopProxy>& message_loop, |
| - const scoped_refptr<DataSource>& data_source) |
| + const scoped_refptr<DataSource>& data_source, |
| + const FFmpegNeedKeyCB& need_key_cb) |
| : host_(NULL), |
| message_loop_(message_loop), |
| format_context_(NULL), |
| @@ -269,7 +293,8 @@ FFmpegDemuxer::FFmpegDemuxer( |
| bitrate_(0), |
| start_time_(kNoTimestamp()), |
| audio_disabled_(false), |
| - duration_known_(false) { |
| + duration_known_(false), |
| + need_key_cb_(need_key_cb) { |
| DCHECK(message_loop_); |
| DCHECK(data_source_); |
| } |
| @@ -316,6 +341,13 @@ void FFmpegDemuxer::OnAudioRendererDisabled() { |
| &FFmpegDemuxer::DisableAudioStreamTask, this)); |
| } |
| +void FFmpegDemuxer::NeedKey(const std::string& key_id) { |
| + int key_id_size = key_id.size(); |
| + scoped_array<uint8> key_id_local(new uint8[key_id_size]); |
| + memcpy(key_id_local.get(), key_id.data(), key_id_size); |
| + need_key_cb_.Run(key_id_local.Pass(), key_id_size); |
|
xhwang
2012/08/29 05:08:14
Sad to see this conversion again. I think we need
|
| +} |
| + |
| void FFmpegDemuxer::Initialize(DemuxerHost* host, |
| const PipelineStatusCB& status_cb) { |
| message_loop_->PostTask(FROM_HERE, base::Bind( |