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 */
33 #include "stream/stream.h"
37 static int smjpeg_check_file(demuxer_t
* demuxer
){
38 int orig_pos
= stream_tell(demuxer
->stream
);
42 mp_msg(MSGT_DEMUX
, MSGL_V
, "Checking for SMJPEG\n");
44 if (stream_read_word(demuxer
->stream
) == 0xA)
46 stream_read(demuxer
->stream
, buf
, 6);
49 if (strncmp("SMJPEG", buf
, 6)) {
50 mp_msg(MSGT_DEMUX
, MSGL_DBG2
, "Failed: SMJPEG\n");
57 version
= stream_read_dword(demuxer
->stream
);
60 mp_msg(MSGT_DEMUX
, MSGL_ERR
, "Unknown version (%d) of SMJPEG. Please report!\n",
65 stream_seek(demuxer
->stream
, orig_pos
);
67 return DEMUXER_TYPE_SMJPEG
;
72 // 0 = EOF or no stream found
73 // 1 = successfully read a packet
74 static int demux_smjpeg_fill_buffer(demuxer_t
*demux
, demux_stream_t
*ds
)
76 int dtype
, dsize
, dpts
;
78 demux
->filepos
= stream_tell(demux
->stream
);
80 dtype
= stream_read_dword_le(demux
->stream
);
81 dpts
= stream_read_dword(demux
->stream
);
82 dsize
= stream_read_dword(demux
->stream
);
86 case mmioFOURCC('s','n','d','D'):
87 /* fixme, but no decoder implemented yet */
88 ds_read_packet(demux
->audio
, demux
->stream
, dsize
,
89 (float)dpts
/1000.0, demux
->filepos
, 0);
91 case mmioFOURCC('v','i','d','D'):
92 ds_read_packet(demux
->video
, demux
->stream
, dsize
,
93 (float)dpts
/1000.0, demux
->filepos
, 0);
95 case mmioFOURCC('D','O','N','E'):
104 static demuxer_t
* demux_open_smjpeg(demuxer_t
* demuxer
){
105 sh_video_t
* sh_video
;
106 sh_audio_t
* sh_audio
;
107 unsigned int htype
= 0, hleng
;
111 stream_skip(demuxer
->stream
, 8); /* \x00\x0aSMJPEG */
112 stream_skip(demuxer
->stream
, 4);
114 mp_msg(MSGT_DEMUX
, MSGL_INFO
, "This clip is %d seconds\n",
115 stream_read_dword(demuxer
->stream
));
121 htype
= stream_read_dword_le(demuxer
->stream
);
122 if (htype
== mmioFOURCC('H','E','N','D'))
124 hleng
= (stream_read_word(demuxer
->stream
)<<16)|stream_read_word(demuxer
->stream
);
127 case mmioFOURCC('_','V','I','D'):
128 sh_video
= new_sh_video(demuxer
, 0);
129 demuxer
->video
->sh
= sh_video
;
130 sh_video
->ds
= demuxer
->video
;
132 sh_video
->bih
= malloc(sizeof(BITMAPINFOHEADER
));
133 memset(sh_video
->bih
, 0, sizeof(BITMAPINFOHEADER
));
135 stream_skip(demuxer
->stream
, 4); /* number of frames */
136 // sh_video->fps = 24;
137 // sh_video->frametime = 1.0f/sh_video->fps;
138 sh_video
->disp_w
= stream_read_word(demuxer
->stream
);
139 sh_video
->disp_h
= stream_read_word(demuxer
->stream
);
140 sh_video
->format
= stream_read_dword_le(demuxer
->stream
);
142 /* these are false values */
143 sh_video
->bih
->biSize
= 40;
144 sh_video
->bih
->biWidth
= sh_video
->disp_w
;
145 sh_video
->bih
->biHeight
= sh_video
->disp_h
;
146 sh_video
->bih
->biPlanes
= 3;
147 sh_video
->bih
->biBitCount
= 12;
148 sh_video
->bih
->biCompression
= sh_video
->format
;
149 sh_video
->bih
->biSizeImage
= sh_video
->disp_w
*sh_video
->disp_h
;
151 case mmioFOURCC('_','S','N','D'):
152 sh_audio
= new_sh_audio(demuxer
, 0);
153 demuxer
->audio
->id
= 0;
154 demuxer
->audio
->sh
= sh_audio
;
155 sh_audio
->ds
= demuxer
->audio
;
157 sh_audio
->wf
= malloc(sizeof(WAVEFORMATEX
));
158 memset(sh_audio
->wf
, 0, sizeof(WAVEFORMATEX
));
160 sh_audio
->samplerate
= stream_read_word(demuxer
->stream
);
161 sh_audio
->wf
->wBitsPerSample
= stream_read_char(demuxer
->stream
);
162 sh_audio
->channels
= stream_read_char(demuxer
->stream
);
163 sh_audio
->format
= stream_read_dword_le(demuxer
->stream
);
164 sh_audio
->wf
->wFormatTag
= sh_audio
->format
;
165 sh_audio
->wf
->nChannels
= sh_audio
->channels
;
166 sh_audio
->wf
->nSamplesPerSec
= sh_audio
->samplerate
;
167 sh_audio
->wf
->nAvgBytesPerSec
= sh_audio
->wf
->nChannels
*
168 sh_audio
->wf
->wBitsPerSample
*sh_audio
->wf
->nSamplesPerSec
/8;
169 sh_audio
->wf
->nBlockAlign
= sh_audio
->channels
*2;
170 sh_audio
->wf
->cbSize
= 0;
172 case mmioFOURCC('_','T','X','T'):
173 stream_skip(demuxer
->stream
, stream_read_dword(demuxer
->stream
));
178 demuxer
->seekable
= 0;
183 static void demux_close_smjpeg(demuxer_t
*demuxer
)
189 const demuxer_desc_t demuxer_desc_smjpeg
= {
196 1, // safe autodetect
198 demux_smjpeg_fill_buffer
,