2 SMJPEG file parser by Alex Beregszaszi
4 Only for testing some files.
5 Commited only for Nexus' request.
7 Based on text by Arpi (SMJPEG-format.txt) and later on
8 http://www.lokigames.com/development/download/smjpeg/SMJPEG.txt
14 #include <string.h> /* strtok */
20 #include "stream/stream.h"
24 static int smjpeg_check_file(demuxer_t
* demuxer
){
25 int orig_pos
= stream_tell(demuxer
->stream
);
29 mp_msg(MSGT_DEMUX
, MSGL_V
, "Checking for SMJPEG\n");
31 if (stream_read_word(demuxer
->stream
) == 0xA)
33 stream_read(demuxer
->stream
, buf
, 6);
36 if (strncmp("SMJPEG", buf
, 6)) {
37 mp_msg(MSGT_DEMUX
, MSGL_DBG2
, "Failed: SMJPEG\n");
44 version
= stream_read_dword(demuxer
->stream
);
47 mp_msg(MSGT_DEMUX
, MSGL_ERR
, "Unknown version (%d) of SMJPEG. Please report!\n",
52 stream_seek(demuxer
->stream
, orig_pos
);
54 return DEMUXER_TYPE_SMJPEG
;
59 // 0 = EOF or no stream found
60 // 1 = successfully read a packet
61 static int demux_smjpeg_fill_buffer(demuxer_t
*demux
, demux_stream_t
*ds
)
63 int dtype
, dsize
, dpts
;
65 demux
->filepos
= stream_tell(demux
->stream
);
67 dtype
= stream_read_dword_le(demux
->stream
);
68 dpts
= stream_read_dword(demux
->stream
);
69 dsize
= stream_read_dword(demux
->stream
);
73 case mmioFOURCC('s','n','d','D'):
74 /* fixme, but no decoder implemented yet */
75 ds_read_packet(demux
->audio
, demux
->stream
, dsize
,
76 (float)dpts
/1000.0, demux
->filepos
, 0);
78 case mmioFOURCC('v','i','d','D'):
79 ds_read_packet(demux
->video
, demux
->stream
, dsize
,
80 (float)dpts
/1000.0, demux
->filepos
, 0);
82 case mmioFOURCC('D','O','N','E'):
91 static demuxer_t
* demux_open_smjpeg(demuxer_t
* demuxer
){
94 unsigned int htype
= 0, hleng
;
98 stream_skip(demuxer
->stream
, 8); /* \x00\x0aSMJPEG */
99 stream_skip(demuxer
->stream
, 4);
101 mp_msg(MSGT_DEMUX
, MSGL_INFO
, "This clip is %d seconds\n",
102 stream_read_dword(demuxer
->stream
));
108 htype
= stream_read_dword_le(demuxer
->stream
);
109 if (htype
== mmioFOURCC('H','E','N','D'))
111 hleng
= (stream_read_word(demuxer
->stream
)<<16)|stream_read_word(demuxer
->stream
);
114 case mmioFOURCC('_','V','I','D'):
115 sh_video
= new_sh_video(demuxer
, 0);
116 demuxer
->video
->sh
= sh_video
;
117 sh_video
->ds
= demuxer
->video
;
119 sh_video
->bih
= malloc(sizeof(BITMAPINFOHEADER
));
120 memset(sh_video
->bih
, 0, sizeof(BITMAPINFOHEADER
));
122 stream_skip(demuxer
->stream
, 4); /* number of frames */
123 // sh_video->fps = 24;
124 // sh_video->frametime = 1.0f/sh_video->fps;
125 sh_video
->disp_w
= stream_read_word(demuxer
->stream
);
126 sh_video
->disp_h
= stream_read_word(demuxer
->stream
);
127 sh_video
->format
= stream_read_dword_le(demuxer
->stream
);
129 /* these are false values */
130 sh_video
->bih
->biSize
= 40;
131 sh_video
->bih
->biWidth
= sh_video
->disp_w
;
132 sh_video
->bih
->biHeight
= sh_video
->disp_h
;
133 sh_video
->bih
->biPlanes
= 3;
134 sh_video
->bih
->biBitCount
= 12;
135 sh_video
->bih
->biCompression
= sh_video
->format
;
136 sh_video
->bih
->biSizeImage
= sh_video
->disp_w
*sh_video
->disp_h
;
138 case mmioFOURCC('_','S','N','D'):
139 sh_audio
= new_sh_audio(demuxer
, 0);
140 demuxer
->audio
->sh
= sh_audio
;
141 sh_audio
->ds
= demuxer
->audio
;
143 sh_audio
->wf
= malloc(sizeof(WAVEFORMATEX
));
144 memset(sh_audio
->wf
, 0, sizeof(WAVEFORMATEX
));
146 sh_audio
->samplerate
= stream_read_word(demuxer
->stream
);
147 sh_audio
->wf
->wBitsPerSample
= stream_read_char(demuxer
->stream
);
148 sh_audio
->channels
= stream_read_char(demuxer
->stream
);
149 sh_audio
->format
= stream_read_dword_le(demuxer
->stream
);
150 sh_audio
->wf
->wFormatTag
= sh_audio
->format
;
151 sh_audio
->wf
->nChannels
= sh_audio
->channels
;
152 sh_audio
->wf
->nSamplesPerSec
= sh_audio
->samplerate
;
153 sh_audio
->wf
->nAvgBytesPerSec
= sh_audio
->wf
->nChannels
*
154 sh_audio
->wf
->wBitsPerSample
*sh_audio
->wf
->nSamplesPerSec
/8;
155 sh_audio
->wf
->nBlockAlign
= sh_audio
->channels
*2;
156 sh_audio
->wf
->cbSize
= 0;
158 case mmioFOURCC('_','T','X','T'):
159 stream_skip(demuxer
->stream
, stream_read_dword(demuxer
->stream
));
164 demuxer
->seekable
= 0;
169 static void demux_close_smjpeg(demuxer_t
*demuxer
)
175 const demuxer_desc_t demuxer_desc_smjpeg
= {
182 1, // safe autodetect
184 demux_smjpeg_fill_buffer
,