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

Side by Side Diff: media/webm/webm_stream_parser.cc

Issue 10912080: Switch to AVIO instead of a custom FFmpeg URLProtocol handler. (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Rebase. Created 8 years, 1 month 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 | « media/filters/in_memory_url_protocol.cc ('k') | no next file » | 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) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "media/webm/webm_stream_parser.h" 5 #include "media/webm/webm_stream_parser.h"
6 6
7 #include <string> 7 #include <string>
8 8
9 #include "base/callback.h" 9 #include "base/callback.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
(...skipping 25 matching lines...) Expand all
36 bool Parse(const uint8* data, int size); 36 bool Parse(const uint8* data, int size);
37 37
38 const AudioDecoderConfig& audio_config() const; 38 const AudioDecoderConfig& audio_config() const;
39 const VideoDecoderConfig& video_config() const; 39 const VideoDecoderConfig& video_config() const;
40 40
41 private: 41 private:
42 static const uint8 kWebMHeader[]; 42 static const uint8 kWebMHeader[];
43 static const int kSegmentSizeOffset; 43 static const int kSegmentSizeOffset;
44 static const uint8 kEmptyCluster[]; 44 static const uint8 kEmptyCluster[];
45 45
46 AVFormatContext* CreateFormatContext(const uint8* data, int size); 46 bool OpenFormatContext(const uint8* data, int size);
47 bool SetupStreamConfigs(); 47 bool SetupStreamConfigs();
48 48
49 AudioDecoderConfig audio_config_; 49 AudioDecoderConfig audio_config_;
50 VideoDecoderConfig video_config_; 50 VideoDecoderConfig video_config_;
51 51
52 // Backing buffer for |url_protocol_|. 52 // Backing buffer for |url_protocol_|.
53 scoped_array<uint8> url_protocol_buffer_; 53 scoped_array<uint8> url_protocol_buffer_;
54 54
55 // Protocol used by |format_context_|. It must outlive the context object. 55 // Protocol used by FFmpegGlue. It must outlive the context object.
56 scoped_ptr<InMemoryUrlProtocol> url_protocol_; 56 scoped_ptr<InMemoryUrlProtocol> url_protocol_;
57 57
58 // FFmpeg format context for this demuxer. It is created by 58 // Glue for interfacing InMemoryUrlProtocol with FFmpeg.
59 // avformat_open_input() during demuxer initialization and cleaned up with 59 scoped_ptr<FFmpegGlue> glue_;
60 // DestroyAVFormatContext() in the destructor.
61 AVFormatContext* format_context_;
62 60
63 DISALLOW_COPY_AND_ASSIGN(FFmpegConfigHelper); 61 DISALLOW_COPY_AND_ASSIGN(FFmpegConfigHelper);
64 }; 62 };
65 63
66 // WebM File Header. This is prepended to the INFO & TRACKS 64 // WebM File Header. This is prepended to the INFO & TRACKS
67 // data passed to Init() before handing it to FFmpeg. Essentially 65 // data passed to Init() before handing it to FFmpeg. Essentially
68 // we are making the INFO & TRACKS data look like a small WebM 66 // we are making the INFO & TRACKS data look like a small WebM
69 // file so we can use FFmpeg to initialize the AVFormatContext. 67 // file so we can use FFmpeg to initialize the AVFormatContext.
70 const uint8 FFmpegConfigHelper::kWebMHeader[] = { 68 const uint8 FFmpegConfigHelper::kWebMHeader[] = {
71 0x1A, 0x45, 0xDF, 0xA3, 0x9F, // EBML (size = 0x1f) 69 0x1A, 0x45, 0xDF, 0xA3, 0x9F, // EBML (size = 0x1f)
(...skipping 11 matching lines...) Expand all
83 }; 81 };
84 82
85 // Offset of the segment size field in kWebMHeader. Used to update 83 // Offset of the segment size field in kWebMHeader. Used to update
86 // the segment size field before handing the buffer to FFmpeg. 84 // the segment size field before handing the buffer to FFmpeg.
87 const int FFmpegConfigHelper::kSegmentSizeOffset = sizeof(kWebMHeader) - 8; 85 const int FFmpegConfigHelper::kSegmentSizeOffset = sizeof(kWebMHeader) - 8;
88 86
89 const uint8 FFmpegConfigHelper::kEmptyCluster[] = { 87 const uint8 FFmpegConfigHelper::kEmptyCluster[] = {
90 0x1F, 0x43, 0xB6, 0x75, 0x80 // CLUSTER (size = 0) 88 0x1F, 0x43, 0xB6, 0x75, 0x80 // CLUSTER (size = 0)
91 }; 89 };
92 90
93 FFmpegConfigHelper::FFmpegConfigHelper() : format_context_(NULL) {} 91 FFmpegConfigHelper::FFmpegConfigHelper() {}
94 92
95 FFmpegConfigHelper::~FFmpegConfigHelper() { 93 FFmpegConfigHelper::~FFmpegConfigHelper() {
96 if (!format_context_)
97 return;
98
99 DestroyAVFormatContext(format_context_);
100 format_context_ = NULL;
101
102 if (url_protocol_.get()) { 94 if (url_protocol_.get()) {
103 FFmpegGlue::GetInstance()->RemoveProtocol(url_protocol_.get());
104 url_protocol_.reset(); 95 url_protocol_.reset();
105 url_protocol_buffer_.reset(); 96 url_protocol_buffer_.reset();
106 } 97 }
98
99 if (glue_.get())
100 glue_.reset();
107 } 101 }
108 102
109 bool FFmpegConfigHelper::Parse(const uint8* data, int size) { 103 bool FFmpegConfigHelper::Parse(const uint8* data, int size) {
110 format_context_ = CreateFormatContext(data, size); 104 return OpenFormatContext(data, size) && SetupStreamConfigs();
111 return format_context_ && SetupStreamConfigs();
112 } 105 }
113 106
114 const AudioDecoderConfig& FFmpegConfigHelper::audio_config() const { 107 const AudioDecoderConfig& FFmpegConfigHelper::audio_config() const {
115 return audio_config_; 108 return audio_config_;
116 } 109 }
117 110
118 const VideoDecoderConfig& FFmpegConfigHelper::video_config() const { 111 const VideoDecoderConfig& FFmpegConfigHelper::video_config() const {
119 return video_config_; 112 return video_config_;
120 } 113 }
121 114
122 AVFormatContext* FFmpegConfigHelper::CreateFormatContext(const uint8* data, 115 bool FFmpegConfigHelper::OpenFormatContext(const uint8* data, int size) {
123 int size) {
124 DCHECK(!url_protocol_.get()); 116 DCHECK(!url_protocol_.get());
125 DCHECK(!url_protocol_buffer_.get()); 117 DCHECK(!url_protocol_buffer_.get());
118 DCHECK(!glue_.get());
126 119
127 int segment_size = size + sizeof(kEmptyCluster); 120 int segment_size = size + sizeof(kEmptyCluster);
128 int buf_size = sizeof(kWebMHeader) + segment_size; 121 int buf_size = sizeof(kWebMHeader) + segment_size;
129 url_protocol_buffer_.reset(new uint8[buf_size]); 122 url_protocol_buffer_.reset(new uint8[buf_size]);
130 uint8* buf = url_protocol_buffer_.get(); 123 uint8* buf = url_protocol_buffer_.get();
131 memcpy(buf, kWebMHeader, sizeof(kWebMHeader)); 124 memcpy(buf, kWebMHeader, sizeof(kWebMHeader));
132 memcpy(buf + sizeof(kWebMHeader), data, size); 125 memcpy(buf + sizeof(kWebMHeader), data, size);
133 memcpy(buf + sizeof(kWebMHeader) + size, kEmptyCluster, 126 memcpy(buf + sizeof(kWebMHeader) + size, kEmptyCluster,
134 sizeof(kEmptyCluster)); 127 sizeof(kEmptyCluster));
135 128
136 // Update the segment size in the buffer. 129 // Update the segment size in the buffer.
137 int64 tmp = (segment_size & GG_LONGLONG(0x00FFFFFFFFFFFFFF)) | 130 int64 tmp = (segment_size & GG_LONGLONG(0x00FFFFFFFFFFFFFF)) |
138 GG_LONGLONG(0x0100000000000000); 131 GG_LONGLONG(0x0100000000000000);
139 for (int i = 0; i < 8; i++) { 132 for (int i = 0; i < 8; i++) {
140 buf[kSegmentSizeOffset + i] = (tmp >> (8 * (7 - i))) & 0xff; 133 buf[kSegmentSizeOffset + i] = (tmp >> (8 * (7 - i))) & 0xff;
141 } 134 }
142 135
143 url_protocol_.reset(new InMemoryUrlProtocol(buf, buf_size, true)); 136 url_protocol_.reset(new InMemoryUrlProtocol(buf, buf_size, true));
144 std::string key = FFmpegGlue::GetInstance()->AddProtocol(url_protocol_.get()); 137 glue_.reset(new FFmpegGlue(url_protocol_.get()));
145 138
146 // Open FFmpeg AVFormatContext. 139 // Open FFmpeg AVFormatContext.
147 AVFormatContext* context = NULL; 140 return glue_->OpenContext();
148 int result = avformat_open_input(&context, key.c_str(), NULL, NULL);
149
150 if (result < 0)
151 return NULL;
152
153 return context;
154 } 141 }
155 142
156 bool FFmpegConfigHelper::SetupStreamConfigs() { 143 bool FFmpegConfigHelper::SetupStreamConfigs() {
157 int result = avformat_find_stream_info(format_context_, NULL); 144 AVFormatContext* format_context = glue_->format_context();
145 int result = avformat_find_stream_info(format_context, NULL);
158 146
159 if (result < 0) 147 if (result < 0)
160 return false; 148 return false;
161 149
162 bool no_supported_streams = true; 150 bool no_supported_streams = true;
163 for (size_t i = 0; i < format_context_->nb_streams; ++i) { 151 for (size_t i = 0; i < format_context->nb_streams; ++i) {
164 AVStream* stream = format_context_->streams[i]; 152 AVStream* stream = format_context->streams[i];
165 AVCodecContext* codec_context = stream->codec; 153 AVCodecContext* codec_context = stream->codec;
166 AVMediaType codec_type = codec_context->codec_type; 154 AVMediaType codec_type = codec_context->codec_type;
167 155
168 if (codec_type == AVMEDIA_TYPE_AUDIO && 156 if (codec_type == AVMEDIA_TYPE_AUDIO &&
169 stream->codec->codec_id == CODEC_ID_VORBIS && 157 stream->codec->codec_id == CODEC_ID_VORBIS &&
170 !audio_config_.IsValidConfig()) { 158 !audio_config_.IsValidConfig()) {
171 AVCodecContextToAudioDecoderConfig(stream->codec, &audio_config_); 159 AVCodecContextToAudioDecoderConfig(stream->codec, &audio_config_);
172 no_supported_streams = false; 160 no_supported_streams = false;
173 continue; 161 continue;
174 } 162 }
(...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after
474 462
475 void WebMStreamParser::FireNeedKey(const std::string& key_id) { 463 void WebMStreamParser::FireNeedKey(const std::string& key_id) {
476 int key_id_size = key_id.size(); 464 int key_id_size = key_id.size();
477 DCHECK_GT(key_id_size, 0); 465 DCHECK_GT(key_id_size, 0);
478 scoped_array<uint8> key_id_array(new uint8[key_id_size]); 466 scoped_array<uint8> key_id_array(new uint8[key_id_size]);
479 memcpy(key_id_array.get(), key_id.data(), key_id_size); 467 memcpy(key_id_array.get(), key_id.data(), key_id_size);
480 need_key_cb_.Run(kWebMInitDataType, key_id_array.Pass(), key_id_size); 468 need_key_cb_.Run(kWebMInitDataType, key_id_array.Pass(), key_id_size);
481 } 469 }
482 470
483 } // namespace media 471 } // namespace media
OLDNEW
« no previous file with comments | « media/filters/in_memory_url_protocol.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698