Search code examples
androidandroid-mediarecorder

MediaRecorder start error codes


I want to record raw h.264 video without sound and possibly HW accelerated (and stream it later). So I decided to use MediaRecorder (and the socket hack for streaming).

I have the following code:

final MediaRecorder recorder = new MediaRecorder();
final Camera camera = Camera.open();
camera.unlock();
recorder.setCamera(camera);
recorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
recorder.setOutputFormat(MediaRecorder.OutputFormat.DEFAULT);
recorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
final CamcorderProfile profile = CamcorderProfile.get(CamcorderProfile.QUALITY_LOW);
recorder.setVideoSize(profile.videoFrameWidth, profile.videoFrameHeight);
recorder.setVideoFrameRate(profile.videoFrameRate);
recorder.setVideoEncodingBitRate(profile.videoBitRate);
recorder.prepare();
recorder.start();

And bam! This in logcat:

E/MediaRecorder﹕ start failed: -38

I started googling, and found plenty of questions and answers, but none about my error code -38.

So I tried to look at Android source code, and noticed it's native method, and I don't know where to look for that.

So my big question is: Is there some list of those error codes, so I could find what error -38 means?`

Also know tjat I'm targeting API 10 (Gingerbread) and building with latest SDK 21.


Solution

  • Alright, I think I have an answer for you. The start function that is failing is defined in a file called mediarecorder.cpp. Found here:

    frameworks/av/media/libmedia/mediarecorder.cpp
    

    This start function returns a variable of type status_t, and corresponds to the error that you're seeing thrown.

    Now, the type status_t is defined in a file called Errors.h which can be found here:

    system/core/include/utils/Errors.h
    

    This defines an enumeration that corresponds to status_t as seen here:

    enum {
        OK                = 0,    // Everything's swell.
        NO_ERROR          = 0,    // No errors.
    
        UNKNOWN_ERROR       = 0x80000000,
    
        NO_MEMORY           = -ENOMEM,
        INVALID_OPERATION   = -ENOSYS,
        BAD_VALUE           = -EINVAL,
        BAD_TYPE            = 0x80000001,
        NAME_NOT_FOUND      = -ENOENT,
        PERMISSION_DENIED   = -EPERM,
        NO_INIT             = -ENODEV,
        ALREADY_EXISTS      = -EEXIST,
        DEAD_OBJECT         = -EPIPE,
        FAILED_TRANSACTION  = 0x80000002,
        JPARKS_BROKE_IT     = -EPIPE,
    #if !defined(HAVE_MS_C_RUNTIME)
        BAD_INDEX           = -EOVERFLOW,
        NOT_ENOUGH_DATA     = -ENODATA,
        WOULD_BLOCK         = -EWOULDBLOCK, 
        TIMED_OUT           = -ETIMEDOUT,
        UNKNOWN_TRANSACTION = -EBADMSG,
    #else    
        BAD_INDEX           = -E2BIG,
        NOT_ENOUGH_DATA     = 0x80000003,
        WOULD_BLOCK         = 0x80000004,
        TIMED_OUT           = 0x80000005,
        UNKNOWN_TRANSACTION = 0x80000006,
    #endif    
        FDS_NOT_ALLOWED     = 0x80000007,
    };
    

    As you can see, some of the values here are taken from errno.h, so we just need to see which one equates to a value of 38.

    According to this source, 38 corresponds to ENOSYS. So, if we look back at the status_t enumeration, we can see that in android, ENOSYS corresponds to an invalid operation. Not terribly helpful, but I hope this at least points you in the right direction.