Statistics
| Branch: | Revision:

ffmpeg / libavcodec / avcodec.c @ 983e3246

History | View | Annotate | Download (3.55 KB)

1
/**
2
 * @file avcodec.c
3
 * avcodec.
4
 */
5

    
6
#include "errno.h"
7
#include "avcodec.h"
8

    
9
#ifndef MKTAG
10
#define MKTAG(a,b,c,d) (a | (b << 8) | (c << 16) | (d << 24))
11
#endif
12

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

    
24
static private_handle_t* handle_first = 0;
25

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

    
43
        { CODEC_ID_NONE, {0}}
44
    };
45
    const struct fcc_to_avcodecid* c;
46

    
47
    for (c = lc; c->codec != CODEC_ID_NONE; c++)
48
    {
49
        int i = 0;
50
        while (c->list[i] != 0)
51
            if (c->list[i++] == fcc)
52
                return avcodec_find_decoder(c->codec);
53
    }
54

    
55
    return NULL;
56
}
57

    
58
static private_handle_t* create_handle(void)
59
{
60
    private_handle_t* t = av_malloc(sizeof(private_handle_t));
61
    if (!t)
62
        return NULL;
63
    memset(t, 0, sizeof(*t));
64

    
65
    // register and fill
66
    if (!handle_first)
67
    {
68
        avcodec_init();
69
        avcodec_register_all();
70
        handle_first = t;
71
    }
72
    else
73
    {
74
        t->prev = handle_first->next;
75
        handle_first->next = t;
76
        t->next = handle_first;
77
    }
78

    
79
    return t;
80
}
81

    
82
static void destroy_handle(private_handle_t* handle)
83
{
84
    if (handle)
85
    {
86
        if (handle->avcodec)
87
        {
88
            avcodec_close(&handle->avcontext);
89
        }
90
        av_free(handle);
91

    
92
        // count referencies
93
    }
94
}
95

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

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

    
155
    case AVC_FLUSH:
156
        break;
157

    
158
    case AVC_DECODE:
159
        break;
160

    
161
    case AVC_ENCODE:
162
        break;
163

    
164
    case AVC_GET_VERSION:
165
        (int*) pout = 500;
166
    default:
167
        return -1;
168

    
169
    }
170
    return 0;
171
}