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
|
|
11 typedef struct
|
|
12 {
|
|
13 AVCodec* avcodec;
|
|
14 AVCodecContext avcontext;
|
|
15 } private_handle_t;
|
|
16
|
|
17 static AVCodec* avcodec_find_by_fcc(uint32_t fcc)
|
|
18 {
|
|
19 // translation table
|
|
20 static const struct fcc_to_avcodecid {
|
|
21 enum CodecID codec;
|
|
22 uint32_t list[4]; // maybe we could map more fcc to same codec
|
|
23 } lc[] = {
|
|
24 { CODEC_ID_H263, { MKTAG('U', '2', '6', '3'), 0 } },
|
|
25 { CODEC_ID_H263I, { MKTAG('I', '2', '6', '3'), 0 } },
|
|
26 { CODEC_ID_MSMPEG4, { MKTAG('D', 'I', 'V', '3'), 0 } },
|
|
27 { CODEC_ID_MPEG4, { MKTAG('D', 'I', 'V', 'X'), MKTAG('D', 'X', '5', '0'), 0 } },
|
|
28 { CODEC_ID_MSMPEG4V2, { MKTAG('M', 'P', '4', '2'), 0 } },
|
|
29 { CODEC_ID_MJPEG, { MKTAG('M', 'J', 'P', 'G'), 0 } },
|
|
30 { CODEC_ID_MPEG1VIDEO, { MKTAG('P', 'I', 'M', '1'), 0 } },
|
|
31 { CODEC_ID_AC3, { 0x2000, 0 } },
|
|
32 { CODEC_ID_MP2, { 0x50, 0x55, 0 } },
|
|
33
|
|
34 { CODEC_ID_NONE, {0}}
|
|
35 };
|
|
36 const struct fcc_to_avcodecid* c;
|
|
37
|
|
38 for (c = lc; c->codec != CODEC_ID_NONE; c++)
|
|
39 {
|
|
40 int i = 0;
|
|
41 while (c->list[i] != 0)
|
|
42 if (c->list[i++] == fcc)
|
|
43 return avcodec_find_decoder(c->codec);
|
|
44 }
|
|
45
|
|
46 return NULL;
|
|
47 }
|
|
48
|
|
49 static private_handle_t* create_handle()
|
|
50 {
|
|
51 private_handle_t* t = malloc(sizeof(private_handle_t));
|
|
52 if (!t)
|
|
53 return NULL;
|
|
54
|
|
55 // register and fill
|
|
56 avcodec_init();
|
|
57 avcodec_register_all();
|
|
58 return t;
|
|
59 }
|
|
60
|
|
61 static void destroy_handle(private_handle_t* handle)
|
|
62 {
|
|
63 if (handle)
|
|
64 {
|
|
65 if (handle->avcodec)
|
|
66 {
|
|
67 avcodec_close(&handle->avcontext);
|
|
68 }
|
|
69 free(handle);
|
|
70
|
|
71 // count referencies
|
|
72 }
|
|
73 }
|
|
74
|
|
75 int avcodec(void* handle, avc_cmd_t cmd, void* pin, void* pout)
|
|
76 {
|
|
77 AVCodecContext* ctx = handle;
|
|
78 switch (cmd)
|
|
79 {
|
|
80 case AVC_OPEN_BY_NAME:
|
|
81 {
|
|
82 // pin char* codec name
|
|
83 private_handle_t* handle = create_handle();
|
|
84 (private_handle_t**)pout = handle;
|
|
85 if (!handle)
|
|
86 return -ENOMEM;
|
|
87 if (!handle->avcodec)
|
|
88 {
|
|
89 destroy_handle(handle);
|
|
90 (private_handle_t**)pout = NULL;
|
|
91 return -1;// better error
|
|
92 }
|
|
93 return 0;
|
|
94 }
|
|
95 case AVC_OPEN_BY_CODEC_ID:
|
|
96 {
|
|
97 // pin uint32_t codec fourcc
|
|
98 private_handle_t* handle = create_handle();
|
|
99 (private_handle_t**)pout = handle;
|
|
100 if (!handle)
|
|
101 return -ENOMEM;
|
|
102
|
|
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_FOURCC:
|
|
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 handle->avcodec = avcodec_find_by_fcc((uint32_t) pin);
|
|
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_CLOSE:
|
|
128 // uninit part
|
|
129 // eventually close all allocated space if this was last
|
|
130 // instance
|
|
131 destroy_handle(handle);
|
|
132 break;
|
|
133
|
|
134 case AVC_FLUSH:
|
|
135 break;
|
|
136
|
|
137 case AVC_DECODE:
|
|
138 break;
|
|
139
|
|
140 case AVC_ENCODE:
|
|
141 break;
|
|
142
|
|
143 case AVC_GET_VERSION:
|
|
144 (int*) pout = 500;
|
|
145 default:
|
|
146 return -1;
|
|
147
|
|
148 }
|
|
149 return 0;
|
|
150 }
|