382
|
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
|
852
|
11 typedef struct private_handle
|
382
|
12 {
|
|
13 AVCodec* avcodec;
|
|
14 AVCodecContext avcontext;
|
852
|
15 struct private_handle* next;
|
|
16 struct private_handle* prev;
|
382
|
17 } private_handle_t;
|
|
18
|
852
|
19 static private_handle_t* handle_first = 0;
|
|
20
|
382
|
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 } },
|
852
|
30 { CODEC_ID_MSMPEG4V3, { MKTAG('D', 'I', 'V', '3'), 0 } },
|
382
|
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;
|
852
|
58 memset(t, 0, sizeof(*t));
|
382
|
59
|
|
60 // register and fill
|
852
|
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
|
382
|
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 }
|