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 */
25 int smjpeg_check_file(demuxer_t
* demuxer
){
26 int orig_pos
= stream_tell(demuxer
->stream
);
30 mp_msg(MSGT_DEMUX
, MSGL_V
, "Checking for SMJPEG\n");
32 if (stream_read_word(demuxer
->stream
) == 0xA)
34 stream_read(demuxer
->stream
, buf
, 6);
37 if (strncmp("SMJPEG", buf
, 6)) {
38 mp_msg(MSGT_DEMUX
, MSGL_DBG2
, "Failed: SMJPEG\n");
45 version
= stream_read_dword(demuxer
->stream
);
48 mp_msg(MSGT_DEMUX
, MSGL_ERR
, "Unknown version (%d) of SMJPEG. Please report!\n",
53 stream_seek(demuxer
->stream
, orig_pos
);
60 // 0 = EOF or no stream found
61 // 1 = successfully read a packet
62 int demux_smjpeg_fill_buffer(demuxer_t
*demux
)
64 int dtype
, dsize
, dpts
;
66 demux
->filepos
= stream_tell(demux
->stream
);
68 dtype
= stream_read_dword_le(demux
->stream
);
69 dpts
= stream_read_dword(demux
->stream
);
70 dsize
= stream_read_dword(demux
->stream
);
74 case mmioFOURCC('s','n','d','D'):
75 /* fixme, but no decoder implemented yet */
76 ds_read_packet(demux
->audio
, demux
->stream
, dsize
,
77 (float)dpts
/1000.0, demux
->filepos
, 0);
79 case mmioFOURCC('v','i','d','D'):
80 ds_read_packet(demux
->video
, demux
->stream
, dsize
,
81 (float)dpts
/1000.0, demux
->filepos
, 0);
83 case mmioFOURCC('D','O','N','E'):
92 int demux_open_smjpeg(demuxer_t
* demuxer
){
95 unsigned int htype
= 0, hleng
;
99 stream_skip(demuxer
->stream
, 8); /* \x00\x0aSMJPEG */
100 stream_skip(demuxer
->stream
, 4);
102 mp_msg(MSGT_DEMUX
, MSGL_INFO
, "This clip is %d seconds\n",
103 stream_read_dword(demuxer
->stream
));
109 htype
= stream_read_dword_le(demuxer
->stream
);
110 if (htype
== mmioFOURCC('H','E','N','D'))
112 hleng
= (stream_read_word(demuxer
->stream
)<<16)|stream_read_word(demuxer
->stream
);
115 case mmioFOURCC('_','V','I','D'):
116 sh_video
= new_sh_video(demuxer
, 0);
117 demuxer
->video
->sh
= sh_video
;
118 sh_video
->ds
= demuxer
->video
;
120 sh_video
->bih
= malloc(sizeof(BITMAPINFOHEADER
));
121 memset(sh_video
->bih
, 0, sizeof(BITMAPINFOHEADER
));
123 stream_skip(demuxer
->stream
, 4); /* number of frames */
124 // sh_video->fps = 24;
125 // sh_video->frametime = 1.0f/sh_video->fps;
126 sh_video
->disp_w
= stream_read_word(demuxer
->stream
);
127 sh_video
->disp_h
= stream_read_word(demuxer
->stream
);
128 sh_video
->format
= stream_read_dword_le(demuxer
->stream
);
130 /* these are false values */
131 sh_video
->bih
->biSize
= 40;
132 sh_video
->bih
->biWidth
= sh_video
->disp_w
;
133 sh_video
->bih
->biHeight
= sh_video
->disp_h
;
134 sh_video
->bih
->biPlanes
= 3;
135 sh_video
->bih
->biBitCount
= 12;
136 sh_video
->bih
->biCompression
= sh_video
->format
;
137 sh_video
->bih
->biSizeImage
= sh_video
->disp_w
*sh_video
->disp_h
;
139 case mmioFOURCC('_','S','N','D'):
140 sh_audio
= new_sh_audio(demuxer
, 0);
141 demuxer
->audio
->sh
= sh_audio
;
142 sh_audio
->ds
= demuxer
->audio
;
144 sh_audio
->wf
= malloc(sizeof(WAVEFORMATEX
));
145 memset(sh_audio
->wf
, 0, sizeof(WAVEFORMATEX
));
147 sh_audio
->samplerate
= stream_read_word(demuxer
->stream
);
148 sh_audio
->wf
->wBitsPerSample
= stream_read_char(demuxer
->stream
);
149 sh_audio
->channels
= stream_read_char(demuxer
->stream
);
150 sh_audio
->format
= stream_read_dword_le(demuxer
->stream
);
151 sh_audio
->wf
->wFormatTag
= sh_audio
->format
;
152 sh_audio
->wf
->nChannels
= sh_audio
->channels
;
153 sh_audio
->wf
->nSamplesPerSec
= sh_audio
->samplerate
;
154 sh_audio
->wf
->nAvgBytesPerSec
= sh_audio
->wf
->nChannels
*
155 sh_audio
->wf
->wBitsPerSample
*sh_audio
->wf
->nSamplesPerSec
/8;
156 sh_audio
->wf
->nBlockAlign
= sh_audio
->channels
*2;
157 sh_audio
->wf
->cbSize
= 0;
159 case mmioFOURCC('_','T','X','T'):
160 stream_skip(demuxer
->stream
, stream_read_dword(demuxer
->stream
));
165 demuxer
->seekable
= 0;
170 void demux_close_smjpeg(demuxer_t
*demuxer
)