1 /* 2 ** 3 ** Copyright 2008, The Android Open Source Project 4 ** 5 ** Licensed under the Apache License, Version 2.0 (the "License"); 6 ** you may not use this file except in compliance with the License. 7 ** You may obtain a copy of the License at 8 ** 9 ** http://www.apache.org/licenses/LICENSE-2.0 10 ** 11 ** Unless required by applicable law or agreed to in writing, software 12 ** distributed under the License is distributed on an "AS IS" BASIS, 13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 ** See the License for the specific language governing permissions and 15 ** limitations under the License. 16 */ 17 18 //#define LOG_NDEBUG 0 19 #define LOG_TAG "IMediaRecorder" 20 #include <utils/Log.h> 21 #include <binder/Parcel.h> 22 #include <surfaceflinger/Surface.h> 23 #include <camera/ICamera.h> 24 #include <media/IMediaRecorderClient.h> 25 #include <media/IMediaRecorder.h> 26 #include <gui/ISurfaceTexture.h> 27 #include <unistd.h> 28 29 30 namespace android { 31 32 enum { 33 RELEASE = IBinder::FIRST_CALL_TRANSACTION, 34 INIT, 35 CLOSE, 36 QUERY_SURFACE_MEDIASOURCE, 37 RESET, 38 STOP, 39 START, 40 PREPARE, 41 GET_MAX_AMPLITUDE, 42 SET_VIDEO_SOURCE, 43 SET_AUDIO_SOURCE, 44 SET_OUTPUT_FORMAT, 45 SET_VIDEO_ENCODER, 46 SET_AUDIO_ENCODER, 47 SET_OUTPUT_FILE_PATH, 48 SET_OUTPUT_FILE_FD, 49 SET_VIDEO_SIZE, 50 SET_VIDEO_FRAMERATE, 51 SET_PARAMETERS, 52 SET_PREVIEW_SURFACE, 53 SET_CAMERA, 54 SET_LISTENER 55 }; 56 57 class BpMediaRecorder: public BpInterface<IMediaRecorder> 58 { 59 public: 60 BpMediaRecorder(const sp<IBinder>& impl) 61 : BpInterface<IMediaRecorder>(impl) 62 { 63 } 64 65 status_t setCamera(const sp<ICamera>& camera, const sp<ICameraRecordingProxy>& proxy) 66 { 67 LOGV("setCamera(%p,%p)", camera.get(), proxy.get()); 68 Parcel data, reply; 69 data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor()); 70 data.writeStrongBinder(camera->asBinder()); 71 data.writeStrongBinder(proxy->asBinder()); 72 remote()->transact(SET_CAMERA, data, &reply); 73 return reply.readInt32(); 74 } 75 76 sp<ISurfaceTexture> querySurfaceMediaSource() 77 { 78 LOGV("Query SurfaceMediaSource"); 79 Parcel data, reply; 80 data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor()); 81 remote()->transact(QUERY_SURFACE_MEDIASOURCE, data, &reply); 82 int returnedNull = reply.readInt32(); 83 if (returnedNull) { 84 return NULL; 85 } 86 return interface_cast<ISurfaceTexture>(reply.readStrongBinder()); 87 } 88 89 status_t setPreviewSurface(const sp<Surface>& surface) 90 { 91 LOGV("setPreviewSurface(%p)", surface.get()); 92 Parcel data, reply; 93 data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor()); 94 Surface::writeToParcel(surface, &data); 95 remote()->transact(SET_PREVIEW_SURFACE, data, &reply); 96 return reply.readInt32(); 97 } 98 99 status_t init() 100 { 101 LOGV("init"); 102 Parcel data, reply; 103 data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor()); 104 remote()->transact(INIT, data, &reply); 105 return reply.readInt32(); 106 } 107 108 status_t setVideoSource(int vs) 109 { 110 LOGV("setVideoSource(%d)", vs); 111 Parcel data, reply; 112 data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor()); 113 data.writeInt32(vs); 114 remote()->transact(SET_VIDEO_SOURCE, data, &reply); 115 return reply.readInt32(); 116 } 117 118 status_t setAudioSource(int as) 119 { 120 LOGV("setAudioSource(%d)", as); 121 Parcel data, reply; 122 data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor()); 123 data.writeInt32(as); 124 remote()->transact(SET_AUDIO_SOURCE, data, &reply); 125 return reply.readInt32(); 126 } 127 128 status_t setOutputFormat(int of) 129 { 130 LOGV("setOutputFormat(%d)", of); 131 Parcel data, reply; 132 data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor()); 133 data.writeInt32(of); 134 remote()->transact(SET_OUTPUT_FORMAT, data, &reply); 135 return reply.readInt32(); 136 } 137 138 status_t setVideoEncoder(int ve) 139 { 140 LOGV("setVideoEncoder(%d)", ve); 141 Parcel data, reply; 142 data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor()); 143 data.writeInt32(ve); 144 remote()->transact(SET_VIDEO_ENCODER, data, &reply); 145 return reply.readInt32(); 146 } 147 148 status_t setAudioEncoder(int ae) 149 { 150 LOGV("setAudioEncoder(%d)", ae); 151 Parcel data, reply; 152 data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor()); 153 data.writeInt32(ae); 154 remote()->transact(SET_AUDIO_ENCODER, data, &reply); 155 return reply.readInt32(); 156 } 157 158 status_t setOutputFile(const char* path) 159 { 160 LOGV("setOutputFile(%s)", path); 161 Parcel data, reply; 162 data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor()); 163 data.writeCString(path); 164 remote()->transact(SET_OUTPUT_FILE_PATH, data, &reply); 165 return reply.readInt32(); 166 } 167 168 status_t setOutputFile(int fd, int64_t offset, int64_t length) { 169 LOGV("setOutputFile(%d, %lld, %lld)", fd, offset, length); 170 Parcel data, reply; 171 data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor()); 172 data.writeFileDescriptor(fd); 173 data.writeInt64(offset); 174 data.writeInt64(length); 175 remote()->transact(SET_OUTPUT_FILE_FD, data, &reply); 176 return reply.readInt32(); 177 } 178 179 status_t setVideoSize(int width, int height) 180 { 181 LOGV("setVideoSize(%dx%d)", width, height); 182 Parcel data, reply; 183 data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor()); 184 data.writeInt32(width); 185 data.writeInt32(height); 186 remote()->transact(SET_VIDEO_SIZE, data, &reply); 187 return reply.readInt32(); 188 } 189 190 status_t setVideoFrameRate(int frames_per_second) 191 { 192 LOGV("setVideoFrameRate(%d)", frames_per_second); 193 Parcel data, reply; 194 data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor()); 195 data.writeInt32(frames_per_second); 196 remote()->transact(SET_VIDEO_FRAMERATE, data, &reply); 197 return reply.readInt32(); 198 } 199 200 status_t setParameters(const String8& params) 201 { 202 LOGV("setParameter(%s)", params.string()); 203 Parcel data, reply; 204 data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor()); 205 data.writeString8(params); 206 remote()->transact(SET_PARAMETERS, data, &reply); 207 return reply.readInt32(); 208 } 209 210 status_t setListener(const sp<IMediaRecorderClient>& listener) 211 { 212 LOGV("setListener(%p)", listener.get()); 213 Parcel data, reply; 214 data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor()); 215 data.writeStrongBinder(listener->asBinder()); 216 remote()->transact(SET_LISTENER, data, &reply); 217 return reply.readInt32(); 218 } 219 220 status_t prepare() 221 { 222 LOGV("prepare"); 223 Parcel data, reply; 224 data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor()); 225 remote()->transact(PREPARE, data, &reply); 226 return reply.readInt32(); 227 } 228 229 status_t getMaxAmplitude(int* max) 230 { 231 LOGV("getMaxAmplitude"); 232 Parcel data, reply; 233 data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor()); 234 remote()->transact(GET_MAX_AMPLITUDE, data, &reply); 235 *max = reply.readInt32(); 236 return reply.readInt32(); 237 } 238 239 status_t start() 240 { 241 LOGV("start"); 242 Parcel data, reply; 243 data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor()); 244 remote()->transact(START, data, &reply); 245 return reply.readInt32(); 246 } 247 248 status_t stop() 249 { 250 LOGV("stop"); 251 Parcel data, reply; 252 data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor()); 253 remote()->transact(STOP, data, &reply); 254 return reply.readInt32(); 255 } 256 257 status_t reset() 258 { 259 LOGV("reset"); 260 Parcel data, reply; 261 data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor()); 262 remote()->transact(RESET, data, &reply); 263 return reply.readInt32(); 264 } 265 266 status_t close() 267 { 268 LOGV("close"); 269 Parcel data, reply; 270 data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor()); 271 remote()->transact(CLOSE, data, &reply); 272 return reply.readInt32(); 273 } 274 275 status_t release() 276 { 277 LOGV("release"); 278 Parcel data, reply; 279 data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor()); 280 remote()->transact(RELEASE, data, &reply); 281 return reply.readInt32(); 282 } 283 }; 284 285 IMPLEMENT_META_INTERFACE(MediaRecorder, "android.media.IMediaRecorder"); 286 287 // ---------------------------------------------------------------------- 288 289 status_t BnMediaRecorder::onTransact( 290 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) 291 { 292 switch(code) { 293 case RELEASE: { 294 LOGV("RELEASE"); 295 CHECK_INTERFACE(IMediaRecorder, data, reply); 296 reply->writeInt32(release()); 297 return NO_ERROR; 298 } break; 299 case INIT: { 300 LOGV("INIT"); 301 CHECK_INTERFACE(IMediaRecorder, data, reply); 302 reply->writeInt32(init()); 303 return NO_ERROR; 304 } break; 305 case CLOSE: { 306 LOGV("CLOSE"); 307 CHECK_INTERFACE(IMediaRecorder, data, reply); 308 reply->writeInt32(close()); 309 return NO_ERROR; 310 } break; 311 case RESET: { 312 LOGV("RESET"); 313 CHECK_INTERFACE(IMediaRecorder, data, reply); 314 reply->writeInt32(reset()); 315 return NO_ERROR; 316 } break; 317 case STOP: { 318 LOGV("STOP"); 319 CHECK_INTERFACE(IMediaRecorder, data, reply); 320 reply->writeInt32(stop()); 321 return NO_ERROR; 322 } break; 323 case START: { 324 LOGV("START"); 325 CHECK_INTERFACE(IMediaRecorder, data, reply); 326 reply->writeInt32(start()); 327 return NO_ERROR; 328 } break; 329 case PREPARE: { 330 LOGV("PREPARE"); 331 CHECK_INTERFACE(IMediaRecorder, data, reply); 332 reply->writeInt32(prepare()); 333 return NO_ERROR; 334 } break; 335 case GET_MAX_AMPLITUDE: { 336 LOGV("GET_MAX_AMPLITUDE"); 337 CHECK_INTERFACE(IMediaRecorder, data, reply); 338 int max = 0; 339 status_t ret = getMaxAmplitude(&max); 340 reply->writeInt32(max); 341 reply->writeInt32(ret); 342 return NO_ERROR; 343 } break; 344 case SET_VIDEO_SOURCE: { 345 LOGV("SET_VIDEO_SOURCE"); 346 CHECK_INTERFACE(IMediaRecorder, data, reply); 347 int vs = data.readInt32(); 348 reply->writeInt32(setVideoSource(vs)); 349 return NO_ERROR; 350 } break; 351 case SET_AUDIO_SOURCE: { 352 LOGV("SET_AUDIO_SOURCE"); 353 CHECK_INTERFACE(IMediaRecorder, data, reply); 354 int as = data.readInt32(); 355 reply->writeInt32(setAudioSource(as)); 356 return NO_ERROR; 357 } break; 358 case SET_OUTPUT_FORMAT: { 359 LOGV("SET_OUTPUT_FORMAT"); 360 CHECK_INTERFACE(IMediaRecorder, data, reply); 361 int of = data.readInt32(); 362 reply->writeInt32(setOutputFormat(of)); 363 return NO_ERROR; 364 } break; 365 case SET_VIDEO_ENCODER: { 366 LOGV("SET_VIDEO_ENCODER"); 367 CHECK_INTERFACE(IMediaRecorder, data, reply); 368 int ve = data.readInt32(); 369 reply->writeInt32(setVideoEncoder(ve)); 370 return NO_ERROR; 371 } break; 372 case SET_AUDIO_ENCODER: { 373 LOGV("SET_AUDIO_ENCODER"); 374 CHECK_INTERFACE(IMediaRecorder, data, reply); 375 int ae = data.readInt32(); 376 reply->writeInt32(setAudioEncoder(ae)); 377 return NO_ERROR; 378 379 } break; 380 case SET_OUTPUT_FILE_PATH: { 381 LOGV("SET_OUTPUT_FILE_PATH"); 382 CHECK_INTERFACE(IMediaRecorder, data, reply); 383 const char* path = data.readCString(); 384 reply->writeInt32(setOutputFile(path)); 385 return NO_ERROR; 386 } break; 387 case SET_OUTPUT_FILE_FD: { 388 LOGV("SET_OUTPUT_FILE_FD"); 389 CHECK_INTERFACE(IMediaRecorder, data, reply); 390 int fd = dup(data.readFileDescriptor()); 391 int64_t offset = data.readInt64(); 392 int64_t length = data.readInt64(); 393 reply->writeInt32(setOutputFile(fd, offset, length)); 394 ::close(fd); 395 return NO_ERROR; 396 } break; 397 case SET_VIDEO_SIZE: { 398 LOGV("SET_VIDEO_SIZE"); 399 CHECK_INTERFACE(IMediaRecorder, data, reply); 400 int width = data.readInt32(); 401 int height = data.readInt32(); 402 reply->writeInt32(setVideoSize(width, height)); 403 return NO_ERROR; 404 } break; 405 case SET_VIDEO_FRAMERATE: { 406 LOGV("SET_VIDEO_FRAMERATE"); 407 CHECK_INTERFACE(IMediaRecorder, data, reply); 408 int frames_per_second = data.readInt32(); 409 reply->writeInt32(setVideoFrameRate(frames_per_second)); 410 return NO_ERROR; 411 } break; 412 case SET_PARAMETERS: { 413 LOGV("SET_PARAMETER"); 414 CHECK_INTERFACE(IMediaRecorder, data, reply); 415 reply->writeInt32(setParameters(data.readString8())); 416 return NO_ERROR; 417 } break; 418 case SET_LISTENER: { 419 LOGV("SET_LISTENER"); 420 CHECK_INTERFACE(IMediaRecorder, data, reply); 421 sp<IMediaRecorderClient> listener = 422 interface_cast<IMediaRecorderClient>(data.readStrongBinder()); 423 reply->writeInt32(setListener(listener)); 424 return NO_ERROR; 425 } break; 426 case SET_PREVIEW_SURFACE: { 427 LOGV("SET_PREVIEW_SURFACE"); 428 CHECK_INTERFACE(IMediaRecorder, data, reply); 429 sp<Surface> surface = Surface::readFromParcel(data); 430 reply->writeInt32(setPreviewSurface(surface)); 431 return NO_ERROR; 432 } break; 433 case SET_CAMERA: { 434 LOGV("SET_CAMERA"); 435 CHECK_INTERFACE(IMediaRecorder, data, reply); 436 sp<ICamera> camera = interface_cast<ICamera>(data.readStrongBinder()); 437 sp<ICameraRecordingProxy> proxy = 438 interface_cast<ICameraRecordingProxy>(data.readStrongBinder()); 439 reply->writeInt32(setCamera(camera, proxy)); 440 return NO_ERROR; 441 } break; 442 case QUERY_SURFACE_MEDIASOURCE: { 443 LOGV("QUERY_SURFACE_MEDIASOURCE"); 444 CHECK_INTERFACE(IMediaRecorder, data, reply); 445 // call the mediaserver side to create 446 // a surfacemediasource 447 sp<ISurfaceTexture> surfaceMediaSource = querySurfaceMediaSource(); 448 // The mediaserver might have failed to create a source 449 int returnedNull= (surfaceMediaSource == NULL) ? 1 : 0 ; 450 reply->writeInt32(returnedNull); 451 if (!returnedNull) { 452 reply->writeStrongBinder(surfaceMediaSource->asBinder()); 453 } 454 return NO_ERROR; 455 } break; 456 default: 457 return BBinder::onTransact(code, data, reply, flags); 458 } 459 } 460 461 // ---------------------------------------------------------------------------- 462 463 }; // namespace android 464