libdts support by (Benjamin Zores <ben at geexbox dot org>)
[libav.git] / libavcodec / avcodec.c
CommitLineData
983e3246
MN
1/**
2 * @file avcodec.c
3 * avcodec.
4 */
5
e8f14793
ZK
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
fb602cd1 16typedef struct private_handle
e8f14793
ZK
17{
18 AVCodec* avcodec;
19 AVCodecContext avcontext;
fb602cd1
ZK
20 struct private_handle* next;
21 struct private_handle* prev;
e8f14793
ZK
22} private_handle_t;
23
fb602cd1
ZK
24static private_handle_t* handle_first = 0;
25
e8f14793
ZK
26static 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 } },
fb602cd1 35 { CODEC_ID_MSMPEG4V3, { MKTAG('D', 'I', 'V', '3'), 0 } },
e8f14793
ZK
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 } },
23c99253 41 { CODEC_ID_DTS, { 0x10, 0 } },
e8f14793 42 { CODEC_ID_MP2, { 0x50, 0x55, 0 } },
d4f5d74a 43 { CODEC_ID_FLV1, { MKTAG('F', 'L', 'V', '1'), 0 } },
e8f14793
ZK
44
45 { CODEC_ID_NONE, {0}}
46 };
47 const struct fcc_to_avcodecid* c;
48
49 for (c = lc; c->codec != CODEC_ID_NONE; c++)
50 {
51 int i = 0;
52 while (c->list[i] != 0)
53 if (c->list[i++] == fcc)
54 return avcodec_find_decoder(c->codec);
55 }
56
57 return NULL;
58}
59
fe1b62fb 60static private_handle_t* create_handle(void)
e8f14793 61{
fe1b62fb 62 private_handle_t* t = av_malloc(sizeof(private_handle_t));
e8f14793
ZK
63 if (!t)
64 return NULL;
fb602cd1 65 memset(t, 0, sizeof(*t));
e8f14793
ZK
66
67 // register and fill
fb602cd1
ZK
68 if (!handle_first)
69 {
70 avcodec_init();
71 avcodec_register_all();
72 handle_first = t;
73 }
74 else
75 {
76 t->prev = handle_first->next;
77 handle_first->next = t;
78 t->next = handle_first;
79 }
80
e8f14793
ZK
81 return t;
82}
83
84static void destroy_handle(private_handle_t* handle)
85{
86 if (handle)
87 {
88 if (handle->avcodec)
89 {
90 avcodec_close(&handle->avcontext);
91 }
fe1b62fb 92 av_free(handle);
e8f14793
ZK
93
94 // count referencies
95 }
96}
97
98int avcodec(void* handle, avc_cmd_t cmd, void* pin, void* pout)
99{
100 AVCodecContext* ctx = handle;
101 switch (cmd)
102 {
103 case AVC_OPEN_BY_NAME:
104 {
105 // pin char* codec name
fe1b62fb
ZK
106 private_handle_t* h = create_handle();
107 (private_handle_t**)pout = h;
108 if (!h)
e8f14793 109 return -ENOMEM;
fe1b62fb 110 if (!h->avcodec)
e8f14793 111 {
fe1b62fb 112 destroy_handle(h);
e8f14793
ZK
113 (private_handle_t**)pout = NULL;
114 return -1;// better error
115 }
116 return 0;
117 }
118 case AVC_OPEN_BY_CODEC_ID:
119 {
120 // pin uint32_t codec fourcc
fe1b62fb
ZK
121 private_handle_t* h = create_handle();
122 (private_handle_t**)pout = h;
123 if (!h)
e8f14793
ZK
124 return -ENOMEM;
125
fe1b62fb 126 if (!h->avcodec)
e8f14793 127 {
fe1b62fb 128 destroy_handle(h);
e8f14793
ZK
129 (private_handle_t**)pout = NULL;
130 return -1;// better error
131 }
132 return 0;
133 }
134 case AVC_OPEN_BY_FOURCC:
135 {
136 // pin uint32_t codec fourcc
fe1b62fb
ZK
137 private_handle_t* h = create_handle();
138 (private_handle_t**)pout = h;
139 if (!h)
e8f14793 140 return -ENOMEM;
fe1b62fb
ZK
141 h->avcodec = avcodec_find_by_fcc((uint32_t) pin);
142 if (!h->avcodec)
e8f14793 143 {
fe1b62fb 144 destroy_handle(h);
e8f14793
ZK
145 (private_handle_t**)pout = NULL;
146 return -1;// better error
147 }
148 return 0;
149 }
150 case AVC_CLOSE:
151 // uninit part
152 // eventually close all allocated space if this was last
153 // instance
154 destroy_handle(handle);
155 break;
156
157 case AVC_FLUSH:
158 break;
159
160 case AVC_DECODE:
161 break;
162
163 case AVC_ENCODE:
164 break;
165
166 case AVC_GET_VERSION:
167 (int*) pout = 500;
168 default:
169 return -1;
170
171 }
172 return 0;
173}