Statistics
| Branch: | Revision:

ffmpeg / libavcodec / avcodec.c @ fb602cd1

History | View | Annotate | Download (3.58 KB)

1
#include "errno.h"
2
#include "avcodec.h"
3

    
4
#ifndef MKTAG
5
#define MKTAG(a,b,c,d) (a | (b << 8) | (c << 16) | (d << 24))
6
#endif
7

    
8
// private structure used to hide all internal memory allocations
9
// and structures used for de/encoding - end user should
10
// never see any complicated structure
11
typedef struct private_handle
12
{
13
    AVCodec* avcodec;
14
    AVCodecContext avcontext;
15
    struct private_handle* next;
16
    struct private_handle* prev;
17
} private_handle_t;
18

    
19
static private_handle_t* handle_first = 0;
20

    
21
static AVCodec* avcodec_find_by_fcc(uint32_t fcc)
22
{
23
    // translation table
24
    static const struct fcc_to_avcodecid {
25
        enum CodecID codec;
26
        uint32_t list[4]; // maybe we could map more fcc to same codec
27
    } lc[] = {
28
        { CODEC_ID_H263, { MKTAG('U', '2', '6', '3'), 0 } },
29
        { CODEC_ID_H263I, { MKTAG('I', '2', '6', '3'), 0 } },
30
        { CODEC_ID_MSMPEG4V3, { MKTAG('D', 'I', 'V', '3'), 0 } },
31
        { CODEC_ID_MPEG4, { MKTAG('D', 'I', 'V', 'X'),  MKTAG('D', 'X', '5', '0'), 0 } },
32
        { CODEC_ID_MSMPEG4V2, { MKTAG('M', 'P', '4', '2'), 0 } },
33
        { CODEC_ID_MJPEG, { MKTAG('M', 'J', 'P', 'G'), 0 } },
34
        { CODEC_ID_MPEG1VIDEO, { MKTAG('P', 'I', 'M', '1'), 0 } },
35
        { CODEC_ID_AC3, { 0x2000, 0 } },
36
        { CODEC_ID_MP2, { 0x50, 0x55, 0 } },
37

    
38
        { CODEC_ID_NONE, {0}}
39
    };
40
    const struct fcc_to_avcodecid* c;
41

    
42
    for (c = lc; c->codec != CODEC_ID_NONE; c++)
43
    {
44
        int i = 0;
45
        while (c->list[i] != 0)
46
            if (c->list[i++] == fcc)
47
                return avcodec_find_decoder(c->codec);
48
    }
49

    
50
    return NULL;
51
}
52

    
53
static private_handle_t* create_handle()
54
{
55
    private_handle_t* t = malloc(sizeof(private_handle_t));
56
    if (!t)
57
        return NULL;
58
    memset(t, 0, sizeof(*t));
59

    
60
    // register and fill
61
    if (!handle_first)
62
    {
63
        avcodec_init();
64
        avcodec_register_all();
65
        handle_first = t;
66
    }
67
    else
68
    {
69
        t->prev = handle_first->next;
70
        handle_first->next = t;
71
        t->next = handle_first;
72
    }
73

    
74
    return t;
75
}
76

    
77
static void destroy_handle(private_handle_t* handle)
78
{
79
    if (handle)
80
    {
81
        if (handle->avcodec)
82
        {
83
            avcodec_close(&handle->avcontext);
84
        }
85
        free(handle);
86

    
87
        // count referencies
88
    }
89
}
90

    
91
int avcodec(void* handle, avc_cmd_t cmd, void* pin, void* pout)
92
{
93
    AVCodecContext* ctx = handle;
94
    switch (cmd)
95
    {
96
    case AVC_OPEN_BY_NAME:
97
        {
98
            // pin  char* codec name
99
            private_handle_t* handle = create_handle();
100
            (private_handle_t**)pout = handle;
101
            if (!handle)
102
                return -ENOMEM;
103
            if (!handle->avcodec)
104
            {
105
                destroy_handle(handle);
106
                (private_handle_t**)pout = NULL;
107
                return -1;// better error
108
            }
109
            return 0;
110
        }
111
    case AVC_OPEN_BY_CODEC_ID:
112
        {
113
            // pin  uint32_t codec fourcc
114
            private_handle_t* handle = create_handle();
115
            (private_handle_t**)pout = handle;
116
            if (!handle)
117
                return -ENOMEM;
118

    
119
            if (!handle->avcodec)
120
            {
121
                destroy_handle(handle);
122
                (private_handle_t**)pout = NULL;
123
                return -1;// better error
124
            }
125
            return 0;
126
        }
127
    case AVC_OPEN_BY_FOURCC:
128
        {
129
            // pin  uint32_t codec fourcc
130
            private_handle_t* handle = create_handle();
131
            (private_handle_t**)pout = handle;
132
            if (!handle)
133
                return -ENOMEM;
134
            handle->avcodec = avcodec_find_by_fcc((uint32_t) pin);
135
            if (!handle->avcodec)
136
            {
137
                destroy_handle(handle);
138
                (private_handle_t**)pout = NULL;
139
                return -1;// better error
140
            }
141
            return 0;
142
        }
143
    case AVC_CLOSE:
144
        // uninit part
145
        // eventually close all allocated space if this was last
146
        // instance
147
        destroy_handle(handle);
148
        break;
149

    
150
    case AVC_FLUSH:
151
        break;
152

    
153
    case AVC_DECODE:
154
        break;
155

    
156
    case AVC_ENCODE:
157
        break;
158

    
159
    case AVC_GET_VERSION:
160
        (int*) pout = 500;
161
    default:
162
        return -1;
163

    
164
    }
165
    return 0;
166
}