3 * copyright (c) 2002 Alex Beregszaszi
4 * based on text by Arpi (SMJPEG-format.txt) and later on
5 * http://www.lokigames.com/development/download/smjpeg/SMJPEG.txt
7 * This file is part of MPlayer.
9 * MPlayer is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * MPlayer is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License along
20 * with MPlayer; if not, write to the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
27 #include <string.h> /* strtok */
32 #include "stream/stream.h"
36 static int smjpeg_check_file(demuxer_t
* demuxer
){
37 int orig_pos
= stream_tell(demuxer
->stream
);
41 mp_msg(MSGT_DEMUX
, MSGL_V
, "Checking for SMJPEG\n");
43 if (stream_read_word(demuxer
->stream
) == 0xA)
45 stream_read(demuxer
->stream
, buf
, 6);
48 if (strncmp("SMJPEG", buf
, 6)) {
49 mp_msg(MSGT_DEMUX
, MSGL_DBG2
, "Failed: SMJPEG\n");
56 version
= stream_read_dword(demuxer
->stream
);
59 mp_msg(MSGT_DEMUX
, MSGL_ERR
, "Unknown version (%d) of SMJPEG. Please report!\n",
64 stream_seek(demuxer
->stream
, orig_pos
);
66 return DEMUXER_TYPE_SMJPEG
;
71 // 0 = EOF or no stream found
72 // 1 = successfully read a packet
73 static int demux_smjpeg_fill_buffer(demuxer_t
*demux
, demux_stream_t
*ds
)
75 int dtype
, dsize
, dpts
;
77 demux
->filepos
= stream_tell(demux
->stream
);
79 dtype
= stream_read_dword_le(demux
->stream
);
80 dpts
= stream_read_dword(demux
->stream
);
81 dsize
= stream_read_dword(demux
->stream
);
85 case mmioFOURCC('s','n','d','D'):
86 /* fixme, but no decoder implemented yet */
87 ds_read_packet(demux
->audio
, demux
->stream
, dsize
,
88 (float)dpts
/1000.0, demux
->filepos
, 0);
90 case mmioFOURCC('v','i','d','D'):
91 ds_read_packet(demux
->video
, demux
->stream
, dsize
,
92 (float)dpts
/1000.0, demux
->filepos
, 0);
94 case mmioFOURCC('D','O','N','E'):
103 static demuxer_t
* demux_open_smjpeg(demuxer_t
* demuxer
){
104 sh_video_t
* sh_video
;
105 sh_audio_t
* sh_audio
;
106 unsigned int htype
= 0, hleng
;
110 stream_skip(demuxer
->stream
, 8); /* \x00\x0aSMJPEG */
111 stream_skip(demuxer
->stream
, 4);
113 mp_msg(MSGT_DEMUX
, MSGL_INFO
, "This clip is %d seconds\n",
114 stream_read_dword(demuxer
->stream
));
120 htype
= stream_read_dword_le(demuxer
->stream
);
121 if (htype
== mmioFOURCC('H','E','N','D'))
123 hleng
= (stream_read_word(demuxer
->stream
)<<16)|stream_read_word(demuxer
->stream
);
126 case mmioFOURCC('_','V','I','D'):
127 sh_video
= new_sh_video(demuxer
, 0);
128 demuxer
->video
->sh
= sh_video
;
129 sh_video
->ds
= demuxer
->video
;
131 sh_video
->bih
= calloc(1, sizeof(*sh_video
->bih
));
133 stream_skip(demuxer
->stream
, 4); /* number of frames */
134 // sh_video->fps = 24;
135 // sh_video->frametime = 1.0f/sh_video->fps;
136 sh_video
->disp_w
= stream_read_word(demuxer
->stream
);
137 sh_video
->disp_h
= stream_read_word(demuxer
->stream
);
138 sh_video
->format
= stream_read_dword_le(demuxer
->stream
);
140 /* these are false values */
141 sh_video
->bih
->biSize
= 40;
142 sh_video
->bih
->biWidth
= sh_video
->disp_w
;
143 sh_video
->bih
->biHeight
= sh_video
->disp_h
;
144 sh_video
->bih
->biPlanes
= 3;
145 sh_video
->bih
->biBitCount
= 12;
146 sh_video
->bih
->biCompression
= sh_video
->format
;
147 sh_video
->bih
->biSizeImage
= sh_video
->disp_w
*sh_video
->disp_h
;
149 case mmioFOURCC('_','S','N','D'):
150 sh_audio
= new_sh_audio(demuxer
, 0);
151 demuxer
->audio
->id
= 0;
152 demuxer
->audio
->sh
= sh_audio
;
153 sh_audio
->ds
= demuxer
->audio
;
155 sh_audio
->wf
= calloc(1, sizeof(*sh_audio
->wf
));
157 sh_audio
->samplerate
= stream_read_word(demuxer
->stream
);
158 sh_audio
->wf
->wBitsPerSample
= stream_read_char(demuxer
->stream
);
159 sh_audio
->channels
= stream_read_char(demuxer
->stream
);
160 sh_audio
->format
= stream_read_dword_le(demuxer
->stream
);
161 sh_audio
->wf
->wFormatTag
= sh_audio
->format
;
162 sh_audio
->wf
->nChannels
= sh_audio
->channels
;
163 sh_audio
->wf
->nSamplesPerSec
= sh_audio
->samplerate
;
164 sh_audio
->wf
->nAvgBytesPerSec
= sh_audio
->wf
->nChannels
*
165 sh_audio
->wf
->wBitsPerSample
*sh_audio
->wf
->nSamplesPerSec
/8;
166 sh_audio
->wf
->nBlockAlign
= sh_audio
->channels
*2;
167 sh_audio
->wf
->cbSize
= 0;
169 case mmioFOURCC('_','T','X','T'):
170 stream_skip(demuxer
->stream
, stream_read_dword(demuxer
->stream
));
175 demuxer
->seekable
= 0;
180 static void demux_close_smjpeg(demuxer_t
*demuxer
)
186 const demuxer_desc_t demuxer_desc_smjpeg
= {
193 1, // safe autodetect
195 demux_smjpeg_fill_buffer
,