Chaoqi Zhang
Chaoqi Zhang

Reputation: 11

How to call the functions in libvpx.so correctly?

I wanna decode the vp8 frame data received from UDP. So how can I call the functions in libvpx.so?

I downloaded the libvpx v1.8.1. package and I compiled the libvpx to get libvpx.so. My computer is:

Linux ubuntu 4.18.0-25-generic #26~18.04.1-Ubuntu SMP

My libvpx.so configure is :

../configure --log=yes --target=x86_64-linux-gcc --enable-pic --enable-ccache --enable-debug --enable-install-docs --enable-unit-tests --enable-decode-perf-tests --enable-encode-perf-tests --enable-better-hw-compatibility --enable-vp8 --enable-vp9 --enable-internal-stats --enable-postproc --enable-vp9-postproc --enable-error-concealment --enable-shared --enable-multi-res-encoding --enable-webm-io --enable-libyuv

I wrote a c file to do the thing above. My source file is :

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#include "vpx/vpx_decoder.h"
#include "vpx/vp8dx.h"


#define DEBUGPRINT

#ifdef DEBUGPRINT
#define DPRINT(format, arg...)  printf(format, ##arg)
#else 
#define DPRINT(format, arg...) do{}while(0)
#endif


#define UDP_SERV_PORT (12345)
#define UDP_RECV_DATA_MAXLEN (65535)
#define IVF_HEADER_SIZE (12)


int main(int argc, char **argv)
{
    int sockfd;
    struct sockaddr_in servaddr, cliaddr;

    sockfd = socket(PF_INET, SOCK_DGRAM, 0);
    if(sockfd < 0) {
        perror("socket create failed!");
        exit(0);
    }

    bzero(&servaddr, sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    servaddr.sin_port = htons(UDP_SERV_PORT);

    if( bind(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) ) {
        perror("bind failed!");
        exit(0);
    }

    char recvdata[UDP_RECV_DATA_MAXLEN];
    int rdatalen = 0, clilen = 0;

    vpx_codec_ctx_t decoder;
    vpx_codec_dec_cfg_t* dec_cfg = NULL;
    vpx_codec_flags_t dec_flags = 0;
    vpx_codec_dec_init(&decoder, &vpx_codec_vp8_dx_algo, dec_cfg, dec_flags);

    while(1) {
        memset(recvdata, 0, UDP_RECV_DATA_MAXLEN);
        rdatalen = recvfrom(sockfd, recvdata, UDP_RECV_DATA_MAXLEN, 0, (struct sockaddr *)&cliaddr, &clilen);
        DPRINT(" recv %d data from %s:%d\n", rdatalen, inet_ntoa(cliaddr.sin_addr), ntohs(cliaddr.sin_port));

        vpx_codec_iter_t iter = NULL;
        vpx_image_t* img;
        int frame_size = 0;
        frame_size += (int) ((recvdata[0]));
        frame_size += (int) ((recvdata[1]) << 8);
        frame_size += (int) ((recvdata[2]) << 16);
        frame_size += (int) ((recvdata[3]) << 24);
        vpx_codec_decode(&decoder, &recvdata[IVF_HEADER_SIZE], frame_size, NULL, 0);
        img = vpx_codec_get_frame(&decoder, &iter);
        DPRINT(" img: d_w=%d d_h=%d\n", img->d_w, img->d_h);
    }

    return 0;
    // close(sockfd);
}

I put the libvpx.so file and the vpx/* source code from the package to the same path with my source c code. And I used gcc to compile the file like this:

gcc -Wall -L. -lvpx udpframedecoder.c -o main

But I got this:

udpframedecoder.c: In function ‘main’:
udpframedecoder.c:66:101: warning: pointer targets in passing argument 6 of ‘recvfrom’ differ in signedness [-Wpointer-sign]
 rdatalen = recvfrom(sockfd, recvdata, UDP_RECV_DATA_MAXLEN, 0, (struct sockaddr *)&cliaddr, &clilen);
                                                                                             ^
In file included from udpframedecoder.c:5:0:
/usr/include/x86_64-linux-gnu/sys/socket.h:163:16: note: expected ‘socklen_t * restrict {aka unsigned int * restrict}’ but argument is of type ‘int *’
 extern ssize_t recvfrom (int __fd, void *__restrict __buf, size_t __n,
                ^~~~~~~~
udpframedecoder.c:76:36: warning: pointer targets in passing argument 2 of ‘vpx_codec_decode’ differ in signedness [-Wpointer-sign]
         vpx_codec_decode(&decoder, &recvdata[IVF_HEADER_SIZE], frame_size, NULL, 0);
                                    ^
In file included from udpframedecoder.c:9:0:
vpx/vpx_decoder.h:215:17: note: expected ‘const uint8_t * {aka const unsigned char *}’ but argument is of type ‘char *’
 vpx_codec_err_t vpx_codec_decode(vpx_codec_ctx_t *ctx, const uint8_t *data,
                 ^~~~~~~~~~~~~~~~
/tmp/ccHVjYj5.o: In function `vpx_codec_control_VP8_SET_REFERENCE':
udpframedecoder.c:(.text+0x29): undefined reference to `vpx_codec_control_'
/tmp/ccHVjYj5.o: In function `vpx_codec_control_VP8_COPY_REFERENCE':
udpframedecoder.c:(.text+0x58): undefined reference to `vpx_codec_control_'
/tmp/ccHVjYj5.o: In function `vpx_codec_control_VP8_SET_POSTPROC':
udpframedecoder.c:(.text+0x87): undefined reference to `vpx_codec_control_'
/tmp/ccHVjYj5.o: In function `vpx_codec_control_VP9_GET_REFERENCE':
udpframedecoder.c:(.text+0xb6): undefined reference to `vpx_codec_control_'
/tmp/ccHVjYj5.o: In function `vpx_codec_control_VP8D_GET_LAST_REF_UPDATES':
udpframedecoder.c:(.text+0xe5): undefined reference to `vpx_codec_control_'
/tmp/ccHVjYj5.o:udpframedecoder.c:(.text+0x114): more undefined references to `vpx_codec_control_' follow
/tmp/ccHVjYj5.o: In function `main':
udpframedecoder.c:(.text+0x461): undefined reference to `vpx_codec_vp8_dx_algo'
udpframedecoder.c:(.text+0x469): undefined reference to `vpx_codec_dec_init_ver'
udpframedecoder.c:(.text+0x582): undefined reference to `vpx_codec_decode'
udpframedecoder.c:(.text+0x59b): undefined reference to `vpx_codec_get_frame'
collect2: error: ld returned 1 exit status

The "vpx_codec_control_" is contained in the "vpx/vpx_codec.h". And the "vpx/vpx_decoder.h" include the "vpx/vpx_codec.h". It seems like that I did not link the .so file well. But I don't know where it is wrong. Can somebody help me this?

Upvotes: 1

Views: 627

Answers (1)

Chaoqi Zhang
Chaoqi Zhang

Reputation: 11

I have found the reason. I should compile the file like this:

gcc udpframedecoder.c -o main -Wall -L. -lvpx 

And this can fix this problem.

Upvotes: 0

Related Questions