4f687568b7dd7e38b57cada6009458fbfb98fe9a
[libav.git] / libavcodec / avcodec.c
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 { CODEC_ID_FLV1, { MKTAG('F', 'L', 'V', '1'), 0 } },
43
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 static private_handle_t* create_handle(void)
60 {
61 private_handle_t* t = av_malloc(sizeof(private_handle_t));
62 if (!t)
63 return NULL;
64 memset(t, 0, sizeof(*t));
65
66 // register and fill
67 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 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 av_free(handle);
92
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 private_handle_t* h = create_handle();
106 (private_handle_t**)pout = h;
107 if (!h)
108 return -ENOMEM;
109 if (!h->avcodec)
110 {
111 destroy_handle(h);
112 (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 private_handle_t* h = create_handle();
121 (private_handle_t**)pout = h;
122 if (!h)
123 return -ENOMEM;
124
125 if (!h->avcodec)
126 {
127 destroy_handle(h);
128 (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 private_handle_t* h = create_handle();
137 (private_handle_t**)pout = h;
138 if (!h)
139 return -ENOMEM;
140 h->avcodec = avcodec_find_by_fcc((uint32_t) pin);
141 if (!h->avcodec)
142 {
143 destroy_handle(h);
144 (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 }