1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
3 * mp3.h: Mp3 for the media
6 * Moonlight List (moonlight-list@lists.ximian.com)
8 * Copyright 2008 Novell, Inc. (http://www.novell.com)
10 * See the LICENSE file included with the distribution for details.
22 /* validate that this is an MPEG audio stream by checking that
23 * the 32bit header matches the pattern:
25 * 1111 1111 111* **** **** **** **** **** = 0xff 0xe0
27 * Use a mask of 0xffe6 (because bits 12 and 13 can both be 0 if it is
28 * MPEG 2.5). Compare the second byte > 0xe0 because one of the other
29 * masked bits has to be set (the Layer bits cannot both be 0).
31 #define is_mpeg_header(buffer) (buffer[0] == 0xff && ((buffer[1] & 0xe6) > 0xe0) && (buffer[1] & 0x18) != 0x08)
33 struct MpegFrameHeader
{
50 enum MpegVBRHeaderType
{
56 struct MpegVBRHeader
{
57 MpegVBRHeaderType type
;
66 // this is needed in case this frame did not specify it's own
67 // bit rate which is possible for MPEG-1 Layer 3 audio.
71 class Mp3FrameReader
{
86 guint32
MpegFrameSearch (guint64 pts
);
87 void AddFrameIndex (gint64 offset
, guint64 pts
, guint32 dur
, gint32 bit_rate
);
89 MediaResult
SkipFrame ();
92 Mp3FrameReader (IMediaSource
*source
, AudioStream
*stream
, gint64 start
, guint32 frame_len
, guint32 frame_duration
, bool xing
);
95 MediaResult
Seek (guint64 pts
);
97 MediaResult
TryReadFrame (MediaFrame
**frame
);
100 // Might change the current position of the source
101 static MediaResult
FindMpegHeader (MpegFrameHeader
*mpeg
, MpegVBRHeader
*vbr
, IMediaSource
*source
, gint64 start
, gint64
*result
);
104 class Mp3Demuxer
: public IMediaDemuxer
{
106 Mp3FrameReader
*reader
;
109 MediaResult
ReadHeader ();
111 static MediaResult
GetFrameCallback (MediaClosure
*closure
);
114 virtual ~Mp3Demuxer ();
116 virtual void GetFrameAsyncInternal (IMediaStream
*stream
);
117 virtual void OpenDemuxerAsyncInternal ();
118 virtual void SeekAsyncInternal (guint64 timeToSeek
);
119 virtual void SwitchMediaStreamAsyncInternal (IMediaStream
*stream
) {}; // An mp3 file has only 1 stream, so this doesn't make any sense
122 Mp3Demuxer (Media
*media
, IMediaSource
*source
);
124 virtual const char *GetName () { return "Mp3Demuxer"; }
127 class Mp3DemuxerInfo
: public DemuxerInfo
{
129 virtual MediaResult
Supports (IMediaSource
*source
);
130 virtual IMediaDemuxer
*Create (Media
*media
, IMediaSource
*source
);
131 virtual const char *GetName () { return "Mp3Demuxer"; }
134 bool mpeg_parse_header (MpegFrameHeader
*mpeg
, const guint8
*buffer
);
135 double mpeg_frame_length (MpegFrameHeader
*mpeg
, bool xing
);