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 21#include <inttypes.h> 22#include <unistd.h> 23 24#include <utils/Log.h> 25#include <binder/Parcel.h> 26#include <camera/android/hardware/ICamera.h> 27#include <camera/ICameraRecordingProxy.h> 28#include <media/IMediaRecorderClient.h> 29#include <media/IMediaRecorder.h> 30#include <gui/Surface.h> 31#include <gui/IGraphicBufferProducer.h> 32 33namespace android { 34 35enum { 36 RELEASE = IBinder::FIRST_CALL_TRANSACTION, 37 INIT, 38 CLOSE, 39 SET_INPUT_SURFACE, 40 QUERY_SURFACE_MEDIASOURCE, 41 RESET, 42 STOP, 43 START, 44 PREPARE, 45 GET_MAX_AMPLITUDE, 46 SET_VIDEO_SOURCE, 47 SET_AUDIO_SOURCE, 48 SET_OUTPUT_FORMAT, 49 SET_VIDEO_ENCODER, 50 SET_AUDIO_ENCODER, 51 SET_OUTPUT_FILE_FD, 52 SET_VIDEO_SIZE, 53 SET_VIDEO_FRAMERATE, 54 SET_PARAMETERS, 55 SET_PREVIEW_SURFACE, 56 SET_CAMERA, 57 SET_LISTENER, 58 SET_CLIENT_NAME, 59 PAUSE, 60 RESUME 61}; 62 63class BpMediaRecorder: public BpInterface<IMediaRecorder> 64{ 65public: 66 BpMediaRecorder(const sp<IBinder>& impl) 67 : BpInterface<IMediaRecorder>(impl) 68 { 69 } 70 71 status_t setCamera(const sp<hardware::ICamera>& camera, const sp<ICameraRecordingProxy>& proxy) 72 { 73 ALOGV("setCamera(%p,%p)", camera.get(), proxy.get()); 74 Parcel data, reply; 75 data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor()); 76 data.writeStrongBinder(IInterface::asBinder(camera)); 77 data.writeStrongBinder(IInterface::asBinder(proxy)); 78 remote()->transact(SET_CAMERA, data, &reply); 79 return reply.readInt32(); 80 } 81 82 status_t setInputSurface(const sp<IGraphicBufferConsumer>& surface) 83 { 84 ALOGV("setInputSurface(%p)", surface.get()); 85 Parcel data, reply; 86 data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor()); 87 data.writeStrongBinder(IInterface::asBinder(surface)); 88 remote()->transact(SET_INPUT_SURFACE, data, &reply); 89 return reply.readInt32(); 90 } 91 92 sp<IGraphicBufferProducer> querySurfaceMediaSource() 93 { 94 ALOGV("Query SurfaceMediaSource"); 95 Parcel data, reply; 96 data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor()); 97 remote()->transact(QUERY_SURFACE_MEDIASOURCE, data, &reply); 98 int returnedNull = reply.readInt32(); 99 if (returnedNull) { 100 return NULL; 101 } 102 return interface_cast<IGraphicBufferProducer>(reply.readStrongBinder()); 103 } 104 105 status_t setPreviewSurface(const sp<IGraphicBufferProducer>& surface) 106 { 107 ALOGV("setPreviewSurface(%p)", surface.get()); 108 Parcel data, reply; 109 data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor()); 110 data.writeStrongBinder(IInterface::asBinder(surface)); 111 remote()->transact(SET_PREVIEW_SURFACE, data, &reply); 112 return reply.readInt32(); 113 } 114 115 status_t init() 116 { 117 ALOGV("init"); 118 Parcel data, reply; 119 data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor()); 120 remote()->transact(INIT, data, &reply); 121 return reply.readInt32(); 122 } 123 124 status_t setVideoSource(int vs) 125 { 126 ALOGV("setVideoSource(%d)", vs); 127 Parcel data, reply; 128 data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor()); 129 data.writeInt32(vs); 130 remote()->transact(SET_VIDEO_SOURCE, data, &reply); 131 return reply.readInt32(); 132 } 133 134 status_t setAudioSource(int as) 135 { 136 ALOGV("setAudioSource(%d)", as); 137 Parcel data, reply; 138 data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor()); 139 data.writeInt32(as); 140 remote()->transact(SET_AUDIO_SOURCE, data, &reply); 141 return reply.readInt32(); 142 } 143 144 status_t setOutputFormat(int of) 145 { 146 ALOGV("setOutputFormat(%d)", of); 147 Parcel data, reply; 148 data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor()); 149 data.writeInt32(of); 150 remote()->transact(SET_OUTPUT_FORMAT, data, &reply); 151 return reply.readInt32(); 152 } 153 154 status_t setVideoEncoder(int ve) 155 { 156 ALOGV("setVideoEncoder(%d)", ve); 157 Parcel data, reply; 158 data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor()); 159 data.writeInt32(ve); 160 remote()->transact(SET_VIDEO_ENCODER, data, &reply); 161 return reply.readInt32(); 162 } 163 164 status_t setAudioEncoder(int ae) 165 { 166 ALOGV("setAudioEncoder(%d)", ae); 167 Parcel data, reply; 168 data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor()); 169 data.writeInt32(ae); 170 remote()->transact(SET_AUDIO_ENCODER, data, &reply); 171 return reply.readInt32(); 172 } 173 174 status_t setOutputFile(int fd, int64_t offset, int64_t length) { 175 ALOGV("setOutputFile(%d, %" PRId64 ", %" PRId64 ")", fd, offset, length); 176 Parcel data, reply; 177 data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor()); 178 data.writeFileDescriptor(fd); 179 data.writeInt64(offset); 180 data.writeInt64(length); 181 remote()->transact(SET_OUTPUT_FILE_FD, data, &reply); 182 return reply.readInt32(); 183 } 184 185 status_t setVideoSize(int width, int height) 186 { 187 ALOGV("setVideoSize(%dx%d)", width, height); 188 Parcel data, reply; 189 data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor()); 190 data.writeInt32(width); 191 data.writeInt32(height); 192 remote()->transact(SET_VIDEO_SIZE, data, &reply); 193 return reply.readInt32(); 194 } 195 196 status_t setVideoFrameRate(int frames_per_second) 197 { 198 ALOGV("setVideoFrameRate(%d)", frames_per_second); 199 Parcel data, reply; 200 data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor()); 201 data.writeInt32(frames_per_second); 202 remote()->transact(SET_VIDEO_FRAMERATE, data, &reply); 203 return reply.readInt32(); 204 } 205 206 status_t setParameters(const String8& params) 207 { 208 ALOGV("setParameter(%s)", params.string()); 209 Parcel data, reply; 210 data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor()); 211 data.writeString8(params); 212 remote()->transact(SET_PARAMETERS, data, &reply); 213 return reply.readInt32(); 214 } 215 216 status_t setListener(const sp<IMediaRecorderClient>& listener) 217 { 218 ALOGV("setListener(%p)", listener.get()); 219 Parcel data, reply; 220 data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor()); 221 data.writeStrongBinder(IInterface::asBinder(listener)); 222 remote()->transact(SET_LISTENER, data, &reply); 223 return reply.readInt32(); 224 } 225 226 status_t setClientName(const String16& clientName) 227 { 228 ALOGV("setClientName(%s)", String8(clientName).string()); 229 Parcel data, reply; 230 data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor()); 231 data.writeString16(clientName); 232 remote()->transact(SET_CLIENT_NAME, data, &reply); 233 return reply.readInt32(); 234 } 235 236 status_t prepare() 237 { 238 ALOGV("prepare"); 239 Parcel data, reply; 240 data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor()); 241 remote()->transact(PREPARE, data, &reply); 242 return reply.readInt32(); 243 } 244 245 status_t getMaxAmplitude(int* max) 246 { 247 ALOGV("getMaxAmplitude"); 248 Parcel data, reply; 249 data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor()); 250 remote()->transact(GET_MAX_AMPLITUDE, data, &reply); 251 *max = reply.readInt32(); 252 return reply.readInt32(); 253 } 254 255 status_t start() 256 { 257 ALOGV("start"); 258 Parcel data, reply; 259 data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor()); 260 remote()->transact(START, data, &reply); 261 return reply.readInt32(); 262 } 263 264 status_t stop() 265 { 266 ALOGV("stop"); 267 Parcel data, reply; 268 data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor()); 269 remote()->transact(STOP, data, &reply); 270 return reply.readInt32(); 271 } 272 273 status_t reset() 274 { 275 ALOGV("reset"); 276 Parcel data, reply; 277 data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor()); 278 remote()->transact(RESET, data, &reply); 279 return reply.readInt32(); 280 } 281 282 status_t pause() 283 { 284 ALOGV("pause"); 285 Parcel data, reply; 286 data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor()); 287 remote()->transact(PAUSE, data, &reply); 288 return reply.readInt32(); 289 } 290 291 status_t resume() 292 { 293 ALOGV("resume"); 294 Parcel data, reply; 295 data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor()); 296 remote()->transact(RESUME, data, &reply); 297 return reply.readInt32(); 298 } 299 300 status_t close() 301 { 302 ALOGV("close"); 303 Parcel data, reply; 304 data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor()); 305 remote()->transact(CLOSE, data, &reply); 306 return reply.readInt32(); 307 } 308 309 status_t release() 310 { 311 ALOGV("release"); 312 Parcel data, reply; 313 data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor()); 314 remote()->transact(RELEASE, data, &reply); 315 return reply.readInt32(); 316 } 317}; 318 319IMPLEMENT_META_INTERFACE(MediaRecorder, "android.media.IMediaRecorder"); 320 321// ---------------------------------------------------------------------- 322 323status_t BnMediaRecorder::onTransact( 324 uint32_t code, const Parcel& data, Parcel* reply, 325 uint32_t flags) 326{ 327 switch (code) { 328 case RELEASE: { 329 ALOGV("RELEASE"); 330 CHECK_INTERFACE(IMediaRecorder, data, reply); 331 reply->writeInt32(release()); 332 return NO_ERROR; 333 } break; 334 case INIT: { 335 ALOGV("INIT"); 336 CHECK_INTERFACE(IMediaRecorder, data, reply); 337 reply->writeInt32(init()); 338 return NO_ERROR; 339 } break; 340 case CLOSE: { 341 ALOGV("CLOSE"); 342 CHECK_INTERFACE(IMediaRecorder, data, reply); 343 reply->writeInt32(close()); 344 return NO_ERROR; 345 } break; 346 case RESET: { 347 ALOGV("RESET"); 348 CHECK_INTERFACE(IMediaRecorder, data, reply); 349 reply->writeInt32(reset()); 350 return NO_ERROR; 351 } break; 352 case STOP: { 353 ALOGV("STOP"); 354 CHECK_INTERFACE(IMediaRecorder, data, reply); 355 reply->writeInt32(stop()); 356 return NO_ERROR; 357 } break; 358 case START: { 359 ALOGV("START"); 360 CHECK_INTERFACE(IMediaRecorder, data, reply); 361 reply->writeInt32(start()); 362 return NO_ERROR; 363 } break; 364 case PAUSE: { 365 ALOGV("PAUSE"); 366 CHECK_INTERFACE(IMediaRecorder, data, reply); 367 reply->writeInt32(pause()); 368 return NO_ERROR; 369 } break; 370 case RESUME: { 371 ALOGV("RESUME"); 372 CHECK_INTERFACE(IMediaRecorder, data, reply); 373 reply->writeInt32(resume()); 374 return NO_ERROR; 375 } break; 376 case PREPARE: { 377 ALOGV("PREPARE"); 378 CHECK_INTERFACE(IMediaRecorder, data, reply); 379 reply->writeInt32(prepare()); 380 return NO_ERROR; 381 } break; 382 case GET_MAX_AMPLITUDE: { 383 ALOGV("GET_MAX_AMPLITUDE"); 384 CHECK_INTERFACE(IMediaRecorder, data, reply); 385 int max = 0; 386 status_t ret = getMaxAmplitude(&max); 387 reply->writeInt32(max); 388 reply->writeInt32(ret); 389 return NO_ERROR; 390 } break; 391 case SET_VIDEO_SOURCE: { 392 ALOGV("SET_VIDEO_SOURCE"); 393 CHECK_INTERFACE(IMediaRecorder, data, reply); 394 int vs = data.readInt32(); 395 reply->writeInt32(setVideoSource(vs)); 396 return NO_ERROR; 397 } break; 398 case SET_AUDIO_SOURCE: { 399 ALOGV("SET_AUDIO_SOURCE"); 400 CHECK_INTERFACE(IMediaRecorder, data, reply); 401 int as = data.readInt32(); 402 reply->writeInt32(setAudioSource(as)); 403 return NO_ERROR; 404 } break; 405 case SET_OUTPUT_FORMAT: { 406 ALOGV("SET_OUTPUT_FORMAT"); 407 CHECK_INTERFACE(IMediaRecorder, data, reply); 408 int of = data.readInt32(); 409 reply->writeInt32(setOutputFormat(of)); 410 return NO_ERROR; 411 } break; 412 case SET_VIDEO_ENCODER: { 413 ALOGV("SET_VIDEO_ENCODER"); 414 CHECK_INTERFACE(IMediaRecorder, data, reply); 415 int ve = data.readInt32(); 416 reply->writeInt32(setVideoEncoder(ve)); 417 return NO_ERROR; 418 } break; 419 case SET_AUDIO_ENCODER: { 420 ALOGV("SET_AUDIO_ENCODER"); 421 CHECK_INTERFACE(IMediaRecorder, data, reply); 422 int ae = data.readInt32(); 423 reply->writeInt32(setAudioEncoder(ae)); 424 return NO_ERROR; 425 426 } break; 427 case SET_OUTPUT_FILE_FD: { 428 ALOGV("SET_OUTPUT_FILE_FD"); 429 CHECK_INTERFACE(IMediaRecorder, data, reply); 430 int fd = dup(data.readFileDescriptor()); 431 int64_t offset = data.readInt64(); 432 int64_t length = data.readInt64(); 433 reply->writeInt32(setOutputFile(fd, offset, length)); 434 ::close(fd); 435 return NO_ERROR; 436 } break; 437 case SET_VIDEO_SIZE: { 438 ALOGV("SET_VIDEO_SIZE"); 439 CHECK_INTERFACE(IMediaRecorder, data, reply); 440 int width = data.readInt32(); 441 int height = data.readInt32(); 442 reply->writeInt32(setVideoSize(width, height)); 443 return NO_ERROR; 444 } break; 445 case SET_VIDEO_FRAMERATE: { 446 ALOGV("SET_VIDEO_FRAMERATE"); 447 CHECK_INTERFACE(IMediaRecorder, data, reply); 448 int frames_per_second = data.readInt32(); 449 reply->writeInt32(setVideoFrameRate(frames_per_second)); 450 return NO_ERROR; 451 } break; 452 case SET_PARAMETERS: { 453 ALOGV("SET_PARAMETER"); 454 CHECK_INTERFACE(IMediaRecorder, data, reply); 455 reply->writeInt32(setParameters(data.readString8())); 456 return NO_ERROR; 457 } break; 458 case SET_LISTENER: { 459 ALOGV("SET_LISTENER"); 460 CHECK_INTERFACE(IMediaRecorder, data, reply); 461 sp<IMediaRecorderClient> listener = 462 interface_cast<IMediaRecorderClient>(data.readStrongBinder()); 463 reply->writeInt32(setListener(listener)); 464 return NO_ERROR; 465 } break; 466 case SET_CLIENT_NAME: { 467 ALOGV("SET_CLIENT_NAME"); 468 CHECK_INTERFACE(IMediaRecorder, data, reply); 469 reply->writeInt32(setClientName(data.readString16())); 470 return NO_ERROR; 471 } 472 case SET_PREVIEW_SURFACE: { 473 ALOGV("SET_PREVIEW_SURFACE"); 474 CHECK_INTERFACE(IMediaRecorder, data, reply); 475 sp<IGraphicBufferProducer> surface = interface_cast<IGraphicBufferProducer>( 476 data.readStrongBinder()); 477 reply->writeInt32(setPreviewSurface(surface)); 478 return NO_ERROR; 479 } break; 480 case SET_CAMERA: { 481 ALOGV("SET_CAMERA"); 482 CHECK_INTERFACE(IMediaRecorder, data, reply); 483 sp<hardware::ICamera> camera = 484 interface_cast<hardware::ICamera>(data.readStrongBinder()); 485 sp<ICameraRecordingProxy> proxy = 486 interface_cast<ICameraRecordingProxy>(data.readStrongBinder()); 487 reply->writeInt32(setCamera(camera, proxy)); 488 return NO_ERROR; 489 } break; 490 case SET_INPUT_SURFACE: { 491 ALOGV("SET_INPUT_SURFACE"); 492 CHECK_INTERFACE(IMediaRecorder, data, reply); 493 sp<IGraphicBufferConsumer> surface = interface_cast<IGraphicBufferConsumer>( 494 data.readStrongBinder()); 495 reply->writeInt32(setInputSurface(surface)); 496 return NO_ERROR; 497 } break; 498 case QUERY_SURFACE_MEDIASOURCE: { 499 ALOGV("QUERY_SURFACE_MEDIASOURCE"); 500 CHECK_INTERFACE(IMediaRecorder, data, reply); 501 // call the mediaserver side to create 502 // a surfacemediasource 503 sp<IGraphicBufferProducer> surfaceMediaSource = querySurfaceMediaSource(); 504 // The mediaserver might have failed to create a source 505 int returnedNull= (surfaceMediaSource == NULL) ? 1 : 0 ; 506 reply->writeInt32(returnedNull); 507 if (!returnedNull) { 508 reply->writeStrongBinder(IInterface::asBinder(surfaceMediaSource)); 509 } 510 return NO_ERROR; 511 } break; 512 default: 513 return BBinder::onTransact(code, data, reply, flags); 514 } 515} 516 517// ---------------------------------------------------------------------------- 518 519} // namespace android 520