Statistics
| Branch: | Revision:

ffmpeg / libavcodec / avcodec.c @ 68ca24e6

History | View | Annotate | Download (3.6 KB)

1 983e3246 Michael Niedermayer
/**
2
 * @file avcodec.c
3
 * avcodec.
4
 */
5
6 e8f14793 Zdenek Kabelac
#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 fb602cd1 Zdenek Kabelac
typedef struct private_handle
17 e8f14793 Zdenek Kabelac
{
18
    AVCodec* avcodec;
19
    AVCodecContext avcontext;
20 fb602cd1 Zdenek Kabelac
    struct private_handle* next;
21
    struct private_handle* prev;
22 e8f14793 Zdenek Kabelac
} private_handle_t;
23
24 fb602cd1 Zdenek Kabelac
static private_handle_t* handle_first = 0;
25
26 e8f14793 Zdenek Kabelac
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 fb602cd1 Zdenek Kabelac
        { CODEC_ID_MSMPEG4V3, { MKTAG('D', 'I', 'V', '3'), 0 } },
36 e8f14793 Zdenek Kabelac
        { 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 d4f5d74a Garrick Meeker
        { CODEC_ID_FLV1, { MKTAG('F', 'L', 'V', '1'), 0 } },
43 e8f14793 Zdenek Kabelac
44
        { CODEC_ID_NONE, {0}}
45
    };
46
    const struct fcc_to_avcodecid* c;
47
48
    for (c = lc; c->codec != CODEC_ID_NONE; c++)
49
    {
50
        int i = 0;
51
        while (c->list[i] != 0)
52
            if (c->list[i++] == fcc)
53
                return avcodec_find_decoder(c->codec);
54
    }
55
56
    return NULL;
57
}
58
59 fe1b62fb Zdenek Kabelac
static private_handle_t* create_handle(void)
60 e8f14793 Zdenek Kabelac
{
61 fe1b62fb Zdenek Kabelac
    private_handle_t* t = av_malloc(sizeof(private_handle_t));
62 e8f14793 Zdenek Kabelac
    if (!t)
63
        return NULL;
64 fb602cd1 Zdenek Kabelac
    memset(t, 0, sizeof(*t));
65 e8f14793 Zdenek Kabelac
66
    // register and fill
67 fb602cd1 Zdenek Kabelac
    if (!handle_first)
68
    {
69
        avcodec_init();
70
        avcodec_register_all();
71
        handle_first = t;
72
    }
73
    else
74
    {
75
        t->prev = handle_first->next;
76
        handle_first->next = t;
77
        t->next = handle_first;
78
    }
79
80 e8f14793 Zdenek Kabelac
    return t;
81
}
82
83
static void destroy_handle(private_handle_t* handle)
84
{
85
    if (handle)
86
    {
87
        if (handle->avcodec)
88
        {
89
            avcodec_close(&handle->avcontext);
90
        }
91 fe1b62fb Zdenek Kabelac
        av_free(handle);
92 e8f14793 Zdenek Kabelac
93
        // count referencies
94
    }
95
}
96
97
int avcodec(void* handle, avc_cmd_t cmd, void* pin, void* pout)
98
{
99
    AVCodecContext* ctx = handle;
100
    switch (cmd)
101
    {
102
    case AVC_OPEN_BY_NAME:
103
        {
104
            // pin  char* codec name
105 fe1b62fb Zdenek Kabelac
            private_handle_t* h = create_handle();
106
            (private_handle_t**)pout = h;
107
            if (!h)
108 e8f14793 Zdenek Kabelac
                return -ENOMEM;
109 fe1b62fb Zdenek Kabelac
            if (!h->avcodec)
110 e8f14793 Zdenek Kabelac
            {
111 fe1b62fb Zdenek Kabelac
                destroy_handle(h);
112 e8f14793 Zdenek Kabelac
                (private_handle_t**)pout = NULL;
113
                return -1;// better error
114
            }
115
            return 0;
116
        }
117
    case AVC_OPEN_BY_CODEC_ID:
118
        {
119
            // pin  uint32_t codec fourcc
120 fe1b62fb Zdenek Kabelac
            private_handle_t* h = create_handle();
121
            (private_handle_t**)pout = h;
122
            if (!h)
123 e8f14793 Zdenek Kabelac
                return -ENOMEM;
124
125 fe1b62fb Zdenek Kabelac
            if (!h->avcodec)
126 e8f14793 Zdenek Kabelac
            {
127 fe1b62fb Zdenek Kabelac
                destroy_handle(h);
128 e8f14793 Zdenek Kabelac
                (private_handle_t**)pout = NULL;
129
                return -1;// better error
130
            }
131
            return 0;
132
        }
133
    case AVC_OPEN_BY_FOURCC:
134
        {
135
            // pin  uint32_t codec fourcc
136 fe1b62fb Zdenek Kabelac
            private_handle_t* h = create_handle();
137
            (private_handle_t**)pout = h;
138
            if (!h)
139 e8f14793 Zdenek Kabelac
                return -ENOMEM;
140 fe1b62fb Zdenek Kabelac
            h->avcodec = avcodec_find_by_fcc((uint32_t) pin);
141
            if (!h->avcodec)
142 e8f14793 Zdenek Kabelac
            {
143 fe1b62fb Zdenek Kabelac
                destroy_handle(h);
144 e8f14793 Zdenek Kabelac
                (private_handle_t**)pout = NULL;
145
                return -1;// better error
146
            }
147
            return 0;
148
        }
149
    case AVC_CLOSE:
150
        // uninit part
151
        // eventually close all allocated space if this was last
152
        // instance
153
        destroy_handle(handle);
154
        break;
155
156
    case AVC_FLUSH:
157
        break;
158
159
    case AVC_DECODE:
160
        break;
161
162
    case AVC_ENCODE:
163
        break;
164
165
    case AVC_GET_VERSION:
166
        (int*) pout = 500;
167
    default:
168
        return -1;
169
170
    }
171
    return 0;
172
}