* still unfinished code for Options
[libav.git] / libavcodec / avcodec.c
CommitLineData
e8f14793
ZK
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
fb602cd1 11typedef struct private_handle
e8f14793
ZK
12{
13 AVCodec* avcodec;
14 AVCodecContext avcontext;
fb602cd1
ZK
15 struct private_handle* next;
16 struct private_handle* prev;
e8f14793
ZK
17} private_handle_t;
18
fb602cd1
ZK
19static private_handle_t* handle_first = 0;
20
e8f14793
ZK
21static 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 } },
fb602cd1 30 { CODEC_ID_MSMPEG4V3, { MKTAG('D', 'I', 'V', '3'), 0 } },
e8f14793
ZK
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
53static private_handle_t* create_handle()
54{
55 private_handle_t* t = malloc(sizeof(private_handle_t));
56 if (!t)
57 return NULL;
fb602cd1 58 memset(t, 0, sizeof(*t));
e8f14793
ZK
59
60 // register and fill
fb602cd1
ZK
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
e8f14793
ZK
74 return t;
75}
76
77static 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
91int 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}