-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathdecoder-jni.c
71 lines (59 loc) · 2.54 KB
/
decoder-jni.c
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
#include <jni.h>
#include <libavcodec/avcodec.h>
#include <libswscale/swscale.h>
#include <stdbool.h>
#include <android/bitmap.h>
AVCodecContext *pCodecCtx; // FFMPEG codec context
AVCodec *pCodec; // Pointer to FFMPEG codec (H264)
AVFrame *pFrame; // Used in the decoding process
struct SwsContext *convertCtx; // Used in the scaling/conversion process
AVPacket avpkt; // Used in the decoding process
int temp; // Various uses
bool Java_se_forskningsavd_automatonbrain_Decoder_init(JNIEnv* env, jobject thiz) {
avcodec_init();
avcodec_register_all();
pCodecCtx = avcodec_alloc_context();
pCodec = avcodec_find_decoder( CODEC_ID_H264 );
av_init_packet( &avpkt );
if( !pCodec ) {
return false;
//printf( "RoboCortex [error]: Unable to initialize decoder\n" );
//exit( EXIT_DECODER );
}
avcodec_open( pCodecCtx, pCodec );
// Allocate decoder frame
pFrame = avcodec_alloc_frame();
return true;
}
bool Java_se_forskningsavd_automatonbrain_Decoder_decode(JNIEnv *env, jobject thiz, jbyteArray frame, jobject bitmap) {
AndroidBitmapInfo bitmapInfo;
if (AndroidBitmap_getInfo(env, bitmap, &bitmapInfo) != 0) {
return false;
}
uint8_t *dest_data = 0; //TODO
avpkt.data = (*env)->GetByteArrayElements(env, frame, 0);
avpkt.size = (*env)->GetArrayLength(env, frame);
avpkt.flags = AV_PKT_FLAG_KEY;
int len = avcodec_decode_video2( pCodecCtx, pFrame, &temp, &avpkt );
(*env)->ReleaseByteArrayElements(env, frame, avpkt.data, JNI_ABORT);
if (len < 0 ) {
return false;
//printf( "RoboCortex [info]: Decoding error (packet loss)\n" );
} else {
void *bitmapData;
AndroidBitmap_lockPixels(env, bitmap, &bitmapData);
const uint8_t * data[1] = { bitmapData };
int linesize[1] = { bitmapInfo.stride };
// Create scaling & color-space conversion context
convertCtx = sws_getContext( pCodecCtx->width, pCodecCtx->height, pCodecCtx->pix_fmt,
bitmapInfo.width, bitmapInfo.height, PIX_FMT_BGRA, SWS_AREA, NULL, NULL, NULL);
// Scale and convert the frame
sws_scale( convertCtx, (const uint8_t**) pFrame->data, pFrame->linesize, 0,
pCodecCtx->height, (uint8_t * const*) data, linesize );
// Cleanup
sws_freeContext( convertCtx );
//
AndroidBitmap_unlockPixels(env, bitmap);
}
return true;
}