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