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