-
Notifications
You must be signed in to change notification settings - Fork 27
/
h264hwenc_mediaserver.cpp
executable file
·140 lines (116 loc) · 3.97 KB
/
h264hwenc_mediaserver.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
#define LOG_TAG "h264hwenc"
// 包含头文件
#include <jni.h>
#include <stdlib.h>
#include <pthread.h>
#include <utils/Log.h>
#include "ffencoder.h"
#include "h264hwenc.h"
#include <binder/Binder.h>
#include <binder/IPCThreadState.h>
#include <binder/IServiceManager.h>
namespace android
{
class IH264EncService : public IInterface {
public:
DECLARE_META_INTERFACE(H264EncService);
virtual int init(int iw, int ih, int ow, int oh, int frate, int bitrate) = 0;
virtual void close(int handle) = 0;
virtual int encode(int handle, int64_t pts, void *phyy, void *phyc, int timeout, void *param) = 0;
};
enum {
INIT = IBinder::FIRST_CALL_TRANSACTION,
CLOSE,
ENCODE,
};
// client class
class BpH264EncService: public BpInterface<IH264EncService> {
public:
BpH264EncService(const sp<IBinder>& impl) : BpInterface<IH264EncService>(impl) {}
int init(int iw, int ih, int ow, int oh, int frate, int bitrate) {
Parcel data, reply;
data.writeInt32(iw);
data.writeInt32(ih);
data.writeInt32(ow);
data.writeInt32(oh);
data.writeInt32(frate);
data.writeInt32(bitrate);
remote()->transact(INIT, data, &reply);
return reply.readInt32();
}
void close(int handle) {
Parcel data, reply;
data.writeInt32(handle);
remote()->transact(CLOSE, data, &reply);
}
int encode(int handle, int64_t pts, void *phyy, void *phyc, int timeout, void *param) {
Parcel data, reply;
int key, len;
uint8_t *buf;
data.writeInt32(handle);
data.writeInt64(pts);
data.writeInt32((int32_t)phyy);
data.writeInt32((int32_t)phyc);
data.writeInt32(timeout);
remote()->transact(ENCODE, data, &reply);
key = reply.readInt32() ? AV_PKT_FLAG_KEY : 0;
len = reply.readInt32();
buf = (uint8_t*)reply.readInplace(len);
ffencoder_write_video_frame(param, key, buf, len, pts);
return len;
}
};
IMPLEMENT_META_INTERFACE(H264EncService, "android.mediaserver.IH264EncService");
}
// 内部类型定义
// h264hwenc context
typedef struct {
void *ffencoder;
android::sp<android::IH264EncService> cs;
int handle;
} H264ENC;
// 函数实现
void *h264hwenc_mediaserver_init(int iw, int ih, int ow, int oh, int frate, int bitrate, void *ffencoder)
{
H264ENC *enc = new H264ENC();
if (!enc) {
ALOGE("failed to allocate h264hwenc context !\n");
return NULL;
}
android::sp<android::IServiceManager> sm = android::defaultServiceManager();
android::sp<android::IBinder > binder = sm->getService(android::String16("media.h264enc"));
android::sp<android::IH264EncService> cs = android::interface_cast<android::IH264EncService>(binder);
enc->ffencoder = ffencoder;
enc->cs = cs;
enc->handle = cs->init(iw, ih, ow, oh, frate, bitrate);
return enc;
}
void h264hwenc_mediaserver_close(void *ctxt)
{
H264ENC *enc = (H264ENC*)ctxt;
if (!enc) return;
enc->cs->close(enc->handle);
enc->cs = NULL;
delete enc;
}
int h264hwenc_mediaserver_picture_format(void *ctxt)
{
return AV_PIX_FMT_NV12;
}
int h264hwenc_mediaserver_picture_alloc(void *ctxt, AVFrame *frame)
{
// do nothing
return 0;
}
int h264hwenc_mediaserver_picture_free(void *ctxt, AVFrame *frame)
{
// do nothing
return 0;
}
int h264hwenc_mediaserver_encode(void *ctxt, AVFrame *frame, int timeout)
{
H264ENC *enc = (H264ENC*)ctxt;
if (!enc) return -1;
enc->cs->encode(enc->handle, frame->pts, frame->data[6], frame->data[7], timeout, enc->ffencoder);
return 0;
}