]> git.sesse.net Git - ffmpeg/blob - libavcodec/avcodec.c
* Ogg/Vorbis patch by Mark Hills
[ffmpeg] / libavcodec / avcodec.c
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 private_handle
12 {
13     AVCodec* avcodec;
14     AVCodecContext avcontext;
15     struct private_handle* next;
16     struct private_handle* prev;
17 } private_handle_t;
18
19 static private_handle_t* handle_first = 0;
20
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 } },
30         { CODEC_ID_MSMPEG4V3, { MKTAG('D', 'I', 'V', '3'), 0 } },
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;
58     memset(t, 0, sizeof(*t));
59
60     // register and fill
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
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 }