ffmpeg / libavcodec / avcodec.c @ 983e3246
History | View | Annotate | Download (3.55 KB)
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 |
|
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 |
|
58 |
static private_handle_t* create_handle(void) |
59 |
{ |
60 |
private_handle_t* t = av_malloc(sizeof(private_handle_t));
|
61 |
if (!t)
|
62 |
return NULL; |
63 |
memset(t, 0, sizeof(*t)); |
64 |
|
65 |
// register and fill
|
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 |
|
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 |
} |
90 |
av_free(handle); |
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
|
104 |
private_handle_t* h = create_handle(); |
105 |
(private_handle_t**)pout = h; |
106 |
if (!h)
|
107 |
return -ENOMEM;
|
108 |
if (!h->avcodec)
|
109 |
{ |
110 |
destroy_handle(h); |
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
|
119 |
private_handle_t* h = create_handle(); |
120 |
(private_handle_t**)pout = h; |
121 |
if (!h)
|
122 |
return -ENOMEM;
|
123 |
|
124 |
if (!h->avcodec)
|
125 |
{ |
126 |
destroy_handle(h); |
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
|
135 |
private_handle_t* h = create_handle(); |
136 |
(private_handle_t**)pout = h; |
137 |
if (!h)
|
138 |
return -ENOMEM;
|
139 |
h->avcodec = avcodec_find_by_fcc((uint32_t) pin); |
140 |
if (!h->avcodec)
|
141 |
{ |
142 |
destroy_handle(h); |
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 |
} |