3 * MPEG-1/2 file format decoder for the Wiretap library.
4 * Written by Shaun Jackman <sjackman@gmail.com>
5 * Copyright 2007 Shaun Jackman
7 * MPEG-1/2 Program Streams (ISO/IEC 11172-1, ISO/IEC 13818-1 / ITU-T H.220.0)
8 * MPEG-1/2 Video bitstream (ISO/IEC 11172-2, ISO/IEC 13818-2 / ITU-T H.262)
9 * MPEG-1/2 Audio files (ISO/IEC 11172-3, ISO/IEC 13818-3)
11 * Does not handle other MPEG-2 container formats such as Transport Streams
12 * (also ISO/IEC 13818-1 / ITU-T H.222.0) or MPEG-4 containers such as
13 * MPEG-4 Part 14 / MP4 (ISO/IEC 14496-14). Support in wiretap for those
14 * two formats is provided in mp2t.c and mp4.c, respectively.
17 * SPDX-License-Identifier: GPL-2.0-or-later
23 #include <sys/types.h>
29 #include "wsutil/mpeg-audio.h"
32 #include <wsutil/buffer.h>
33 #include "file_wrappers.h"
39 #define PES_VALID(n) (((n) >> 8 & 0xffffff) == PES_PREFIX)
47 static int mpeg_file_type_subtype
= -1;
49 void register_mpeg(void);
52 mpeg_resync(FILE_T fh
, int *err
)
54 int64_t offset
= file_tell(fh
);
56 int byte
= file_getc(fh
);
59 if (byte
== 0xff && count
> 0) {
61 if (byte
!= EOF
&& (byte
& 0xe0) == 0xe0)
67 if (file_seek(fh
, offset
, SEEK_SET
, err
) == -1)
72 #define SCRHZ 27000000
75 mpeg_read_audio_packet(wtap
*wth
, FILE_T fh
, bool is_random
, int *err
, char **err_info
)
77 mpeg_t
*mpeg
= (mpeg_t
*)wth
->priv
;
78 unsigned int packet_size
;
80 if (!wtap_read_bytes_or_eof(fh
, &n
, sizeof n
, err
, err_info
))
82 if (file_seek(fh
, -(int64_t)(sizeof n
), SEEK_CUR
, err
) == -1)
87 MPA_UNMARSHAL(&mpa
, n
);
88 if (MPA_VALID(&mpa
)) {
89 packet_size
= MPA_BYTES(&mpa
);
91 mpeg
->now
.nsecs
+= MPA_DURATION_NS(&mpa
);
92 if (mpeg
->now
.nsecs
>= 1000000000) {
94 mpeg
->now
.nsecs
-= 1000000000;
98 if ((n
& 0xffffff00) == 0x49443300) {
99 /* We have an ID3v2 header; read the size */
100 if (file_seek(fh
, 6, SEEK_CUR
, err
) == -1)
102 if (!wtap_read_bytes_or_eof(fh
, &n
, sizeof n
, err
, err_info
))
104 if (file_seek(fh
, -(int64_t)(6+sizeof(n
)), SEEK_CUR
, err
) == -1)
108 /* ID3v2 size does not include the 10-byte header */
109 packet_size
= decode_synchsafe_int(n
) + 10;
111 packet_size
= mpeg_resync(fh
, err
);
118 mpeg_read_pes_packet(wtap
*wth
, FILE_T fh
, bool is_random
, int *err
, char **err_info
)
120 mpeg_t
*mpeg
= (mpeg_t
*)wth
->priv
;
121 unsigned int packet_size
= 0;
124 if (!wtap_read_bytes_or_eof(fh
, &n
, sizeof n
, err
, err_info
))
126 if (file_seek(fh
, -(int64_t)(sizeof n
), SEEK_CUR
, err
) == -1)
131 } else if (n
== PES_PREFIX
) {
132 if (!wtap_read_bytes(fh
, NULL
, 1, err
, err_info
))
136 /* XXX: We could try to recover from errors and
137 * resynchronize to the next start code.
139 *err
= WTAP_ERR_BAD_FILE
;
140 *err_info
= ws_strdup("mpeg: Non-zero stuffing bytes before start code");
143 if (!wtap_read_bytes(fh
, NULL
, 2, err
, err_info
))
147 int64_t offset
= file_tell(fh
);
150 if (!wtap_read_bytes(fh
, NULL
, 3, err
, err_info
))
153 if (!wtap_read_bytes(fh
, &stream
, sizeof stream
, err
, err_info
))
156 if (stream
== 0xba) {
162 if (!wtap_read_bytes(fh
, &pack1
, sizeof pack1
, err
, err_info
))
164 if (!wtap_read_bytes(fh
, &pack0
, sizeof pack0
, err
, err_info
))
166 pack
= (uint64_t)g_ntohl(pack1
) << 32 | g_ntohl(pack0
);
168 switch (pack
>> 62) {
170 if (!wtap_read_bytes(fh
, NULL
, 1, err
,
173 if (!wtap_read_bytes(fh
, &stuffing
,
174 sizeof stuffing
, err
, err_info
))
177 packet_size
= 14 + stuffing
;
180 uint64_t bytes
= pack
>> 16;
182 (bytes
>> 43 & 0x0007) << 30 |
183 (bytes
>> 27 & 0x7fff) << 15 |
184 (bytes
>> 11 & 0x7fff) << 0;
185 unsigned ext
= (unsigned)((bytes
>> 1) & 0x1ff);
186 uint64_t cr
= 300 * ts_val
+ ext
;
187 unsigned rem
= (unsigned)(cr
% SCRHZ
);
189 = mpeg
->t0
+ (time_t)(cr
/ SCRHZ
);
191 = (int)(INT64_C(1000000000) * rem
/ SCRHZ
);
197 } else if (stream
== 0xb9) {
198 /* MPEG_program_end_code */
202 if (!wtap_read_bytes(fh
, &length
, sizeof length
, err
, err_info
))
204 length
= g_ntohs(length
);
205 packet_size
= 6 + length
;
208 if (file_seek(fh
, offset
, SEEK_SET
, err
) == -1)
215 mpeg_read_packet(wtap
*wth
, FILE_T fh
, wtap_rec
*rec
, Buffer
*buf
,
216 bool is_random
, int *err
, char **err_info
)
218 mpeg_t
*mpeg
= (mpeg_t
*)wth
->priv
;
219 unsigned int packet_size
;
220 nstime_t ts
= mpeg
->now
;
222 if (mpeg
->is_audio
) {
223 /* mpeg_read_audio_packet calculates the duration of this
224 * packet to determine an updated relative timestamp for the
225 * next packet, if possible.
227 packet_size
= mpeg_read_audio_packet(wth
, fh
, is_random
, err
, err_info
);
229 /* mpeg_read_pes_packet uses the System Clock Reference counter
230 * to produce a relative timestamp for this packet, if possible.
232 packet_size
= mpeg_read_pes_packet(wth
, fh
, is_random
, err
, err_info
);
235 if (packet_size
== 0)
238 if (!wtap_read_packet_bytes(fh
, buf
, packet_size
, err
, err_info
))
241 rec
->rec_type
= REC_TYPE_PACKET
;
242 rec
->block
= wtap_block_create(WTAP_BLOCK_PACKET
);
244 rec
->presence_flags
= 0; /* we may or may not have a time stamp */
246 /* XXX - relative, not absolute, time stamps */
247 rec
->presence_flags
= WTAP_HAS_TS
;
250 rec
->rec_header
.packet_header
.caplen
= packet_size
;
251 rec
->rec_header
.packet_header
.len
= packet_size
;
257 mpeg_read(wtap
*wth
, wtap_rec
*rec
, Buffer
*buf
, int *err
,
258 char **err_info
, int64_t *data_offset
)
260 *data_offset
= file_tell(wth
->fh
);
262 return mpeg_read_packet(wth
, wth
->fh
, rec
, buf
, false, err
, err_info
);
266 mpeg_seek_read(wtap
*wth
, int64_t seek_off
,
267 wtap_rec
*rec
, Buffer
*buf
,
268 int *err
, char **err_info
)
270 if (file_seek(wth
->random_fh
, seek_off
, SEEK_SET
, err
) == -1)
273 if (!mpeg_read_packet(wth
, wth
->random_fh
, rec
, buf
, true, err
,
276 *err
= WTAP_ERR_SHORT_READ
;
287 { 3, "TAG", true }, /* ID3v1 */
288 /* XXX: ID3v1 tags come at the end of MP3 files, so in practice the
289 * untagged magic number is used instead.
291 { 3, "ID3", true }, /* ID3v2 */
292 { 3, "\0\0\1", false }, /* MPEG PES */
293 { 2, "\xff\xfb", true }, /* MP3 (MPEG-1 Audio Layer 3, no CRC), taken from https://en.wikipedia.org/wiki/MP3#File_structure */
295 /* XXX: The value above is for MPEG-1 Audio Layer 3 with no CRC.
296 * Only the first three nibbles are the guaranteed sync byte.
297 * For the fourth nibble, the first bit is '1' for MPEG-1 and
298 * '0' for MPEG-2 (i.e., extension to lower sampling rates),
299 * the next two bits indicate the layer (1 for layer 3, 2 for
300 * layer 2, 3 for layer 1, 0 reserved), and the last ("protection")
301 * bit is 1 if there is no CRC and 0 if there is a CRC.
303 * The mpeg-audio dissector handles these, so wiretap should open
304 * them. Including all of them might increase false positives though.
306 { 2, "\xff\xf2", true }, /* MPEG-2 Audio Layer 3, CRC */
307 { 2, "\xff\xf3", true }, /* MPEG-2 Audio Layer 3, No CRC */
308 { 2, "\xff\xf4", true }, /* MPEG-2 Audio Layer 2, CRC */
309 { 2, "\xff\xf5", true }, /* MPEG-2 Audio Layer 2, No CRC */
310 { 2, "\xff\xf6", true }, /* MPEG-2 Audio Layer 1, CRC */
311 { 2, "\xff\xf7", true }, /* MPEG-2 Audio Layer 1, No CRC */
312 { 2, "\xff\xfa", true }, /* MPEG-1 Audio Layer 3, CRC */
313 { 2, "\xff\xfc", true }, /* MPEG-1 Audio Layer 2, CRC */
314 { 2, "\xff\xfd", true }, /* MPEG-1 Audio Layer 2, No CRC */
315 { 2, "\xff\xfe", true }, /* MPEG-1 Audio Layer 1, CRC */
316 { 2, "\xff\xff", true }, /* MPEG-1 Audio Layer 1, No CRC */
322 * Even though this dissector uses magic numbers, it is registered in
323 * file_access.c as OPEN_INFO_HEURISTIC because the magic numbers are
324 * short and prone to false positives.
326 * XXX: There's room for improvement in detection if needed. A Program Stream
327 * starts with the pack_start_code, \x00\x00\x01\xba, and an uncontainered
328 * Video bitstream starts with the sequence_header_code, \x00\x00\x01\xb3.
329 * We could use those instead of matching any PES packet, which would greatly
330 * reduce false positives with e.g. PacketLogger files. (Unlike Transport
331 * Streams, unaligned file starts are unlikely with PS.)
333 * Untagged MPEG Audio files would still have to be heuristics, though.
336 mpeg_open(wtap
*wth
, int *err
, char **err_info
)
339 struct _mpeg_magic
* m
;
342 if (!wtap_read_bytes(wth
->fh
, magic_buf
, sizeof magic_buf
,
344 if (*err
!= WTAP_ERR_SHORT_READ
)
345 return WTAP_OPEN_ERROR
;
346 return WTAP_OPEN_NOT_MINE
;
349 for (m
=magic
; m
->match
; m
++) {
350 if (memcmp(magic_buf
, m
->match
, m
->len
) == 0)
354 return WTAP_OPEN_NOT_MINE
;
357 /* This appears to be a file with MPEG data. */
358 if (file_seek(wth
->fh
, 0, SEEK_SET
, err
) == -1)
359 return WTAP_OPEN_ERROR
;
361 wth
->file_type_subtype
= mpeg_file_type_subtype
;
362 wth
->file_encap
= WTAP_ENCAP_MPEG
;
363 wth
->file_tsprec
= WTAP_TSPREC_NSEC
;
364 wth
->subtype_read
= mpeg_read
;
365 wth
->subtype_seek_read
= mpeg_seek_read
;
366 wth
->snapshot_length
= 0;
368 mpeg
= g_new(mpeg_t
, 1);
369 wth
->priv
= (void *)mpeg
;
372 mpeg
->t0
= mpeg
->now
.secs
;
373 mpeg
->is_audio
= m
->is_audio
;
375 return WTAP_OPEN_MINE
;
378 static const struct supported_block_type mpeg_blocks_supported
[] = {
380 * This file format divides the file up into a "packet" for
381 * each frame, and doesn't support any options.
383 { WTAP_BLOCK_PACKET
, MULTIPLE_BLOCKS_SUPPORTED
, NO_OPTIONS_SUPPORTED
}
386 static const struct file_type_subtype_info mpeg_info
= {
387 "MPEG", "mpeg", "mpeg", "mpg;mp3",
388 false, BLOCKS_SUPPORTED(mpeg_blocks_supported
),
392 void register_mpeg(void)
394 mpeg_file_type_subtype
= wtap_register_file_type_subtype(&mpeg_info
);
397 * Register name for backwards compatibility with the
398 * wtap_filetypes table in Lua.
400 wtap_register_backwards_compatibility_lua_name("MPEG",
401 mpeg_file_type_subtype
);
405 * Editor modelines - https://www.wireshark.org/tools/modelines.html
410 * indent-tabs-mode: t
413 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
414 * :indentSize=8:tabSize=8:noTabs=false: