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