Example #1
0
bool v4l2codecOperationInit(V4l2CodecOps *opFuncs)
{
    if (!opFuncs)
        return false;

    int isVersionMatch = 0;
    IS_V4L2CODEC_OPS_VERSION_MATCH(opFuncs->mVersion, isVersionMatch);
    if (!isVersionMatch) {
        ERROR("V4l2CodecOps interface version doesn't match\n");
        return false;
    }
    ASSERT(opFuncs->mSize == sizeof(V4l2CodecOps));

    memset(opFuncs->mVendorString, 0, V4L2CODEC_VENDOR_STRING_SIZE);
    strncpy(opFuncs->mVendorString, "yami", V4L2CODEC_VENDOR_STRING_SIZE-1);

#define V4L2_DLSYM_OR_RETURN_ON_ERROR(name) opFuncs->m##name##Func = YamiV4L2_##name

    V4L2_DLSYM_OR_RETURN_ON_ERROR(Open);
    V4L2_DLSYM_OR_RETURN_ON_ERROR(Close);
    V4L2_DLSYM_OR_RETURN_ON_ERROR(Ioctl);
    V4L2_DLSYM_OR_RETURN_ON_ERROR(Poll);
    V4L2_DLSYM_OR_RETURN_ON_ERROR(SetDevicePollInterrupt);
    V4L2_DLSYM_OR_RETURN_ON_ERROR(ClearDevicePollInterrupt);
    V4L2_DLSYM_OR_RETURN_ON_ERROR(Mmap);
    V4L2_DLSYM_OR_RETURN_ON_ERROR(Munmap);
    V4L2_DLSYM_OR_RETURN_ON_ERROR(SetParameter);
#ifndef ANDROID
    V4L2_DLSYM_OR_RETURN_ON_ERROR(UseEglImage);
#endif
#undef V4L2_DLSYM_OR_RETURN_ON_ERROR

    return true;
}
Example #2
0
    bool init()
    {
        const char* libName = "libyami_v4l2.so";
        m_handle = dlopen(libName, RTLD_NOW | RTLD_GLOBAL);
        if (!m_handle) {
            ERROR("dlopen failed for %s", libName);
            return false;
        }

        V4l2codecOperationInitFunc initFunc = NULL;
        initFunc = (V4l2codecOperationInitFunc)dlsym(RTLD_DEFAULT, "v4l2codecOperationInit");

        if (!initFunc) {
            ERROR("fail to dlsym v4l2codecOperationInit\n");
            return false;
        }

        INIT_V4L2CODEC_OPS_SIZE_VERSION(&m_ops);
        if (!initFunc(&m_ops)) {
            ERROR("fail to init v4l2 device operation func pointers\n");
            return false;
        }

        int isVersionMatch = 0;
        IS_V4L2CODEC_OPS_VERSION_MATCH(m_ops.mVersion, isVersionMatch);
        if (!isVersionMatch) {
            ERROR("V4l2CodecOps interface version doesn't match\n");
            return false;
        }
        if (m_ops.mSize != sizeof(V4l2CodecOps)) {
            ERROR("V4l2CodecOps interface data structure size doesn't match\n");
            return false;
        }
        return true;
    }
Example #3
0
static bool loadV4l2CodecDevice(const char* libName )
{
    memset(&s_v4l2CodecOps, 0, sizeof(s_v4l2CodecOps));
    s_v4l2Fd = 0;

#ifndef ANDROID
    if (!dlopen(libName, RTLD_NOW | RTLD_GLOBAL | RTLD_NODELETE)) {
#else
    if (!dlopen(libName, RTLD_NOW | RTLD_GLOBAL)) {
#endif
      ERROR("Failed to load %s\n", libName);
      return false;
    }

    V4l2codecOperationInitFunc initFunc = NULL;
    initFunc = (V4l2codecOperationInitFunc)dlsym(RTLD_DEFAULT, "v4l2codecOperationInit");

    if (!initFunc) {
        ERROR("fail to dlsym v4l2codecOperationInit\n");
        return false;
    }

    INIT_V4L2CODEC_OPS_SIZE_VERSION(&s_v4l2CodecOps);
    if (!initFunc(&s_v4l2CodecOps)) {
        ERROR("fail to init v4l2 device operation func pointers\n");
        return false;
    }

    int isVersionMatch = 0;
    IS_V4L2CODEC_OPS_VERSION_MATCH(s_v4l2CodecOps.mVersion, isVersionMatch);
    if (!isVersionMatch) {
        ERROR("V4l2CodecOps interface version doesn't match\n");
        return false;
    }
    if(s_v4l2CodecOps.mSize != sizeof(V4l2CodecOps)) {
        ERROR("V4l2CodecOps interface data structure size doesn't match\n");
        return false;
    }

    return true;
}
#define SIMULATE_V4L2_OP(OP)  s_v4l2CodecOps.m##OP##Func
#else
#define SIMULATE_V4L2_OP(OP)  YamiV4L2_##OP
#endif


struct RawFrameData {
    uint32_t width;
    uint32_t height;
    uint32_t pitch[3];
    uint32_t offset[3];
    uint32_t fourcc;            //NV12
    uint8_t *data;
};

const uint32_t k_maxInputBufferSize = 1024*1024;
const int k_inputPlaneCount = 1;
const int k_maxOutputPlaneCount = 3;
int outputPlaneCount = 2;
int videoWidth = 0;
int videoHeight = 0;

uint32_t inputQueueCapacity = 0;
uint32_t outputQueueCapacity = 0;
uint32_t k_extraOutputFrameCount = 2;
static std::vector<uint8_t*> inputFrames;
static std::vector<struct RawFrameData> rawOutputFrames;

#if !__ENABLE_V4L2_GLX__
static VideoDataMemoryType memoryType = VIDEO_DATA_MEMORY_TYPE_DRM_NAME;
static const char* typeStrDrmName = "drm-name";
static const char* typeStrDmaBuf = "dma-buf";
static const char* typeStrRawData = "raw-data";
// static const char* typeStrAndroidNativeBuffer = "android-native-buffer";
static const char* memoryTypeStr = typeStrDrmName;
#define IS_DRM_NAME()   (!strcmp(memoryTypeStr, typeStrDrmName))
#define IS_DMA_BUF()   (!strcmp(memoryTypeStr, typeStrDmaBuf))
#define IS_RAW_DATA()   (!strcmp(memoryTypeStr, typeStrRawData))
// #define IS_ANDROID_NATIVE_BUFFER()   (!strcmp(memoryTypeStr, typeStrAndroidNativeBuffer))
#endif

static FILE* outfp = NULL;
#ifndef ANDROID
static Display * x11Display = NULL;
static Window x11Window = 0;
#endif
#ifdef ANDROID
#elif __ENABLE_V4L2_GLX__
static GLXContextType *glxContext;
std::vector <Pixmap> pixmaps;
std::vector <GLXPixmap> glxPixmaps;
#else
static EGLContextType *eglContext = NULL;
static std::vector<EGLImageKHR> eglImages;
#endif
#ifndef ANDROID
static std::vector<GLuint> textureIds;
#endif
static bool isReadEOS=false;
static int32_t stagingBufferInDevice = 0;
static uint32_t renderFrameCount = 0;

bool feedOneInputFrame(DecodeInput * input, int fd, int index = -1 /* if index is not -1, simple enque it*/)
{

    VideoDecodeBuffer inputBuffer;
    struct v4l2_buffer buf;
    struct v4l2_plane planes[k_inputPlaneCount];
    int ioctlRet = -1;

    memset(&buf, 0, sizeof(buf));
    memset(&planes, 0, sizeof(planes));
    buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; // it indicates input buffer(raw frame) type
    buf.memory = V4L2_MEMORY_MMAP;
    buf.m.planes = planes;
    buf.length = k_inputPlaneCount;

    if (index == -1) {
        ioctlRet = SIMULATE_V4L2_OP(Ioctl)(fd, VIDIOC_DQBUF, &buf);
        if (ioctlRet == -1)
            return true;
        stagingBufferInDevice --;
    } else {
        buf.index = index;
    }

    if (isReadEOS)
        return false;

    if (!input->getNextDecodeUnit(inputBuffer)) {
        // send empty buffer for EOS
        buf.m.planes[0].bytesused = 0;
        isReadEOS = true;
    } else {
        ASSERT(inputBuffer.size <= k_maxInputBufferSize);
        memcpy(inputFrames[buf.index], inputBuffer.data, inputBuffer.size);
        buf.m.planes[0].bytesused = inputBuffer.size;
        buf.m.planes[0].m.mem_offset = 0;
        buf.flags = inputBuffer.flag;
    }

    ioctlRet = SIMULATE_V4L2_OP(Ioctl)(fd, VIDIOC_QBUF, &buf);
    ASSERT(ioctlRet != -1);

    stagingBufferInDevice ++;
    return true;
}