1106
|
1 /**
|
|
2 * @file avcodec.c
|
|
3 * avcodec.
|
|
4 */
|
|
5
|
382
|
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
|
852
|
16 typedef struct private_handle
|
382
|
17 {
|
|
18 AVCodec* avcodec;
|
|
19 AVCodecContext avcontext;
|
852
|
20 struct private_handle* next;
|
|
21 struct private_handle* prev;
|
382
|
22 } private_handle_t;
|
|
23
|
852
|
24 static private_handle_t* handle_first = 0;
|
|
25
|
382
|
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 } },
|
852
|
35 { CODEC_ID_MSMPEG4V3, { MKTAG('D', 'I', 'V', '3'), 0 } },
|
382
|
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
|
1059
|
58 static private_handle_t* create_handle(void)
|
382
|
59 {
|
1059
|
60 private_handle_t* t = av_malloc(sizeof(private_handle_t));
|
382
|
61 if (!t)
|
|
62 return NULL;
|
852
|
63 memset(t, 0, sizeof(*t));
|
382
|
64
|
|
65 // register and fill
|
852
|
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
|
382
|
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 }
|
1059
|
90 av_free(handle);
|
382
|
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
|
1059
|
104 private_handle_t* h = create_handle();
|
|
105 (private_handle_t**)pout = h;
|
|
106 if (!h)
|
382
|
107 return -ENOMEM;
|
1059
|
108 if (!h->avcodec)
|
382
|
109 {
|
1059
|
110 destroy_handle(h);
|
382
|
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
|
1059
|
119 private_handle_t* h = create_handle();
|
|
120 (private_handle_t**)pout = h;
|
|
121 if (!h)
|
382
|
122 return -ENOMEM;
|
|
123
|
1059
|
124 if (!h->avcodec)
|
382
|
125 {
|
1059
|
126 destroy_handle(h);
|
382
|
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
|
1059
|
135 private_handle_t* h = create_handle();
|
|
136 (private_handle_t**)pout = h;
|
|
137 if (!h)
|
382
|
138 return -ENOMEM;
|
1059
|
139 h->avcodec = avcodec_find_by_fcc((uint32_t) pin);
|
|
140 if (!h->avcodec)
|
382
|
141 {
|
1059
|
142 destroy_handle(h);
|
382
|
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 }
|