]> git.sesse.net Git - ffmpeg/blob - libavcodec/avcodec.c
per file doxy
[ffmpeg] / libavcodec / avcodec.c
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 }