Mercurial > mplayer.hg
annotate libmpdemux/demux_lmlm4.c @ 30884:53901d222e8a
Announce SMP support for Win32.
Don't hardcode dwNumberOfProcessors=1 for Win32 anymore; the mutex/event code
is still far from perfect, but now good enough that I can't find any codecs
that breaks with this (tested on a quad with various codecs). This tells
codecs they can use more than one core if they want to (some already did, by
launching multiple threads even when told there was only a single core).
author | sesse |
---|---|
date | Wed, 17 Mar 2010 23:33:26 +0000 |
parents | 0f1b5b68af32 |
children | cd81fce1f010 |
rev | line source |
---|---|
11590 | 1 /* |
29238
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
25707
diff
changeset
|
2 * LMLM4 MPEG4 Compression Card stream & file parser |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
25707
diff
changeset
|
3 * Copyright (C) 2003 Maxim Yevtyushkin <max@linuxmedialabs.com> |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
25707
diff
changeset
|
4 * based on SMJPEG file parser by Alex Beregszaszi |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
25707
diff
changeset
|
5 * |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
25707
diff
changeset
|
6 * This file is part of MPlayer. |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
25707
diff
changeset
|
7 * |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
25707
diff
changeset
|
8 * MPlayer is free software; you can redistribute it and/or modify |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
25707
diff
changeset
|
9 * it under the terms of the GNU General Public License as published by |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
25707
diff
changeset
|
10 * the Free Software Foundation; either version 2 of the License, or |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
25707
diff
changeset
|
11 * (at your option) any later version. |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
25707
diff
changeset
|
12 * |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
25707
diff
changeset
|
13 * MPlayer is distributed in the hope that it will be useful, |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
25707
diff
changeset
|
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
25707
diff
changeset
|
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
25707
diff
changeset
|
16 * GNU General Public License for more details. |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
25707
diff
changeset
|
17 * |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
25707
diff
changeset
|
18 * You should have received a copy of the GNU General Public License along |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
25707
diff
changeset
|
19 * with MPlayer; if not, write to the Free Software Foundation, Inc., |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
25707
diff
changeset
|
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
11590 | 21 */ |
22 | |
23 #include <stdio.h> | |
24 #include <stdlib.h> | |
25 #include <unistd.h> | |
26 #include <string.h> /* strtok */ | |
27 | |
28 #include "config.h" | |
29 #include "mp_msg.h" | |
30 #include "help_mp.h" | |
31 | |
22605
4d81dbdf46b9
Add explicit location for headers from the stream/ directory.
diego
parents:
21421
diff
changeset
|
32 #include "stream/stream.h" |
11590 | 33 #include "demuxer.h" |
34 #include "stheader.h" | |
35 | |
25607
9d0b189ce1b2
Fix illegal identifiers: Names starting with __ or _ and uppercase are reserved
diego
parents:
24357
diff
changeset
|
36 typedef struct FrameInfo |
11590 | 37 { |
38 ssize_t frameSize; | |
39 ssize_t paddingSize; | |
40 int frameType; | |
41 int channelNo; | |
42 } FrameInfo; | |
43 | |
44 #define FRAMETYPE_I 0 | |
45 #define FRAMETYPE_P 1 | |
46 #define FRAMETYPE_B 2 | |
47 #define FRAMETYPE_AUDIO_MPEG1L2 4 | |
48 #define FRAMETYPE_AUDIO_ULAW 5 | |
49 #define FRAMETYPE_AUDIO_ADPCM 6 | |
50 | |
51 #define PACKET_BLOCK_SIZE 0x00000200 | |
52 #define PACKET_BLOCK_LAST 0x000001FF | |
53 #define PACKET_BLOCK_MASK 0xFFFFFE00 | |
54 | |
55 #define MAX_PACKET_SIZE 1048576 // 1 Mb | |
56 | |
57 #define STREAM_START_CODE_SIZE 4 | |
58 | |
59 /* | |
60 // codes in MSB first | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
61 static unsigned int start_code [] = |
11590 | 62 { |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
63 0xB0010000, // VISUAL_OBJECT_SEQUENCE_START_CODE |
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
64 0xB6010000, // VOP_START_CODE |
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
65 0x04C4FDFF, // MPEG1LAYERII_START_CODE |
11590 | 66 0x00000000 // end of start codes list |
67 }; | |
68 */ | |
69 | |
70 static int imeHeaderValid(FrameInfo *frame) | |
71 { | |
72 if ( frame->channelNo > 7 || | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
73 frame->frameSize > MAX_PACKET_SIZE || frame->frameSize <= 0) |
11590 | 74 { |
75 mp_msg(MSGT_DEMUX, MSGL_V, "Invalid packet in LMLM4 stream: ch=%d size=%d\n", frame->channelNo, frame->frameSize); | |
76 return 0; | |
77 } | |
78 switch (frame->frameType) { | |
79 case FRAMETYPE_I: | |
80 case FRAMETYPE_P: | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
81 case FRAMETYPE_B: |
11590 | 82 case FRAMETYPE_AUDIO_MPEG1L2: |
83 case FRAMETYPE_AUDIO_ULAW: | |
84 case FRAMETYPE_AUDIO_ADPCM: | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
85 break; |
11590 | 86 default: |
87 mp_msg(MSGT_DEMUX, MSGL_V, "Invalid packet in LMLM4 stream (wrong packet type %d)\n", frame->frameType); | |
88 return 0; | |
89 } | |
90 return 1; | |
91 } | |
92 | |
93 /* | |
94 int searchMPEG4Stream(demuxer_t* demuxer, IME6400Header *imeHeader) | |
95 { | |
96 void *data; | |
97 ssize_t imeHeaderSize = sizeof(IME6400Header); | |
98 ssize_t dataSize = sizeof(IME6400Header) * 3; | |
99 ssize_t ptr = imeHeaderSize * 2; | |
100 int errNo, startCodeNo; | |
101 off_t pos; | |
102 | |
103 data = malloc(dataSize); | |
104 | |
105 imeHeaderSwap(imeHeader); | |
106 memcpy(data + imeHeaderSize, imeHeader, imeHeaderSize); | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
107 |
11590 | 108 // printHex(data + imeHeaderSize, imeHeaderSize); |
109 | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
110 while ((errNo = stream_read(demuxer->stream, data + imeHeaderSize * 2 , imeHeaderSize)) == imeHeaderSize) |
11590 | 111 { |
112 // printHex(data + imeHeaderSize * 2, imeHeaderSize); | |
113 | |
114 pos = stream_tell(demuxer->stream); | |
115 while (dataSize - ptr >= STREAM_START_CODE_SIZE) { | |
116 startCodeNo = 0; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
117 while (start_code[startCodeNo]) |
11590 | 118 { |
119 if (memcmp(&start_code[startCodeNo], data + ptr, STREAM_START_CODE_SIZE) == 0) // start code match | |
120 { | |
121 memcpy(imeHeader, data + ptr - imeHeaderSize, imeHeaderSize); | |
122 imeHeaderSwap(imeHeader); | |
123 if (imeHeaderValid(imeHeader)) | |
124 { | |
125 stream_seek(demuxer->stream, pos - (dataSize - ptr)); | |
126 free(data); | |
127 return 0; | |
128 } | |
129 } | |
130 startCodeNo++; | |
131 } | |
132 ptr++; | |
133 } | |
134 memcpy(data,data + imeHeaderSize, imeHeaderSize * 2); | |
135 ptr -= imeHeaderSize; | |
136 } | |
137 | |
138 free(data); | |
139 return errNo; | |
140 } | |
141 */ | |
142 | |
143 static int getFrame(demuxer_t *demuxer, FrameInfo *frameInfo) | |
144 { | |
145 unsigned int packetSize; | |
146 | |
147 frameInfo->channelNo = stream_read_word(demuxer->stream); | |
148 frameInfo->frameType = stream_read_word(demuxer->stream); | |
149 packetSize=stream_read_dword(demuxer->stream); | |
150 | |
151 if(stream_eof(demuxer->stream)){ | |
152 frameInfo->frameSize = 0; | |
153 return 0; | |
154 } | |
155 | |
156 frameInfo->frameSize = packetSize - 8; //sizeof(IME6400Header); | |
157 frameInfo->paddingSize = (packetSize & PACKET_BLOCK_LAST) ? PACKET_BLOCK_SIZE - (packetSize & PACKET_BLOCK_LAST) : 0; | |
158 | |
159 mp_msg(MSGT_DEMUX, MSGL_DBG2, "typ: %d chan: %d size: %d pad: %d\n", | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
160 frameInfo->frameType, |
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
161 frameInfo->channelNo, |
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
162 frameInfo->frameSize, |
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
163 frameInfo->paddingSize); |
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
164 |
11590 | 165 if(!imeHeaderValid(frameInfo)){ |
166 // skip this packet | |
167 stream_skip(demuxer->stream,PACKET_BLOCK_SIZE-8); | |
168 frameInfo->frameSize = 0; | |
169 return -1; | |
170 } | |
171 | |
172 return 1; | |
173 } | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
174 |
16175 | 175 static int lmlm4_check_file(demuxer_t* demuxer) |
11590 | 176 { |
177 FrameInfo frameInfo; | |
178 unsigned int first; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
179 |
11590 | 180 mp_msg(MSGT_DEMUX, MSGL_V, "Checking for LMLM4 Stream Format\n"); |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
181 |
11590 | 182 if(getFrame(demuxer, &frameInfo)!=1){ |
183 stream_skip(demuxer->stream,-8); | |
11790 | 184 mp_msg(MSGT_DEMUX, MSGL_V, "LMLM4 Stream Format not found\n"); |
11590 | 185 return 0; |
186 } | |
187 first=stream_read_dword(demuxer->stream); | |
188 stream_skip(demuxer->stream,-12); | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
189 |
11590 | 190 mp_msg(MSGT_DEMUXER,MSGL_V,"LMLM4: first=0x%08X\n",first); |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
191 |
11590 | 192 switch(frameInfo.frameType){ |
193 case FRAMETYPE_AUDIO_MPEG1L2: | |
194 if( (first & 0xffe00000) != 0xffe00000 ){ | |
195 mp_msg(MSGT_DEMUXER,MSGL_V,"LMLM4: not mpeg audio\n"); | |
196 return 0; | |
197 } | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
198 if((4-((first>>17)&3))!=2){ |
11590 | 199 mp_msg(MSGT_DEMUXER,MSGL_V,"LMLM4: not layer-2\n"); |
200 return 0; | |
201 } | |
202 if(((first>>10)&0x3)==3){ | |
203 mp_msg(MSGT_DEMUXER,MSGL_V,"LMLM4: invalid audio sampelrate\n"); | |
204 return 0; | |
205 } | |
206 mp_msg(MSGT_DEMUXER,MSGL_V,"LMLM4: first packet is audio, header checks OK!\n"); | |
207 break; | |
208 // TODO: add checks for video header too, for case of disabled audio | |
209 } | |
210 | |
211 | |
212 // stream_reset(demuxer->stream); | |
213 mp_msg(MSGT_DEMUX, MSGL_V, "LMLM4 Stream Format found\n"); | |
214 | |
16175 | 215 return DEMUXER_TYPE_LMLM4; |
11590 | 216 } |
217 | |
218 static int video = 0; | |
219 static int frames= 0; | |
220 | |
221 // return value: | |
222 // 0 = EOF or no stream found | |
223 // 1 = successfully read a packet | |
16175 | 224 static int demux_lmlm4_fill_buffer(demuxer_t *demux, demux_stream_t *ds) |
11590 | 225 { |
226 FrameInfo frameInfo; | |
227 double pts; | |
228 int id=1; | |
229 int ret; | |
230 | |
24357 | 231 //hdr: |
11590 | 232 demux->filepos = stream_tell(demux->stream); |
17366 | 233 mp_msg(MSGT_DEMUX, MSGL_DBG2, "fpos = %"PRId64"\n", (int64_t)demux->filepos); |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
234 |
11590 | 235 ret=getFrame(demux, &frameInfo); |
236 if(ret<=0) return ret; // EOF/error | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
237 |
11590 | 238 pts=demux->video->sh ? frames*((sh_video_t*)(demux->video->sh))->frametime : 0; |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
239 |
11590 | 240 switch(frameInfo.frameType){ |
241 case FRAMETYPE_AUDIO_MPEG1L2: | |
242 mp_dbg(MSGT_DEMUX, MSGL_DBG2, "Audio Packet\n"); | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
243 if (!video) |
11590 | 244 { |
245 stream_skip(demux->stream, frameInfo.frameSize + frameInfo.paddingSize); | |
246 mp_msg(MSGT_DEMUX, MSGL_V, "Skip Audio Packet\n"); | |
247 return -1; //goto hdr; | |
248 } | |
249 if(demux->audio->id==-1){ | |
250 if(!demux->a_streams[id]) new_sh_audio(demux,id); | |
251 demux->audio->id=id; | |
252 demux->audio->sh=demux->a_streams[id]; | |
253 ((sh_audio_t*)(demux->audio->sh))->format=0x50; // mpeg audio layer 1/2 | |
254 } | |
255 if(demux->audio->id==id) | |
256 ds_read_packet(demux->audio, demux->stream, frameInfo.frameSize, | |
257 pts, demux->filepos, 0); | |
258 else | |
259 stream_skip(demux->stream,frameInfo.frameSize); | |
260 break; | |
261 case FRAMETYPE_I: | |
262 if (!video) { | |
263 video = 1; | |
264 mp_dbg(MSGT_DEMUX, MSGL_DBG2, "First Video Packet\n"); | |
265 } | |
266 case FRAMETYPE_P: | |
267 frames=(frames+1)&(1024*1024-1); // wrap around at 4 hrs to avoid inaccurate float calculations | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
268 if (!video) |
11590 | 269 { |
270 stream_skip(demux->stream, frameInfo.frameSize + frameInfo.paddingSize); | |
271 mp_msg(MSGT_DEMUX, MSGL_V, "Skip Video P Packet\n"); | |
272 return -1; //goto hdr; | |
273 } | |
274 mp_dbg(MSGT_DEMUX, MSGL_DBG2, "Video Packet\n"); | |
275 if(demux->video->id==-1){ | |
276 if(!demux->v_streams[id]) new_sh_video(demux,id); | |
277 demux->video->id=id; | |
278 demux->video->sh=demux->v_streams[id]; | |
279 ((sh_video_t*)(demux->video->sh))->format=0x10000004; // mpeg4-ES | |
280 } | |
281 if(demux->video->id==id) | |
282 ds_read_packet(demux->video, demux->stream, frameInfo.frameSize, | |
283 pts, demux->filepos, 0); | |
284 break; | |
285 default: | |
286 stream_skip(demux->stream,frameInfo.frameSize); | |
287 } | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
288 |
11590 | 289 stream_skip(demux->stream, frameInfo.paddingSize); |
290 | |
291 return 1; | |
292 } | |
293 | |
16175 | 294 static demuxer_t* demux_open_lmlm4(demuxer_t* demuxer){ |
295 sh_audio_t *sh_audio=NULL; | |
296 sh_video_t *sh_video=NULL; | |
11590 | 297 |
298 #if 0 | |
299 sh_video_t* sh_video; | |
300 sh_audio_t* sh_audio; | |
301 unsigned int htype = 0, hleng; | |
302 int i = 0; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
303 |
11590 | 304 sh_video = new_sh_video(demuxer, 0); |
305 demuxer->video->sh = sh_video; | |
306 sh_video->ds = demuxer->video; | |
307 sh_video->disp_w = 640; | |
308 sh_video->disp_h = 480; | |
309 sh_video->format = mmioFOURCC('D','I','V','X'); | |
310 | |
311 sh_video->bih = malloc(sizeof(BITMAPINFOHEADER)); | |
312 memset(sh_video->bih, 0, sizeof(BITMAPINFOHEADER)); | |
313 | |
314 /* these are false values */ | |
315 sh_video->bih->biSize = 40; | |
316 sh_video->bih->biWidth = sh_video->disp_w; | |
317 sh_video->bih->biHeight = sh_video->disp_h; | |
318 sh_video->bih->biPlanes = 3; | |
319 sh_video->bih->biBitCount = 16; | |
320 sh_video->bih->biCompression = sh_video->format; | |
321 sh_video->bih->biSizeImage = sh_video->disp_w*sh_video->disp_h; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
322 |
11590 | 323 sh_audio = new_sh_audio(demuxer, 0); |
324 demuxer->audio->sh = sh_audio; | |
325 sh_audio->ds = demuxer->audio; | |
326 | |
327 sh_audio->wf = malloc(sizeof(WAVEFORMATEX)); | |
328 memset(sh_audio->wf, 0, sizeof(WAVEFORMATEX)); | |
329 | |
330 sh_audio->samplerate = 48000; | |
331 sh_audio->wf->wBitsPerSample = 16; | |
332 sh_audio->channels = 2; | |
333 sh_audio->format = 0x50; | |
334 sh_audio->wf->wFormatTag = sh_audio->format; | |
335 sh_audio->wf->nChannels = sh_audio->channels; | |
336 sh_audio->wf->nSamplesPerSec = sh_audio->samplerate; | |
337 sh_audio->wf->nAvgBytesPerSec = sh_audio->wf->nChannels* | |
338 sh_audio->wf->wBitsPerSample*sh_audio->wf->nSamplesPerSec/8; | |
339 sh_audio->wf->nBlockAlign = sh_audio->channels *2; | |
340 sh_audio->wf->cbSize = 0; | |
341 | |
342 #endif | |
343 | |
344 demuxer->seekable = 0; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
345 |
16175 | 346 if(!ds_fill_buffer(demuxer->video)){ |
347 mp_msg(MSGT_DEMUXER,MSGL_INFO,"LMLM4: " MSGTR_MissingVideoStream); | |
348 demuxer->video->sh=NULL; | |
349 } else { | |
350 sh_video=demuxer->video->sh;sh_video->ds=demuxer->video; | |
351 } | |
352 if(demuxer->audio->id!=-2) { | |
353 if(!ds_fill_buffer(demuxer->audio)){ | |
354 mp_msg(MSGT_DEMUXER,MSGL_INFO,"LMLM4: " MSGTR_MissingAudioStream); | |
355 demuxer->audio->sh=NULL; | |
356 } else { | |
357 sh_audio=demuxer->audio->sh;sh_audio->ds=demuxer->audio; | |
358 } | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
359 } |
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
360 |
16175 | 361 return demuxer; |
11590 | 362 } |
363 | |
16175 | 364 static void demux_close_lmlm4(demuxer_t *demuxer) |
11590 | 365 { |
366 // printf("Close LMLM4 Stream\n"); | |
367 return; | |
368 } | |
16175 | 369 |
370 | |
25707
d4fe6e23283e
Make all demuxer_desc_t const, thus moving them to .rodata
reimar
parents:
25607
diff
changeset
|
371 const demuxer_desc_t demuxer_desc_lmlm4 = { |
16175 | 372 "LMLM4 MPEG4 Compression Card stream demuxer", |
373 "lmlm4", | |
374 "RAW LMLM4", | |
375 "Maxim Yevtyushkin", | |
376 "", | |
377 DEMUXER_TYPE_LMLM4, | |
378 0, // unsafe autodetect | |
379 lmlm4_check_file, | |
380 demux_lmlm4_fill_buffer, | |
381 demux_open_lmlm4, | |
382 demux_close_lmlm4, | |
383 NULL, | |
384 NULL | |
385 }; |