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

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

Issue 42029: Checking in media::FFmpegGlue, media::FFmpegDemuxer and tests. (Closed)
Patch Set: Created 11 years, 9 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
« no previous file with comments | « media/filters/ffmpeg_glue.h ('k') | media/filters/ffmpeg_glue_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
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "base/string_util.h"
6 #include "media/base/filters.h"
7 #include "media/filters/ffmpeg_common.h"
8 #include "media/filters/ffmpeg_glue.h"
9
10 namespace {
11
12 // FFmpeg protocol interface.
13 int OpenContext(URLContext* h, const char* filename, int flags) {
14 scoped_refptr<media::DataSource> data_source;
15 media::FFmpegGlue::get()->GetDataSource(filename, &data_source);
16 if (!data_source)
17 return AVERROR_IO;
18
19 data_source->AddRef();
20 h->priv_data = data_source;
21 h->flags = URL_RDONLY;
22 // TODO(scherkus): data source should be able to tell us if we're streaming.
23 h->is_streamed = FALSE;
24 return 0;
25 }
26
27 int ReadContext(URLContext* h, unsigned char* buf, int size) {
28 media::DataSource* data_source =
29 reinterpret_cast<media::DataSource*>(h->priv_data);
30 int result = data_source->Read(buf, size);
31 if (result < 0)
32 result = AVERROR_IO;
33 return result;
34 }
35
36 int WriteContext(URLContext* h, unsigned char* buf, int size) {
37 // We don't support writing.
38 return AVERROR_IO;
39 }
40
41 offset_t SeekContext(URLContext* h, offset_t offset, int whence) {
42 media::DataSource* data_source =
43 reinterpret_cast<media::DataSource*>(h->priv_data);
44 offset_t new_offset = AVERROR_IO;
45 switch (whence) {
46 case SEEK_SET:
47 if (data_source->SetPosition(offset))
48 data_source->GetPosition(&new_offset);
49 break;
50
51 case SEEK_CUR:
52 int64 pos;
53 if (!data_source->GetPosition(&pos))
54 break;
55 if (data_source->SetPosition(pos + offset))
56 data_source->GetPosition(&new_offset);
57 break;
58
59 case SEEK_END:
60 int64 size;
61 if (!data_source->GetSize(&size))
62 break;
63 if (data_source->SetPosition(size + offset))
64 data_source->GetPosition(&new_offset);
65 break;
66
67 case AVSEEK_SIZE:
68 data_source->GetSize(&new_offset);
69 break;
70
71 default:
72 NOTREACHED();
73 }
74 if (new_offset < 0)
75 new_offset = AVERROR_IO;
76 return new_offset;
77 }
78
79 int CloseContext(URLContext* h) {
80 media::DataSource* data_source =
81 reinterpret_cast<media::DataSource*>(h->priv_data);
82 data_source->Release();
83 h->priv_data = NULL;
84 return 0;
85 }
86
87 } // namespace
88
89 //------------------------------------------------------------------------------
90
91 namespace media {
92
93 // Use the HTTP protocol to avoid any file path separator issues.
94 static const char kProtocol[] = "http";
95
96 // Fill out our FFmpeg protocol definition.
97 static URLProtocol kFFmpegProtocol = {
98 kProtocol,
99 &OpenContext,
100 &ReadContext,
101 &WriteContext,
102 &SeekContext,
103 &CloseContext,
104 };
105
106 FFmpegGlue::FFmpegGlue() {
107 // Register our protocol glue code with FFmpeg.
108 avcodec_init();
109 register_protocol(&kFFmpegProtocol);
110
111 // Now register the rest of FFmpeg.
112 av_register_all();
113 }
114
115 FFmpegGlue::~FFmpegGlue() {
116 DataSourceMap::iterator iter = data_sources_.begin();
117 while (iter != data_sources_.end()) {
118 DataSource* data_source = iter->second;
119 iter = data_sources_.erase(iter);
120 }
121 }
122
123 std::string FFmpegGlue::AddDataSource(DataSource* data_source) {
124 AutoLock auto_lock(lock_);
125 std::string key = GetDataSourceKey(data_source);
126 if (data_sources_.find(key) == data_sources_.end()) {
127 data_sources_[key] = data_source;
128 }
129 return key;
130 }
131
132 void FFmpegGlue::RemoveDataSource(DataSource* data_source) {
133 AutoLock auto_lock(lock_);
134 DataSourceMap::iterator iter = data_sources_.begin();
135 while (iter != data_sources_.end()) {
136 if (iter->second == data_source) {
137 iter = data_sources_.erase(iter);
138 } else {
139 ++iter;
140 }
141 }
142 }
143
144 void FFmpegGlue::GetDataSource(const std::string& key,
145 scoped_refptr<DataSource>* data_source) {
146 AutoLock auto_lock(lock_);
147 DataSourceMap::iterator iter = data_sources_.find(key);
148 if (iter == data_sources_.end()) {
149 *data_source = NULL;
150 return;
151 }
152 *data_source = iter->second;
153 }
154
155 std::string FFmpegGlue::GetDataSourceKey(DataSource* data_source) {
156 // Use the DataSource's memory address to generate the unique string. This
157 // also has the nice property that adding the same DataSource reference will
158 // not generate duplicate entries.
159 return StringPrintf("%s://0x%lx", kProtocol, static_cast<void*>(data_source));
160 }
161
162 } // namespace media
OLDNEW
« no previous file with comments | « media/filters/ffmpeg_glue.h ('k') | media/filters/ffmpeg_glue_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698