Mercurial > mplayer.hg
annotate libmpdemux/demux_audio.c @ 35418:cedb0ba2b5c6
Move the code to set guiInfo's Track, Chapter and Angle start values.
Set them before checking whether there is any media opened, because
with no media opened we clear the counters.
author | ib |
---|---|
date | Thu, 29 Nov 2012 14:11:03 +0000 |
parents | 15b6ae10180a |
children | 494c251bd39e |
rev | line source |
---|---|
29238
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
28051
diff
changeset
|
1 /* |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
28051
diff
changeset
|
2 * This file is part of MPlayer. |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
28051
diff
changeset
|
3 * |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
28051
diff
changeset
|
4 * MPlayer is free software; you can redistribute it and/or modify |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
28051
diff
changeset
|
5 * it under the terms of the GNU General Public License as published by |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
28051
diff
changeset
|
6 * the Free Software Foundation; either version 2 of the License, or |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
28051
diff
changeset
|
7 * (at your option) any later version. |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
28051
diff
changeset
|
8 * |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
28051
diff
changeset
|
9 * MPlayer is distributed in the hope that it will be useful, |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
28051
diff
changeset
|
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
28051
diff
changeset
|
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
28051
diff
changeset
|
12 * GNU General Public License for more details. |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
28051
diff
changeset
|
13 * |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
28051
diff
changeset
|
14 * You should have received a copy of the GNU General Public License along |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
28051
diff
changeset
|
15 * with MPlayer; if not, write to the Free Software Foundation, Inc., |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
28051
diff
changeset
|
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
28051
diff
changeset
|
17 */ |
4694 | 18 |
19 #include "config.h" | |
17012 | 20 #include "mp_msg.h" |
18176
f72bc5754209
Part3 of Otvos Attila's oattila AT chello-hu mp_msg changes, with lots of modifications as usual
reynaldo
parents:
18117
diff
changeset
|
21 #include "help_mp.h" |
4694 | 22 |
23 #include <stdlib.h> | |
24 #include <stdio.h> | |
22605
4d81dbdf46b9
Add explicit location for headers from the stream/ directory.
diego
parents:
22586
diff
changeset
|
25 #include "stream/stream.h" |
30589
df6c41f16b40
Add header for AVI print functions; avoids many forward declarations.
diego
parents:
29920
diff
changeset
|
26 #include "aviprint.h" |
4694 | 27 #include "demuxer.h" |
28 #include "stheader.h" | |
29 #include "genres.h" | |
6763 | 30 #include "mp3_hdr.h" |
31418
d2fd0e4d0b9a
Move hr_mp3_seek extern variable declaration to demux_audio.h.
diego
parents:
30667
diff
changeset
|
31 #include "demux_audio.h" |
d2fd0e4d0b9a
Move hr_mp3_seek extern variable declaration to demux_audio.h.
diego
parents:
30667
diff
changeset
|
32 |
23627 | 33 #include "libavutil/intreadwrite.h" |
4694 | 34 |
35 #include <string.h> | |
36 | |
37 #define MP3 1 | |
38 #define WAV 2 | |
11004 | 39 #define fLaC 3 |
4694 | 40 |
41 | |
42 #define HDR_SIZE 4 | |
43 | |
44 typedef struct da_priv { | |
45 int frmt; | |
24589 | 46 double next_pts; |
4694 | 47 } da_priv_t; |
48 | |
18074
a491d7628cdc
check wav header length against upper limit, should protect against
reimar
parents:
17977
diff
changeset
|
49 //! rather arbitrary value for maximum length of wav-format headers |
a491d7628cdc
check wav header length against upper limit, should protect against
reimar
parents:
17977
diff
changeset
|
50 #define MAX_WAVHDR_LEN (1 * 1024 * 1024) |
a491d7628cdc
check wav header length against upper limit, should protect against
reimar
parents:
17977
diff
changeset
|
51 |
21651 | 52 //! how many valid frames in a row we need before accepting as valid MP3 |
21650
0463916369ed
Require 12 consecutive MPEG-audio headers before detecting as audio.
reimar
parents:
20334
diff
changeset
|
53 #define MIN_MP3_HDRS 12 |
13503
f8347c521898
better, tuneable (via #define) MP3 detection, limit demux_audio to scanning
reimar
parents:
13357
diff
changeset
|
54 |
f8347c521898
better, tuneable (via #define) MP3 detection, limit demux_audio to scanning
reimar
parents:
13357
diff
changeset
|
55 //! Used to describe a potential (chain of) MP3 headers we found |
f8347c521898
better, tuneable (via #define) MP3 detection, limit demux_audio to scanning
reimar
parents:
13357
diff
changeset
|
56 typedef struct mp3_hdr { |
f8347c521898
better, tuneable (via #define) MP3 detection, limit demux_audio to scanning
reimar
parents:
13357
diff
changeset
|
57 off_t frame_pos; // start of first frame in this "chain" of headers |
f8347c521898
better, tuneable (via #define) MP3 detection, limit demux_audio to scanning
reimar
parents:
13357
diff
changeset
|
58 off_t next_frame_pos; // here we expect the next header with same parameters |
f8347c521898
better, tuneable (via #define) MP3 detection, limit demux_audio to scanning
reimar
parents:
13357
diff
changeset
|
59 int mp3_chans; |
f8347c521898
better, tuneable (via #define) MP3 detection, limit demux_audio to scanning
reimar
parents:
13357
diff
changeset
|
60 int mp3_freq; |
16162
b5c2254d13f8
set i_bps in demux_audio for WAV and MP3 to avoid division by zero before
reimar
parents:
15215
diff
changeset
|
61 int mpa_spf; |
b5c2254d13f8
set i_bps in demux_audio for WAV and MP3 to avoid division by zero before
reimar
parents:
15215
diff
changeset
|
62 int mpa_layer; |
b5c2254d13f8
set i_bps in demux_audio for WAV and MP3 to avoid division by zero before
reimar
parents:
15215
diff
changeset
|
63 int mpa_br; |
13503
f8347c521898
better, tuneable (via #define) MP3 detection, limit demux_audio to scanning
reimar
parents:
13357
diff
changeset
|
64 int cons_hdrs; // if this reaches MIN_MP3_HDRS we accept as MP3 file |
f8347c521898
better, tuneable (via #define) MP3 detection, limit demux_audio to scanning
reimar
parents:
13357
diff
changeset
|
65 struct mp3_hdr *next; |
f8347c521898
better, tuneable (via #define) MP3 detection, limit demux_audio to scanning
reimar
parents:
13357
diff
changeset
|
66 } mp3_hdr_t; |
f8347c521898
better, tuneable (via #define) MP3 detection, limit demux_audio to scanning
reimar
parents:
13357
diff
changeset
|
67 |
7867 | 68 int hr_mp3_seek = 0; |
4694 | 69 |
13503
f8347c521898
better, tuneable (via #define) MP3 detection, limit demux_audio to scanning
reimar
parents:
13357
diff
changeset
|
70 /** |
f8347c521898
better, tuneable (via #define) MP3 detection, limit demux_audio to scanning
reimar
parents:
13357
diff
changeset
|
71 * \brief free a list of MP3 header descriptions |
f8347c521898
better, tuneable (via #define) MP3 detection, limit demux_audio to scanning
reimar
parents:
13357
diff
changeset
|
72 * \param list pointer to the head-of-list pointer |
f8347c521898
better, tuneable (via #define) MP3 detection, limit demux_audio to scanning
reimar
parents:
13357
diff
changeset
|
73 */ |
f8347c521898
better, tuneable (via #define) MP3 detection, limit demux_audio to scanning
reimar
parents:
13357
diff
changeset
|
74 static void free_mp3_hdrs(mp3_hdr_t **list) { |
f8347c521898
better, tuneable (via #define) MP3 detection, limit demux_audio to scanning
reimar
parents:
13357
diff
changeset
|
75 mp3_hdr_t *tmp; |
f8347c521898
better, tuneable (via #define) MP3 detection, limit demux_audio to scanning
reimar
parents:
13357
diff
changeset
|
76 while (*list) { |
f8347c521898
better, tuneable (via #define) MP3 detection, limit demux_audio to scanning
reimar
parents:
13357
diff
changeset
|
77 tmp = (*list)->next; |
f8347c521898
better, tuneable (via #define) MP3 detection, limit demux_audio to scanning
reimar
parents:
13357
diff
changeset
|
78 free(*list); |
f8347c521898
better, tuneable (via #define) MP3 detection, limit demux_audio to scanning
reimar
parents:
13357
diff
changeset
|
79 *list = tmp; |
f8347c521898
better, tuneable (via #define) MP3 detection, limit demux_audio to scanning
reimar
parents:
13357
diff
changeset
|
80 } |
f8347c521898
better, tuneable (via #define) MP3 detection, limit demux_audio to scanning
reimar
parents:
13357
diff
changeset
|
81 } |
f8347c521898
better, tuneable (via #define) MP3 detection, limit demux_audio to scanning
reimar
parents:
13357
diff
changeset
|
82 |
f8347c521898
better, tuneable (via #define) MP3 detection, limit demux_audio to scanning
reimar
parents:
13357
diff
changeset
|
83 /** |
f8347c521898
better, tuneable (via #define) MP3 detection, limit demux_audio to scanning
reimar
parents:
13357
diff
changeset
|
84 * \brief add another potential MP3 header to our list |
f8347c521898
better, tuneable (via #define) MP3 detection, limit demux_audio to scanning
reimar
parents:
13357
diff
changeset
|
85 * If it fits into an existing chain this one is expanded otherwise |
f8347c521898
better, tuneable (via #define) MP3 detection, limit demux_audio to scanning
reimar
parents:
13357
diff
changeset
|
86 * a new one is created. |
f8347c521898
better, tuneable (via #define) MP3 detection, limit demux_audio to scanning
reimar
parents:
13357
diff
changeset
|
87 * All entries that expected a MP3 header before the current position |
f8347c521898
better, tuneable (via #define) MP3 detection, limit demux_audio to scanning
reimar
parents:
13357
diff
changeset
|
88 * are discarded. |
f8347c521898
better, tuneable (via #define) MP3 detection, limit demux_audio to scanning
reimar
parents:
13357
diff
changeset
|
89 * The list is expected to be and will be kept sorted by next_frame_pos |
f8347c521898
better, tuneable (via #define) MP3 detection, limit demux_audio to scanning
reimar
parents:
13357
diff
changeset
|
90 * and when those are equal by frame_pos. |
f8347c521898
better, tuneable (via #define) MP3 detection, limit demux_audio to scanning
reimar
parents:
13357
diff
changeset
|
91 * \param list pointer to the head-of-list pointer |
f8347c521898
better, tuneable (via #define) MP3 detection, limit demux_audio to scanning
reimar
parents:
13357
diff
changeset
|
92 * \param st_pos stream position where the described header starts |
16162
b5c2254d13f8
set i_bps in demux_audio for WAV and MP3 to avoid division by zero before
reimar
parents:
15215
diff
changeset
|
93 * \param mp3_chans number of channels as specified by the header (*) |
b5c2254d13f8
set i_bps in demux_audio for WAV and MP3 to avoid division by zero before
reimar
parents:
15215
diff
changeset
|
94 * \param mp3_freq sampling frequency as specified by the header (*) |
b5c2254d13f8
set i_bps in demux_audio for WAV and MP3 to avoid division by zero before
reimar
parents:
15215
diff
changeset
|
95 * \param mpa_spf frame size as specified by the header |
b5c2254d13f8
set i_bps in demux_audio for WAV and MP3 to avoid division by zero before
reimar
parents:
15215
diff
changeset
|
96 * \param mpa_layer layer type ("version") as specified by the header (*) |
b5c2254d13f8
set i_bps in demux_audio for WAV and MP3 to avoid division by zero before
reimar
parents:
15215
diff
changeset
|
97 * \param mpa_br bitrate as specified by the header |
13503
f8347c521898
better, tuneable (via #define) MP3 detection, limit demux_audio to scanning
reimar
parents:
13357
diff
changeset
|
98 * \param mp3_flen length of the frame as specified by the header |
f8347c521898
better, tuneable (via #define) MP3 detection, limit demux_audio to scanning
reimar
parents:
13357
diff
changeset
|
99 * \return If non-null the current file is accepted as MP3 and the |
f8347c521898
better, tuneable (via #define) MP3 detection, limit demux_audio to scanning
reimar
parents:
13357
diff
changeset
|
100 * mp3_hdr struct describing the valid chain is returned. Must be |
f8347c521898
better, tuneable (via #define) MP3 detection, limit demux_audio to scanning
reimar
parents:
13357
diff
changeset
|
101 * freed independent of the list. |
16162
b5c2254d13f8
set i_bps in demux_audio for WAV and MP3 to avoid division by zero before
reimar
parents:
15215
diff
changeset
|
102 * |
b5c2254d13f8
set i_bps in demux_audio for WAV and MP3 to avoid division by zero before
reimar
parents:
15215
diff
changeset
|
103 * parameters marked by (*) must be the same for all headers in the same chain |
13503
f8347c521898
better, tuneable (via #define) MP3 detection, limit demux_audio to scanning
reimar
parents:
13357
diff
changeset
|
104 */ |
f8347c521898
better, tuneable (via #define) MP3 detection, limit demux_audio to scanning
reimar
parents:
13357
diff
changeset
|
105 static mp3_hdr_t *add_mp3_hdr(mp3_hdr_t **list, off_t st_pos, |
16162
b5c2254d13f8
set i_bps in demux_audio for WAV and MP3 to avoid division by zero before
reimar
parents:
15215
diff
changeset
|
106 int mp3_chans, int mp3_freq, int mpa_spf, |
b5c2254d13f8
set i_bps in demux_audio for WAV and MP3 to avoid division by zero before
reimar
parents:
15215
diff
changeset
|
107 int mpa_layer, int mpa_br, int mp3_flen) { |
13503
f8347c521898
better, tuneable (via #define) MP3 detection, limit demux_audio to scanning
reimar
parents:
13357
diff
changeset
|
108 mp3_hdr_t *tmp; |
f8347c521898
better, tuneable (via #define) MP3 detection, limit demux_audio to scanning
reimar
parents:
13357
diff
changeset
|
109 int in_list = 0; |
f8347c521898
better, tuneable (via #define) MP3 detection, limit demux_audio to scanning
reimar
parents:
13357
diff
changeset
|
110 while (*list && (*list)->next_frame_pos <= st_pos) { |
f8347c521898
better, tuneable (via #define) MP3 detection, limit demux_audio to scanning
reimar
parents:
13357
diff
changeset
|
111 if (((*list)->next_frame_pos < st_pos) || ((*list)->mp3_chans != mp3_chans) |
16162
b5c2254d13f8
set i_bps in demux_audio for WAV and MP3 to avoid division by zero before
reimar
parents:
15215
diff
changeset
|
112 || ((*list)->mp3_freq != mp3_freq) || ((*list)->mpa_layer != mpa_layer) ) { |
b5c2254d13f8
set i_bps in demux_audio for WAV and MP3 to avoid division by zero before
reimar
parents:
15215
diff
changeset
|
113 // wasn't valid! |
13503
f8347c521898
better, tuneable (via #define) MP3 detection, limit demux_audio to scanning
reimar
parents:
13357
diff
changeset
|
114 tmp = (*list)->next; |
f8347c521898
better, tuneable (via #define) MP3 detection, limit demux_audio to scanning
reimar
parents:
13357
diff
changeset
|
115 free(*list); |
f8347c521898
better, tuneable (via #define) MP3 detection, limit demux_audio to scanning
reimar
parents:
13357
diff
changeset
|
116 *list = tmp; |
f8347c521898
better, tuneable (via #define) MP3 detection, limit demux_audio to scanning
reimar
parents:
13357
diff
changeset
|
117 } else { |
f8347c521898
better, tuneable (via #define) MP3 detection, limit demux_audio to scanning
reimar
parents:
13357
diff
changeset
|
118 (*list)->cons_hdrs++; |
f8347c521898
better, tuneable (via #define) MP3 detection, limit demux_audio to scanning
reimar
parents:
13357
diff
changeset
|
119 (*list)->next_frame_pos = st_pos + mp3_flen; |
16162
b5c2254d13f8
set i_bps in demux_audio for WAV and MP3 to avoid division by zero before
reimar
parents:
15215
diff
changeset
|
120 (*list)->mpa_spf = mpa_spf; |
b5c2254d13f8
set i_bps in demux_audio for WAV and MP3 to avoid division by zero before
reimar
parents:
15215
diff
changeset
|
121 (*list)->mpa_br = mpa_br; |
13503
f8347c521898
better, tuneable (via #define) MP3 detection, limit demux_audio to scanning
reimar
parents:
13357
diff
changeset
|
122 if ((*list)->cons_hdrs >= MIN_MP3_HDRS) { |
f8347c521898
better, tuneable (via #define) MP3 detection, limit demux_audio to scanning
reimar
parents:
13357
diff
changeset
|
123 // copy the valid entry, so that the list can be easily freed |
f8347c521898
better, tuneable (via #define) MP3 detection, limit demux_audio to scanning
reimar
parents:
13357
diff
changeset
|
124 tmp = malloc(sizeof(mp3_hdr_t)); |
f8347c521898
better, tuneable (via #define) MP3 detection, limit demux_audio to scanning
reimar
parents:
13357
diff
changeset
|
125 memcpy(tmp, *list, sizeof(mp3_hdr_t)); |
f8347c521898
better, tuneable (via #define) MP3 detection, limit demux_audio to scanning
reimar
parents:
13357
diff
changeset
|
126 tmp->next = NULL; |
f8347c521898
better, tuneable (via #define) MP3 detection, limit demux_audio to scanning
reimar
parents:
13357
diff
changeset
|
127 return tmp; |
f8347c521898
better, tuneable (via #define) MP3 detection, limit demux_audio to scanning
reimar
parents:
13357
diff
changeset
|
128 } |
f8347c521898
better, tuneable (via #define) MP3 detection, limit demux_audio to scanning
reimar
parents:
13357
diff
changeset
|
129 in_list = 1; |
f8347c521898
better, tuneable (via #define) MP3 detection, limit demux_audio to scanning
reimar
parents:
13357
diff
changeset
|
130 list = &((*list)->next); |
f8347c521898
better, tuneable (via #define) MP3 detection, limit demux_audio to scanning
reimar
parents:
13357
diff
changeset
|
131 } |
f8347c521898
better, tuneable (via #define) MP3 detection, limit demux_audio to scanning
reimar
parents:
13357
diff
changeset
|
132 } |
f8347c521898
better, tuneable (via #define) MP3 detection, limit demux_audio to scanning
reimar
parents:
13357
diff
changeset
|
133 if (!in_list) { // does not belong into an existing chain, insert |
15215
db6286839af7
Fix MP3 detection (list of found MP3 headers was not kep sorted).
reimar
parents:
15205
diff
changeset
|
134 // find right position to insert to keep sorting |
db6286839af7
Fix MP3 detection (list of found MP3 headers was not kep sorted).
reimar
parents:
15205
diff
changeset
|
135 while (*list && (*list)->next_frame_pos <= st_pos + mp3_flen) |
db6286839af7
Fix MP3 detection (list of found MP3 headers was not kep sorted).
reimar
parents:
15205
diff
changeset
|
136 list = &((*list)->next); |
13503
f8347c521898
better, tuneable (via #define) MP3 detection, limit demux_audio to scanning
reimar
parents:
13357
diff
changeset
|
137 tmp = malloc(sizeof(mp3_hdr_t)); |
f8347c521898
better, tuneable (via #define) MP3 detection, limit demux_audio to scanning
reimar
parents:
13357
diff
changeset
|
138 tmp->frame_pos = st_pos; |
f8347c521898
better, tuneable (via #define) MP3 detection, limit demux_audio to scanning
reimar
parents:
13357
diff
changeset
|
139 tmp->next_frame_pos = st_pos + mp3_flen; |
f8347c521898
better, tuneable (via #define) MP3 detection, limit demux_audio to scanning
reimar
parents:
13357
diff
changeset
|
140 tmp->mp3_chans = mp3_chans; |
f8347c521898
better, tuneable (via #define) MP3 detection, limit demux_audio to scanning
reimar
parents:
13357
diff
changeset
|
141 tmp->mp3_freq = mp3_freq; |
16162
b5c2254d13f8
set i_bps in demux_audio for WAV and MP3 to avoid division by zero before
reimar
parents:
15215
diff
changeset
|
142 tmp->mpa_spf = mpa_spf; |
b5c2254d13f8
set i_bps in demux_audio for WAV and MP3 to avoid division by zero before
reimar
parents:
15215
diff
changeset
|
143 tmp->mpa_layer = mpa_layer; |
b5c2254d13f8
set i_bps in demux_audio for WAV and MP3 to avoid division by zero before
reimar
parents:
15215
diff
changeset
|
144 tmp->mpa_br = mpa_br; |
13503
f8347c521898
better, tuneable (via #define) MP3 detection, limit demux_audio to scanning
reimar
parents:
13357
diff
changeset
|
145 tmp->cons_hdrs = 1; |
f8347c521898
better, tuneable (via #define) MP3 detection, limit demux_audio to scanning
reimar
parents:
13357
diff
changeset
|
146 tmp->next = *list; |
f8347c521898
better, tuneable (via #define) MP3 detection, limit demux_audio to scanning
reimar
parents:
13357
diff
changeset
|
147 *list = tmp; |
f8347c521898
better, tuneable (via #define) MP3 detection, limit demux_audio to scanning
reimar
parents:
13357
diff
changeset
|
148 } |
f8347c521898
better, tuneable (via #define) MP3 detection, limit demux_audio to scanning
reimar
parents:
13357
diff
changeset
|
149 return NULL; |
f8347c521898
better, tuneable (via #define) MP3 detection, limit demux_audio to scanning
reimar
parents:
13357
diff
changeset
|
150 } |
f8347c521898
better, tuneable (via #define) MP3 detection, limit demux_audio to scanning
reimar
parents:
13357
diff
changeset
|
151 |
25896 | 152 #if 0 /* this code is a mess, clean it up before reenabling */ |
17898
a2b85171b4de
retrieve metadata from FLAC files (patch by Benjamin Zores < ben _at_ geexbox.org >)
aurel
parents:
17790
diff
changeset
|
153 #define FLAC_SIGNATURE_SIZE 4 |
a2b85171b4de
retrieve metadata from FLAC files (patch by Benjamin Zores < ben _at_ geexbox.org >)
aurel
parents:
17790
diff
changeset
|
154 #define FLAC_STREAMINFO_SIZE 34 |
a2b85171b4de
retrieve metadata from FLAC files (patch by Benjamin Zores < ben _at_ geexbox.org >)
aurel
parents:
17790
diff
changeset
|
155 #define FLAC_SEEKPOINT_SIZE 18 |
a2b85171b4de
retrieve metadata from FLAC files (patch by Benjamin Zores < ben _at_ geexbox.org >)
aurel
parents:
17790
diff
changeset
|
156 |
a2b85171b4de
retrieve metadata from FLAC files (patch by Benjamin Zores < ben _at_ geexbox.org >)
aurel
parents:
17790
diff
changeset
|
157 enum { |
a2b85171b4de
retrieve metadata from FLAC files (patch by Benjamin Zores < ben _at_ geexbox.org >)
aurel
parents:
17790
diff
changeset
|
158 FLAC_STREAMINFO = 0, |
a2b85171b4de
retrieve metadata from FLAC files (patch by Benjamin Zores < ben _at_ geexbox.org >)
aurel
parents:
17790
diff
changeset
|
159 FLAC_PADDING, |
a2b85171b4de
retrieve metadata from FLAC files (patch by Benjamin Zores < ben _at_ geexbox.org >)
aurel
parents:
17790
diff
changeset
|
160 FLAC_APPLICATION, |
a2b85171b4de
retrieve metadata from FLAC files (patch by Benjamin Zores < ben _at_ geexbox.org >)
aurel
parents:
17790
diff
changeset
|
161 FLAC_SEEKTABLE, |
a2b85171b4de
retrieve metadata from FLAC files (patch by Benjamin Zores < ben _at_ geexbox.org >)
aurel
parents:
17790
diff
changeset
|
162 FLAC_VORBIS_COMMENT, |
a2b85171b4de
retrieve metadata from FLAC files (patch by Benjamin Zores < ben _at_ geexbox.org >)
aurel
parents:
17790
diff
changeset
|
163 FLAC_CUESHEET |
a2b85171b4de
retrieve metadata from FLAC files (patch by Benjamin Zores < ben _at_ geexbox.org >)
aurel
parents:
17790
diff
changeset
|
164 } flac_preamble_t; |
a2b85171b4de
retrieve metadata from FLAC files (patch by Benjamin Zores < ben _at_ geexbox.org >)
aurel
parents:
17790
diff
changeset
|
165 |
a2b85171b4de
retrieve metadata from FLAC files (patch by Benjamin Zores < ben _at_ geexbox.org >)
aurel
parents:
17790
diff
changeset
|
166 static void |
a2b85171b4de
retrieve metadata from FLAC files (patch by Benjamin Zores < ben _at_ geexbox.org >)
aurel
parents:
17790
diff
changeset
|
167 get_flac_metadata (demuxer_t* demuxer) |
a2b85171b4de
retrieve metadata from FLAC files (patch by Benjamin Zores < ben _at_ geexbox.org >)
aurel
parents:
17790
diff
changeset
|
168 { |
a2b85171b4de
retrieve metadata from FLAC files (patch by Benjamin Zores < ben _at_ geexbox.org >)
aurel
parents:
17790
diff
changeset
|
169 uint8_t preamble[4]; |
a2b85171b4de
retrieve metadata from FLAC files (patch by Benjamin Zores < ben _at_ geexbox.org >)
aurel
parents:
17790
diff
changeset
|
170 unsigned int blk_len; |
26374 | 171 stream_t *s = demuxer->stream; |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
172 |
17898
a2b85171b4de
retrieve metadata from FLAC files (patch by Benjamin Zores < ben _at_ geexbox.org >)
aurel
parents:
17790
diff
changeset
|
173 /* file is qualified; skip over the signature bytes in the stream */ |
a2b85171b4de
retrieve metadata from FLAC files (patch by Benjamin Zores < ben _at_ geexbox.org >)
aurel
parents:
17790
diff
changeset
|
174 stream_seek (s, 4); |
a2b85171b4de
retrieve metadata from FLAC files (patch by Benjamin Zores < ben _at_ geexbox.org >)
aurel
parents:
17790
diff
changeset
|
175 |
a2b85171b4de
retrieve metadata from FLAC files (patch by Benjamin Zores < ben _at_ geexbox.org >)
aurel
parents:
17790
diff
changeset
|
176 /* loop through the metadata blocks; use a do-while construct since there |
a2b85171b4de
retrieve metadata from FLAC files (patch by Benjamin Zores < ben _at_ geexbox.org >)
aurel
parents:
17790
diff
changeset
|
177 * will always be 1 metadata block */ |
a2b85171b4de
retrieve metadata from FLAC files (patch by Benjamin Zores < ben _at_ geexbox.org >)
aurel
parents:
17790
diff
changeset
|
178 do { |
a2b85171b4de
retrieve metadata from FLAC files (patch by Benjamin Zores < ben _at_ geexbox.org >)
aurel
parents:
17790
diff
changeset
|
179 int r; |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
180 |
17898
a2b85171b4de
retrieve metadata from FLAC files (patch by Benjamin Zores < ben _at_ geexbox.org >)
aurel
parents:
17790
diff
changeset
|
181 r = stream_read (s, (char *) preamble, FLAC_SIGNATURE_SIZE); |
a2b85171b4de
retrieve metadata from FLAC files (patch by Benjamin Zores < ben _at_ geexbox.org >)
aurel
parents:
17790
diff
changeset
|
182 if (r != FLAC_SIGNATURE_SIZE) |
a2b85171b4de
retrieve metadata from FLAC files (patch by Benjamin Zores < ben _at_ geexbox.org >)
aurel
parents:
17790
diff
changeset
|
183 return; |
a2b85171b4de
retrieve metadata from FLAC files (patch by Benjamin Zores < ben _at_ geexbox.org >)
aurel
parents:
17790
diff
changeset
|
184 |
26375 | 185 blk_len = AV_RB24(preamble + 1); |
17898
a2b85171b4de
retrieve metadata from FLAC files (patch by Benjamin Zores < ben _at_ geexbox.org >)
aurel
parents:
17790
diff
changeset
|
186 |
a2b85171b4de
retrieve metadata from FLAC files (patch by Benjamin Zores < ben _at_ geexbox.org >)
aurel
parents:
17790
diff
changeset
|
187 switch (preamble[0] & 0x7F) |
a2b85171b4de
retrieve metadata from FLAC files (patch by Benjamin Zores < ben _at_ geexbox.org >)
aurel
parents:
17790
diff
changeset
|
188 { |
a2b85171b4de
retrieve metadata from FLAC files (patch by Benjamin Zores < ben _at_ geexbox.org >)
aurel
parents:
17790
diff
changeset
|
189 case FLAC_VORBIS_COMMENT: |
a2b85171b4de
retrieve metadata from FLAC files (patch by Benjamin Zores < ben _at_ geexbox.org >)
aurel
parents:
17790
diff
changeset
|
190 { |
a2b85171b4de
retrieve metadata from FLAC files (patch by Benjamin Zores < ben _at_ geexbox.org >)
aurel
parents:
17790
diff
changeset
|
191 /* For a description of the format please have a look at */ |
a2b85171b4de
retrieve metadata from FLAC files (patch by Benjamin Zores < ben _at_ geexbox.org >)
aurel
parents:
17790
diff
changeset
|
192 /* http://www.xiph.org/vorbis/doc/v-comment.html */ |
a2b85171b4de
retrieve metadata from FLAC files (patch by Benjamin Zores < ben _at_ geexbox.org >)
aurel
parents:
17790
diff
changeset
|
193 |
a2b85171b4de
retrieve metadata from FLAC files (patch by Benjamin Zores < ben _at_ geexbox.org >)
aurel
parents:
17790
diff
changeset
|
194 uint32_t length, comment_list_len; |
a2b85171b4de
retrieve metadata from FLAC files (patch by Benjamin Zores < ben _at_ geexbox.org >)
aurel
parents:
17790
diff
changeset
|
195 char comments[blk_len]; |
23628
d4f96ae7081c
Get rid of: useless variable, useless cast and void * arithmetic
reimar
parents:
23627
diff
changeset
|
196 uint8_t *ptr = comments; |
17898
a2b85171b4de
retrieve metadata from FLAC files (patch by Benjamin Zores < ben _at_ geexbox.org >)
aurel
parents:
17790
diff
changeset
|
197 char *comment; |
a2b85171b4de
retrieve metadata from FLAC files (patch by Benjamin Zores < ben _at_ geexbox.org >)
aurel
parents:
17790
diff
changeset
|
198 int cn; |
a2b85171b4de
retrieve metadata from FLAC files (patch by Benjamin Zores < ben _at_ geexbox.org >)
aurel
parents:
17790
diff
changeset
|
199 char c; |
a2b85171b4de
retrieve metadata from FLAC files (patch by Benjamin Zores < ben _at_ geexbox.org >)
aurel
parents:
17790
diff
changeset
|
200 |
a2b85171b4de
retrieve metadata from FLAC files (patch by Benjamin Zores < ben _at_ geexbox.org >)
aurel
parents:
17790
diff
changeset
|
201 if (stream_read (s, comments, blk_len) == blk_len) |
a2b85171b4de
retrieve metadata from FLAC files (patch by Benjamin Zores < ben _at_ geexbox.org >)
aurel
parents:
17790
diff
changeset
|
202 { |
23628
d4f96ae7081c
Get rid of: useless variable, useless cast and void * arithmetic
reimar
parents:
23627
diff
changeset
|
203 length = AV_RL32(ptr); |
17898
a2b85171b4de
retrieve metadata from FLAC files (patch by Benjamin Zores < ben _at_ geexbox.org >)
aurel
parents:
17790
diff
changeset
|
204 ptr += 4 + length; |
a2b85171b4de
retrieve metadata from FLAC files (patch by Benjamin Zores < ben _at_ geexbox.org >)
aurel
parents:
17790
diff
changeset
|
205 |
23628
d4f96ae7081c
Get rid of: useless variable, useless cast and void * arithmetic
reimar
parents:
23627
diff
changeset
|
206 comment_list_len = AV_RL32(ptr); |
17898
a2b85171b4de
retrieve metadata from FLAC files (patch by Benjamin Zores < ben _at_ geexbox.org >)
aurel
parents:
17790
diff
changeset
|
207 ptr += 4; |
a2b85171b4de
retrieve metadata from FLAC files (patch by Benjamin Zores < ben _at_ geexbox.org >)
aurel
parents:
17790
diff
changeset
|
208 |
a2b85171b4de
retrieve metadata from FLAC files (patch by Benjamin Zores < ben _at_ geexbox.org >)
aurel
parents:
17790
diff
changeset
|
209 cn = 0; |
a2b85171b4de
retrieve metadata from FLAC files (patch by Benjamin Zores < ben _at_ geexbox.org >)
aurel
parents:
17790
diff
changeset
|
210 for (; cn < comment_list_len; cn++) |
a2b85171b4de
retrieve metadata from FLAC files (patch by Benjamin Zores < ben _at_ geexbox.org >)
aurel
parents:
17790
diff
changeset
|
211 { |
23628
d4f96ae7081c
Get rid of: useless variable, useless cast and void * arithmetic
reimar
parents:
23627
diff
changeset
|
212 length = AV_RL32(ptr); |
17898
a2b85171b4de
retrieve metadata from FLAC files (patch by Benjamin Zores < ben _at_ geexbox.org >)
aurel
parents:
17790
diff
changeset
|
213 ptr += 4; |
a2b85171b4de
retrieve metadata from FLAC files (patch by Benjamin Zores < ben _at_ geexbox.org >)
aurel
parents:
17790
diff
changeset
|
214 |
23628
d4f96ae7081c
Get rid of: useless variable, useless cast and void * arithmetic
reimar
parents:
23627
diff
changeset
|
215 comment = ptr; |
25889 | 216 if (&comment[length] < comments || &comment[length] >= &comments[blk_len]) |
217 return; | |
17898
a2b85171b4de
retrieve metadata from FLAC files (patch by Benjamin Zores < ben _at_ geexbox.org >)
aurel
parents:
17790
diff
changeset
|
218 c = comment[length]; |
a2b85171b4de
retrieve metadata from FLAC files (patch by Benjamin Zores < ben _at_ geexbox.org >)
aurel
parents:
17790
diff
changeset
|
219 comment[length] = 0; |
a2b85171b4de
retrieve metadata from FLAC files (patch by Benjamin Zores < ben _at_ geexbox.org >)
aurel
parents:
17790
diff
changeset
|
220 |
a2b85171b4de
retrieve metadata from FLAC files (patch by Benjamin Zores < ben _at_ geexbox.org >)
aurel
parents:
17790
diff
changeset
|
221 if (!strncasecmp ("TITLE=", comment, 6) && (length - 6 > 0)) |
a2b85171b4de
retrieve metadata from FLAC files (patch by Benjamin Zores < ben _at_ geexbox.org >)
aurel
parents:
17790
diff
changeset
|
222 demux_info_add (demuxer, "Title", comment + 6); |
a2b85171b4de
retrieve metadata from FLAC files (patch by Benjamin Zores < ben _at_ geexbox.org >)
aurel
parents:
17790
diff
changeset
|
223 else if (!strncasecmp ("ARTIST=", comment, 7) && (length - 7 > 0)) |
a2b85171b4de
retrieve metadata from FLAC files (patch by Benjamin Zores < ben _at_ geexbox.org >)
aurel
parents:
17790
diff
changeset
|
224 demux_info_add (demuxer, "Artist", comment + 7); |
a2b85171b4de
retrieve metadata from FLAC files (patch by Benjamin Zores < ben _at_ geexbox.org >)
aurel
parents:
17790
diff
changeset
|
225 else if (!strncasecmp ("ALBUM=", comment, 6) && (length - 6 > 0)) |
a2b85171b4de
retrieve metadata from FLAC files (patch by Benjamin Zores < ben _at_ geexbox.org >)
aurel
parents:
17790
diff
changeset
|
226 demux_info_add (demuxer, "Album", comment + 6); |
a2b85171b4de
retrieve metadata from FLAC files (patch by Benjamin Zores < ben _at_ geexbox.org >)
aurel
parents:
17790
diff
changeset
|
227 else if (!strncasecmp ("DATE=", comment, 5) && (length - 5 > 0)) |
a2b85171b4de
retrieve metadata from FLAC files (patch by Benjamin Zores < ben _at_ geexbox.org >)
aurel
parents:
17790
diff
changeset
|
228 demux_info_add (demuxer, "Year", comment + 5); |
a2b85171b4de
retrieve metadata from FLAC files (patch by Benjamin Zores < ben _at_ geexbox.org >)
aurel
parents:
17790
diff
changeset
|
229 else if (!strncasecmp ("GENRE=", comment, 6) && (length - 6 > 0)) |
a2b85171b4de
retrieve metadata from FLAC files (patch by Benjamin Zores < ben _at_ geexbox.org >)
aurel
parents:
17790
diff
changeset
|
230 demux_info_add (demuxer, "Genre", comment + 6); |
a2b85171b4de
retrieve metadata from FLAC files (patch by Benjamin Zores < ben _at_ geexbox.org >)
aurel
parents:
17790
diff
changeset
|
231 else if (!strncasecmp ("Comment=", comment, 8) && (length - 8 > 0)) |
a2b85171b4de
retrieve metadata from FLAC files (patch by Benjamin Zores < ben _at_ geexbox.org >)
aurel
parents:
17790
diff
changeset
|
232 demux_info_add (demuxer, "Comment", comment + 8); |
a2b85171b4de
retrieve metadata from FLAC files (patch by Benjamin Zores < ben _at_ geexbox.org >)
aurel
parents:
17790
diff
changeset
|
233 else if (!strncasecmp ("TRACKNUMBER=", comment, 12) |
a2b85171b4de
retrieve metadata from FLAC files (patch by Benjamin Zores < ben _at_ geexbox.org >)
aurel
parents:
17790
diff
changeset
|
234 && (length - 12 > 0)) |
a2b85171b4de
retrieve metadata from FLAC files (patch by Benjamin Zores < ben _at_ geexbox.org >)
aurel
parents:
17790
diff
changeset
|
235 { |
a2b85171b4de
retrieve metadata from FLAC files (patch by Benjamin Zores < ben _at_ geexbox.org >)
aurel
parents:
17790
diff
changeset
|
236 char buf[31]; |
a2b85171b4de
retrieve metadata from FLAC files (patch by Benjamin Zores < ben _at_ geexbox.org >)
aurel
parents:
17790
diff
changeset
|
237 buf[30] = '\0'; |
a2b85171b4de
retrieve metadata from FLAC files (patch by Benjamin Zores < ben _at_ geexbox.org >)
aurel
parents:
17790
diff
changeset
|
238 sprintf (buf, "%d", atoi (comment + 12)); |
a2b85171b4de
retrieve metadata from FLAC files (patch by Benjamin Zores < ben _at_ geexbox.org >)
aurel
parents:
17790
diff
changeset
|
239 demux_info_add(demuxer, "Track", buf); |
a2b85171b4de
retrieve metadata from FLAC files (patch by Benjamin Zores < ben _at_ geexbox.org >)
aurel
parents:
17790
diff
changeset
|
240 } |
a2b85171b4de
retrieve metadata from FLAC files (patch by Benjamin Zores < ben _at_ geexbox.org >)
aurel
parents:
17790
diff
changeset
|
241 comment[length] = c; |
a2b85171b4de
retrieve metadata from FLAC files (patch by Benjamin Zores < ben _at_ geexbox.org >)
aurel
parents:
17790
diff
changeset
|
242 |
a2b85171b4de
retrieve metadata from FLAC files (patch by Benjamin Zores < ben _at_ geexbox.org >)
aurel
parents:
17790
diff
changeset
|
243 ptr += length; |
a2b85171b4de
retrieve metadata from FLAC files (patch by Benjamin Zores < ben _at_ geexbox.org >)
aurel
parents:
17790
diff
changeset
|
244 } |
a2b85171b4de
retrieve metadata from FLAC files (patch by Benjamin Zores < ben _at_ geexbox.org >)
aurel
parents:
17790
diff
changeset
|
245 } |
a2b85171b4de
retrieve metadata from FLAC files (patch by Benjamin Zores < ben _at_ geexbox.org >)
aurel
parents:
17790
diff
changeset
|
246 break; |
a2b85171b4de
retrieve metadata from FLAC files (patch by Benjamin Zores < ben _at_ geexbox.org >)
aurel
parents:
17790
diff
changeset
|
247 } |
a2b85171b4de
retrieve metadata from FLAC files (patch by Benjamin Zores < ben _at_ geexbox.org >)
aurel
parents:
17790
diff
changeset
|
248 |
26376
68302d38e153
Remove another two useless special-case from flac metadata reading function
reimar
parents:
26375
diff
changeset
|
249 case FLAC_STREAMINFO: |
26373 | 250 case FLAC_PADDING: |
251 case FLAC_APPLICATION: | |
26376
68302d38e153
Remove another two useless special-case from flac metadata reading function
reimar
parents:
26375
diff
changeset
|
252 case FLAC_SEEKTABLE: |
17898
a2b85171b4de
retrieve metadata from FLAC files (patch by Benjamin Zores < ben _at_ geexbox.org >)
aurel
parents:
17790
diff
changeset
|
253 case FLAC_CUESHEET: |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
254 default: |
17898
a2b85171b4de
retrieve metadata from FLAC files (patch by Benjamin Zores < ben _at_ geexbox.org >)
aurel
parents:
17790
diff
changeset
|
255 /* 6-127 are presently reserved */ |
a2b85171b4de
retrieve metadata from FLAC files (patch by Benjamin Zores < ben _at_ geexbox.org >)
aurel
parents:
17790
diff
changeset
|
256 stream_skip (s, blk_len); |
a2b85171b4de
retrieve metadata from FLAC files (patch by Benjamin Zores < ben _at_ geexbox.org >)
aurel
parents:
17790
diff
changeset
|
257 break; |
a2b85171b4de
retrieve metadata from FLAC files (patch by Benjamin Zores < ben _at_ geexbox.org >)
aurel
parents:
17790
diff
changeset
|
258 } |
a2b85171b4de
retrieve metadata from FLAC files (patch by Benjamin Zores < ben _at_ geexbox.org >)
aurel
parents:
17790
diff
changeset
|
259 } while ((preamble[0] & 0x80) == 0); |
a2b85171b4de
retrieve metadata from FLAC files (patch by Benjamin Zores < ben _at_ geexbox.org >)
aurel
parents:
17790
diff
changeset
|
260 } |
25890
374816d4d565
Disable reading of flac metadata, mere metadata is not worth such a mess.
reimar
parents:
25889
diff
changeset
|
261 #endif |
17898
a2b85171b4de
retrieve metadata from FLAC files (patch by Benjamin Zores < ben _at_ geexbox.org >)
aurel
parents:
17790
diff
changeset
|
262 |
34185
05306b88b675
Fix wrong runtime and average bitrate for VBR (variable bitrate) MP3.
ib
parents:
34184
diff
changeset
|
263 /** |
05306b88b675
Fix wrong runtime and average bitrate for VBR (variable bitrate) MP3.
ib
parents:
34184
diff
changeset
|
264 * @brief Determine the number of frames of a file encoded with |
05306b88b675
Fix wrong runtime and average bitrate for VBR (variable bitrate) MP3.
ib
parents:
34184
diff
changeset
|
265 * variable bitrate mode (VBR). |
05306b88b675
Fix wrong runtime and average bitrate for VBR (variable bitrate) MP3.
ib
parents:
34184
diff
changeset
|
266 * |
05306b88b675
Fix wrong runtime and average bitrate for VBR (variable bitrate) MP3.
ib
parents:
34184
diff
changeset
|
267 * @param s stream to be read |
05306b88b675
Fix wrong runtime and average bitrate for VBR (variable bitrate) MP3.
ib
parents:
34184
diff
changeset
|
268 * @param off offset in stream to start reading from |
05306b88b675
Fix wrong runtime and average bitrate for VBR (variable bitrate) MP3.
ib
parents:
34184
diff
changeset
|
269 * |
05306b88b675
Fix wrong runtime and average bitrate for VBR (variable bitrate) MP3.
ib
parents:
34184
diff
changeset
|
270 * @return 0 (error or no variable bitrate mode) or number of frames |
05306b88b675
Fix wrong runtime and average bitrate for VBR (variable bitrate) MP3.
ib
parents:
34184
diff
changeset
|
271 */ |
05306b88b675
Fix wrong runtime and average bitrate for VBR (variable bitrate) MP3.
ib
parents:
34184
diff
changeset
|
272 static unsigned int mp3_vbr_frames(stream_t *s, off_t off) { |
05306b88b675
Fix wrong runtime and average bitrate for VBR (variable bitrate) MP3.
ib
parents:
34184
diff
changeset
|
273 static const int xing_offset[2][2] = {{32, 17}, {17, 9}}; |
05306b88b675
Fix wrong runtime and average bitrate for VBR (variable bitrate) MP3.
ib
parents:
34184
diff
changeset
|
274 unsigned int data; |
05306b88b675
Fix wrong runtime and average bitrate for VBR (variable bitrate) MP3.
ib
parents:
34184
diff
changeset
|
275 unsigned char hdr[4]; |
05306b88b675
Fix wrong runtime and average bitrate for VBR (variable bitrate) MP3.
ib
parents:
34184
diff
changeset
|
276 int framesize, chans, spf, layer; |
05306b88b675
Fix wrong runtime and average bitrate for VBR (variable bitrate) MP3.
ib
parents:
34184
diff
changeset
|
277 |
05306b88b675
Fix wrong runtime and average bitrate for VBR (variable bitrate) MP3.
ib
parents:
34184
diff
changeset
|
278 if ((s->flags & MP_STREAM_SEEK) == MP_STREAM_SEEK) { |
05306b88b675
Fix wrong runtime and average bitrate for VBR (variable bitrate) MP3.
ib
parents:
34184
diff
changeset
|
279 |
05306b88b675
Fix wrong runtime and average bitrate for VBR (variable bitrate) MP3.
ib
parents:
34184
diff
changeset
|
280 if (!stream_seek(s, off)) return 0; |
05306b88b675
Fix wrong runtime and average bitrate for VBR (variable bitrate) MP3.
ib
parents:
34184
diff
changeset
|
281 |
05306b88b675
Fix wrong runtime and average bitrate for VBR (variable bitrate) MP3.
ib
parents:
34184
diff
changeset
|
282 data = stream_read_dword(s); |
05306b88b675
Fix wrong runtime and average bitrate for VBR (variable bitrate) MP3.
ib
parents:
34184
diff
changeset
|
283 hdr[0] = data >> 24; |
05306b88b675
Fix wrong runtime and average bitrate for VBR (variable bitrate) MP3.
ib
parents:
34184
diff
changeset
|
284 hdr[1] = data >> 16; |
05306b88b675
Fix wrong runtime and average bitrate for VBR (variable bitrate) MP3.
ib
parents:
34184
diff
changeset
|
285 hdr[2] = data >> 8; |
05306b88b675
Fix wrong runtime and average bitrate for VBR (variable bitrate) MP3.
ib
parents:
34184
diff
changeset
|
286 hdr[3] = data; |
05306b88b675
Fix wrong runtime and average bitrate for VBR (variable bitrate) MP3.
ib
parents:
34184
diff
changeset
|
287 |
05306b88b675
Fix wrong runtime and average bitrate for VBR (variable bitrate) MP3.
ib
parents:
34184
diff
changeset
|
288 if (!mp_check_mp3_header(data)) return 0; |
05306b88b675
Fix wrong runtime and average bitrate for VBR (variable bitrate) MP3.
ib
parents:
34184
diff
changeset
|
289 |
05306b88b675
Fix wrong runtime and average bitrate for VBR (variable bitrate) MP3.
ib
parents:
34184
diff
changeset
|
290 framesize = mp_get_mp3_header(hdr, &chans, NULL, &spf, &layer, NULL); |
05306b88b675
Fix wrong runtime and average bitrate for VBR (variable bitrate) MP3.
ib
parents:
34184
diff
changeset
|
291 |
05306b88b675
Fix wrong runtime and average bitrate for VBR (variable bitrate) MP3.
ib
parents:
34184
diff
changeset
|
292 if (framesize == -1 || layer != 3) return 0; |
05306b88b675
Fix wrong runtime and average bitrate for VBR (variable bitrate) MP3.
ib
parents:
34184
diff
changeset
|
293 |
05306b88b675
Fix wrong runtime and average bitrate for VBR (variable bitrate) MP3.
ib
parents:
34184
diff
changeset
|
294 /* Xing / Info (at variable position: 32, 17 or 9 bytes after header) */ |
05306b88b675
Fix wrong runtime and average bitrate for VBR (variable bitrate) MP3.
ib
parents:
34184
diff
changeset
|
295 |
05306b88b675
Fix wrong runtime and average bitrate for VBR (variable bitrate) MP3.
ib
parents:
34184
diff
changeset
|
296 if (!stream_skip(s, xing_offset[spf < 1152][chans == 1])) return 0; |
05306b88b675
Fix wrong runtime and average bitrate for VBR (variable bitrate) MP3.
ib
parents:
34184
diff
changeset
|
297 |
05306b88b675
Fix wrong runtime and average bitrate for VBR (variable bitrate) MP3.
ib
parents:
34184
diff
changeset
|
298 data = stream_read_dword(s); |
05306b88b675
Fix wrong runtime and average bitrate for VBR (variable bitrate) MP3.
ib
parents:
34184
diff
changeset
|
299 |
05306b88b675
Fix wrong runtime and average bitrate for VBR (variable bitrate) MP3.
ib
parents:
34184
diff
changeset
|
300 if (data == MKBETAG('X','i','n','g') || data == MKBETAG('I','n','f','o')) { |
05306b88b675
Fix wrong runtime and average bitrate for VBR (variable bitrate) MP3.
ib
parents:
34184
diff
changeset
|
301 data = stream_read_dword(s); |
05306b88b675
Fix wrong runtime and average bitrate for VBR (variable bitrate) MP3.
ib
parents:
34184
diff
changeset
|
302 |
05306b88b675
Fix wrong runtime and average bitrate for VBR (variable bitrate) MP3.
ib
parents:
34184
diff
changeset
|
303 if (data & 0x1) // frames field is present |
05306b88b675
Fix wrong runtime and average bitrate for VBR (variable bitrate) MP3.
ib
parents:
34184
diff
changeset
|
304 return stream_read_dword(s); // frames |
05306b88b675
Fix wrong runtime and average bitrate for VBR (variable bitrate) MP3.
ib
parents:
34184
diff
changeset
|
305 } |
05306b88b675
Fix wrong runtime and average bitrate for VBR (variable bitrate) MP3.
ib
parents:
34184
diff
changeset
|
306 |
05306b88b675
Fix wrong runtime and average bitrate for VBR (variable bitrate) MP3.
ib
parents:
34184
diff
changeset
|
307 /* VBRI (at fixed position: 32 bytes after header) */ |
05306b88b675
Fix wrong runtime and average bitrate for VBR (variable bitrate) MP3.
ib
parents:
34184
diff
changeset
|
308 |
05306b88b675
Fix wrong runtime and average bitrate for VBR (variable bitrate) MP3.
ib
parents:
34184
diff
changeset
|
309 if (!stream_seek(s, off + 4 + 32)) return 0; |
05306b88b675
Fix wrong runtime and average bitrate for VBR (variable bitrate) MP3.
ib
parents:
34184
diff
changeset
|
310 |
05306b88b675
Fix wrong runtime and average bitrate for VBR (variable bitrate) MP3.
ib
parents:
34184
diff
changeset
|
311 data = stream_read_dword(s); |
05306b88b675
Fix wrong runtime and average bitrate for VBR (variable bitrate) MP3.
ib
parents:
34184
diff
changeset
|
312 |
05306b88b675
Fix wrong runtime and average bitrate for VBR (variable bitrate) MP3.
ib
parents:
34184
diff
changeset
|
313 if (data == MKBETAG('V','B','R','I')) { |
05306b88b675
Fix wrong runtime and average bitrate for VBR (variable bitrate) MP3.
ib
parents:
34184
diff
changeset
|
314 data = stream_read_word(s); |
05306b88b675
Fix wrong runtime and average bitrate for VBR (variable bitrate) MP3.
ib
parents:
34184
diff
changeset
|
315 |
05306b88b675
Fix wrong runtime and average bitrate for VBR (variable bitrate) MP3.
ib
parents:
34184
diff
changeset
|
316 if (data == 1) { // check version |
05306b88b675
Fix wrong runtime and average bitrate for VBR (variable bitrate) MP3.
ib
parents:
34184
diff
changeset
|
317 if (!stream_skip(s, 8)) return 0; // skip delay, quality and bytes |
05306b88b675
Fix wrong runtime and average bitrate for VBR (variable bitrate) MP3.
ib
parents:
34184
diff
changeset
|
318 return stream_read_dword(s); // frames |
05306b88b675
Fix wrong runtime and average bitrate for VBR (variable bitrate) MP3.
ib
parents:
34184
diff
changeset
|
319 } |
05306b88b675
Fix wrong runtime and average bitrate for VBR (variable bitrate) MP3.
ib
parents:
34184
diff
changeset
|
320 } |
05306b88b675
Fix wrong runtime and average bitrate for VBR (variable bitrate) MP3.
ib
parents:
34184
diff
changeset
|
321 } |
05306b88b675
Fix wrong runtime and average bitrate for VBR (variable bitrate) MP3.
ib
parents:
34184
diff
changeset
|
322 |
05306b88b675
Fix wrong runtime and average bitrate for VBR (variable bitrate) MP3.
ib
parents:
34184
diff
changeset
|
323 return 0; |
05306b88b675
Fix wrong runtime and average bitrate for VBR (variable bitrate) MP3.
ib
parents:
34184
diff
changeset
|
324 } |
05306b88b675
Fix wrong runtime and average bitrate for VBR (variable bitrate) MP3.
ib
parents:
34184
diff
changeset
|
325 |
34631
fde6f34c5eb0
Detect ID3v2 tag at the end of the file and stop demuxing before
reimar
parents:
34630
diff
changeset
|
326 /** |
fde6f34c5eb0
Detect ID3v2 tag at the end of the file and stop demuxing before
reimar
parents:
34630
diff
changeset
|
327 * @brief Determine the total size of an ID3v2 tag. |
fde6f34c5eb0
Detect ID3v2 tag at the end of the file and stop demuxing before
reimar
parents:
34630
diff
changeset
|
328 * |
fde6f34c5eb0
Detect ID3v2 tag at the end of the file and stop demuxing before
reimar
parents:
34630
diff
changeset
|
329 * @param maj_ver major version of the ID3v2 tag |
fde6f34c5eb0
Detect ID3v2 tag at the end of the file and stop demuxing before
reimar
parents:
34630
diff
changeset
|
330 * @param s stream to be read, assumed to be positioned at revision byte |
fde6f34c5eb0
Detect ID3v2 tag at the end of the file and stop demuxing before
reimar
parents:
34630
diff
changeset
|
331 * |
fde6f34c5eb0
Detect ID3v2 tag at the end of the file and stop demuxing before
reimar
parents:
34630
diff
changeset
|
332 * @return 0 (error or malformed tag) or tag size |
fde6f34c5eb0
Detect ID3v2 tag at the end of the file and stop demuxing before
reimar
parents:
34630
diff
changeset
|
333 */ |
fde6f34c5eb0
Detect ID3v2 tag at the end of the file and stop demuxing before
reimar
parents:
34630
diff
changeset
|
334 static unsigned int id3v2_tag_size(uint8_t maj_ver, stream_t *s) { |
fde6f34c5eb0
Detect ID3v2 tag at the end of the file and stop demuxing before
reimar
parents:
34630
diff
changeset
|
335 unsigned int header_footer_size; |
fde6f34c5eb0
Detect ID3v2 tag at the end of the file and stop demuxing before
reimar
parents:
34630
diff
changeset
|
336 unsigned int size; |
fde6f34c5eb0
Detect ID3v2 tag at the end of the file and stop demuxing before
reimar
parents:
34630
diff
changeset
|
337 int i; |
fde6f34c5eb0
Detect ID3v2 tag at the end of the file and stop demuxing before
reimar
parents:
34630
diff
changeset
|
338 |
fde6f34c5eb0
Detect ID3v2 tag at the end of the file and stop demuxing before
reimar
parents:
34630
diff
changeset
|
339 if(stream_read_char(s) == 0xff) |
fde6f34c5eb0
Detect ID3v2 tag at the end of the file and stop demuxing before
reimar
parents:
34630
diff
changeset
|
340 return 0; |
fde6f34c5eb0
Detect ID3v2 tag at the end of the file and stop demuxing before
reimar
parents:
34630
diff
changeset
|
341 header_footer_size = ((stream_read_char(s) & 0x10) && maj_ver >= 4) ? 20 : 10; |
fde6f34c5eb0
Detect ID3v2 tag at the end of the file and stop demuxing before
reimar
parents:
34630
diff
changeset
|
342 |
fde6f34c5eb0
Detect ID3v2 tag at the end of the file and stop demuxing before
reimar
parents:
34630
diff
changeset
|
343 size = 0; |
fde6f34c5eb0
Detect ID3v2 tag at the end of the file and stop demuxing before
reimar
parents:
34630
diff
changeset
|
344 for(i = 0; i < 4; i++) { |
fde6f34c5eb0
Detect ID3v2 tag at the end of the file and stop demuxing before
reimar
parents:
34630
diff
changeset
|
345 uint8_t data = stream_read_char(s); |
fde6f34c5eb0
Detect ID3v2 tag at the end of the file and stop demuxing before
reimar
parents:
34630
diff
changeset
|
346 if (data & 0x80) |
fde6f34c5eb0
Detect ID3v2 tag at the end of the file and stop demuxing before
reimar
parents:
34630
diff
changeset
|
347 return 0; |
fde6f34c5eb0
Detect ID3v2 tag at the end of the file and stop demuxing before
reimar
parents:
34630
diff
changeset
|
348 size = size << 7 | data; |
fde6f34c5eb0
Detect ID3v2 tag at the end of the file and stop demuxing before
reimar
parents:
34630
diff
changeset
|
349 } |
fde6f34c5eb0
Detect ID3v2 tag at the end of the file and stop demuxing before
reimar
parents:
34630
diff
changeset
|
350 |
fde6f34c5eb0
Detect ID3v2 tag at the end of the file and stop demuxing before
reimar
parents:
34630
diff
changeset
|
351 return header_footer_size + size; |
fde6f34c5eb0
Detect ID3v2 tag at the end of the file and stop demuxing before
reimar
parents:
34630
diff
changeset
|
352 } |
fde6f34c5eb0
Detect ID3v2 tag at the end of the file and stop demuxing before
reimar
parents:
34630
diff
changeset
|
353 |
16175 | 354 static int demux_audio_open(demuxer_t* demuxer) { |
4694 | 355 stream_t *s; |
356 sh_audio_t* sh_audio; | |
357 uint8_t hdr[HDR_SIZE]; | |
16162
b5c2254d13f8
set i_bps in demux_audio for WAV and MP3 to avoid division by zero before
reimar
parents:
15215
diff
changeset
|
358 int frmt = 0, n = 0, step; |
13503
f8347c521898
better, tuneable (via #define) MP3 detection, limit demux_audio to scanning
reimar
parents:
13357
diff
changeset
|
359 off_t st_pos = 0, next_frame_pos = 0; |
f8347c521898
better, tuneable (via #define) MP3 detection, limit demux_audio to scanning
reimar
parents:
13357
diff
changeset
|
360 // mp3_hdrs list is sorted first by next_frame_pos and then by frame_pos |
f8347c521898
better, tuneable (via #define) MP3 detection, limit demux_audio to scanning
reimar
parents:
13357
diff
changeset
|
361 mp3_hdr_t *mp3_hdrs = NULL, *mp3_found = NULL; |
4694 | 362 da_priv_t* priv; |
34185
05306b88b675
Fix wrong runtime and average bitrate for VBR (variable bitrate) MP3.
ib
parents:
34184
diff
changeset
|
363 double duration; |
34255
1802d9d74c26
Make WAV format detection more restrictive so it does not incorrectly
reimar
parents:
34185
diff
changeset
|
364 int found_WAVE = 0; |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
365 |
4694 | 366 s = demuxer->stream; |
367 | |
13503
f8347c521898
better, tuneable (via #define) MP3 detection, limit demux_audio to scanning
reimar
parents:
13357
diff
changeset
|
368 stream_read(s, hdr, HDR_SIZE); |
f8347c521898
better, tuneable (via #define) MP3 detection, limit demux_audio to scanning
reimar
parents:
13357
diff
changeset
|
369 while(n < 30000 && !s->eof) { |
16162
b5c2254d13f8
set i_bps in demux_audio for WAV and MP3 to avoid division by zero before
reimar
parents:
15215
diff
changeset
|
370 int mp3_freq, mp3_chans, mp3_flen, mpa_layer, mpa_spf, mpa_br; |
13503
f8347c521898
better, tuneable (via #define) MP3 detection, limit demux_audio to scanning
reimar
parents:
13357
diff
changeset
|
371 st_pos = stream_tell(s) - HDR_SIZE; |
4694 | 372 step = 1; |
373 | |
374 if( hdr[0] == 'R' && hdr[1] == 'I' && hdr[2] == 'F' && hdr[3] == 'F' ) { | |
375 stream_skip(s,4); | |
376 if(s->eof) | |
377 break; | |
378 stream_read(s,hdr,4); | |
379 if(s->eof) | |
380 break; | |
381 if(hdr[0] != 'W' || hdr[1] != 'A' || hdr[2] != 'V' || hdr[3] != 'E' ) | |
382 stream_skip(s,-8); | |
383 else | |
384 // We found wav header. Now we can have 'fmt ' or a mp3 header | |
385 // empty the buffer | |
386 step = 4; | |
34631
fde6f34c5eb0
Detect ID3v2 tag at the end of the file and stop demuxing before
reimar
parents:
34630
diff
changeset
|
387 } else if( hdr[0] == 'I' && hdr[1] == 'D' && hdr[2] == '3' && hdr[3] >= 2 && hdr[3] != 0xff) { |
fde6f34c5eb0
Detect ID3v2 tag at the end of the file and stop demuxing before
reimar
parents:
34630
diff
changeset
|
388 unsigned int len = id3v2_tag_size(hdr[3], s); |
fde6f34c5eb0
Detect ID3v2 tag at the end of the file and stop demuxing before
reimar
parents:
34630
diff
changeset
|
389 if(len > 0) |
fde6f34c5eb0
Detect ID3v2 tag at the end of the file and stop demuxing before
reimar
parents:
34630
diff
changeset
|
390 stream_skip(s,len-10); |
8116 | 391 step = 4; |
34255
1802d9d74c26
Make WAV format detection more restrictive so it does not incorrectly
reimar
parents:
34185
diff
changeset
|
392 } else if( found_WAVE && hdr[0] == 'f' && hdr[1] == 'm' && hdr[2] == 't' && hdr[3] == ' ' ) { |
4694 | 393 frmt = WAV; |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
394 break; |
16162
b5c2254d13f8
set i_bps in demux_audio for WAV and MP3 to avoid division by zero before
reimar
parents:
15215
diff
changeset
|
395 } else if((mp3_flen = mp_get_mp3_header(hdr, &mp3_chans, &mp3_freq, |
b5c2254d13f8
set i_bps in demux_audio for WAV and MP3 to avoid division by zero before
reimar
parents:
15215
diff
changeset
|
396 &mpa_spf, &mpa_layer, &mpa_br)) > 0) { |
b5c2254d13f8
set i_bps in demux_audio for WAV and MP3 to avoid division by zero before
reimar
parents:
15215
diff
changeset
|
397 mp3_found = add_mp3_hdr(&mp3_hdrs, st_pos, mp3_chans, mp3_freq, |
b5c2254d13f8
set i_bps in demux_audio for WAV and MP3 to avoid division by zero before
reimar
parents:
15215
diff
changeset
|
398 mpa_spf, mpa_layer, mpa_br, mp3_flen); |
13503
f8347c521898
better, tuneable (via #define) MP3 detection, limit demux_audio to scanning
reimar
parents:
13357
diff
changeset
|
399 if (mp3_found) { |
f8347c521898
better, tuneable (via #define) MP3 detection, limit demux_audio to scanning
reimar
parents:
13357
diff
changeset
|
400 frmt = MP3; |
f8347c521898
better, tuneable (via #define) MP3 detection, limit demux_audio to scanning
reimar
parents:
13357
diff
changeset
|
401 break; |
f8347c521898
better, tuneable (via #define) MP3 detection, limit demux_audio to scanning
reimar
parents:
13357
diff
changeset
|
402 } |
11004 | 403 } else if( hdr[0] == 'f' && hdr[1] == 'L' && hdr[2] == 'a' && hdr[3] == 'C' ) { |
404 frmt = fLaC; | |
26812
811d717b722e
Continue detection if it is not clear if we have a MP3 or flac file.
reimar
parents:
26376
diff
changeset
|
405 if (!mp3_hdrs || mp3_hdrs->cons_hdrs < 3) |
811d717b722e
Continue detection if it is not clear if we have a MP3 or flac file.
reimar
parents:
26376
diff
changeset
|
406 break; |
4694 | 407 } |
34255
1802d9d74c26
Make WAV format detection more restrictive so it does not incorrectly
reimar
parents:
34185
diff
changeset
|
408 found_WAVE = hdr[0] == 'W' && hdr[1] == 'A' && hdr[2] == 'V' && hdr[3] == 'E'; |
4694 | 409 // Add here some other audio format detection |
410 if(step < HDR_SIZE) | |
411 memmove(hdr,&hdr[step],HDR_SIZE-step); | |
13503
f8347c521898
better, tuneable (via #define) MP3 detection, limit demux_audio to scanning
reimar
parents:
13357
diff
changeset
|
412 stream_read(s, &hdr[HDR_SIZE - step], step); |
f8347c521898
better, tuneable (via #define) MP3 detection, limit demux_audio to scanning
reimar
parents:
13357
diff
changeset
|
413 n++; |
4694 | 414 } |
415 | |
13503
f8347c521898
better, tuneable (via #define) MP3 detection, limit demux_audio to scanning
reimar
parents:
13357
diff
changeset
|
416 free_mp3_hdrs(&mp3_hdrs); |
f8347c521898
better, tuneable (via #define) MP3 detection, limit demux_audio to scanning
reimar
parents:
13357
diff
changeset
|
417 |
4694 | 418 if(!frmt) |
419 return 0; | |
420 | |
31609
cd81fce1f010
Make the stream language an argument to the stream creation function
reimar
parents:
31418
diff
changeset
|
421 sh_audio = new_sh_audio(demuxer,0, NULL); |
4694 | 422 |
423 switch(frmt) { | |
424 case MP3: | |
16162
b5c2254d13f8
set i_bps in demux_audio for WAV and MP3 to avoid division by zero before
reimar
parents:
15215
diff
changeset
|
425 sh_audio->format = (mp3_found->mpa_layer < 3 ? 0x50 : 0x55); |
13503
f8347c521898
better, tuneable (via #define) MP3 detection, limit demux_audio to scanning
reimar
parents:
13357
diff
changeset
|
426 demuxer->movi_start = mp3_found->frame_pos; |
34184 | 427 demuxer->movi_end = s->end_pos; |
13503
f8347c521898
better, tuneable (via #define) MP3 detection, limit demux_audio to scanning
reimar
parents:
13357
diff
changeset
|
428 next_frame_pos = mp3_found->next_frame_pos; |
6763 | 429 sh_audio->audio.dwSampleSize= 0; |
16162
b5c2254d13f8
set i_bps in demux_audio for WAV and MP3 to avoid division by zero before
reimar
parents:
15215
diff
changeset
|
430 sh_audio->audio.dwScale = mp3_found->mpa_spf; |
13503
f8347c521898
better, tuneable (via #define) MP3 detection, limit demux_audio to scanning
reimar
parents:
13357
diff
changeset
|
431 sh_audio->audio.dwRate = mp3_found->mp3_freq; |
32111 | 432 sh_audio->wf = malloc(sizeof(*sh_audio->wf)); |
6763 | 433 sh_audio->wf->wFormatTag = sh_audio->format; |
13503
f8347c521898
better, tuneable (via #define) MP3 detection, limit demux_audio to scanning
reimar
parents:
13357
diff
changeset
|
434 sh_audio->wf->nChannels = mp3_found->mp3_chans; |
f8347c521898
better, tuneable (via #define) MP3 detection, limit demux_audio to scanning
reimar
parents:
13357
diff
changeset
|
435 sh_audio->wf->nSamplesPerSec = mp3_found->mp3_freq; |
16162
b5c2254d13f8
set i_bps in demux_audio for WAV and MP3 to avoid division by zero before
reimar
parents:
15215
diff
changeset
|
436 sh_audio->wf->nAvgBytesPerSec = mp3_found->mpa_br * (1000 / 8); |
b5c2254d13f8
set i_bps in demux_audio for WAV and MP3 to avoid division by zero before
reimar
parents:
15215
diff
changeset
|
437 sh_audio->wf->nBlockAlign = mp3_found->mpa_spf; |
6763 | 438 sh_audio->wf->wBitsPerSample = 16; |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
439 sh_audio->wf->cbSize = 0; |
34185
05306b88b675
Fix wrong runtime and average bitrate for VBR (variable bitrate) MP3.
ib
parents:
34184
diff
changeset
|
440 duration = (double) mp3_vbr_frames(s, demuxer->movi_start) * mp3_found->mpa_spf / mp3_found->mp3_freq; |
13503
f8347c521898
better, tuneable (via #define) MP3 detection, limit demux_audio to scanning
reimar
parents:
13357
diff
changeset
|
441 free(mp3_found); |
f8347c521898
better, tuneable (via #define) MP3 detection, limit demux_audio to scanning
reimar
parents:
13357
diff
changeset
|
442 mp3_found = NULL; |
34826
26d77af0f13a
Add some additional checks to ensure subtractions do not overflow.
reimar
parents:
34631
diff
changeset
|
443 if(demuxer->movi_end && (s->flags & MP_STREAM_SEEK) == MP_STREAM_SEEK) { |
26d77af0f13a
Add some additional checks to ensure subtractions do not overflow.
reimar
parents:
34631
diff
changeset
|
444 if(demuxer->movi_end >= 128) { |
26d77af0f13a
Add some additional checks to ensure subtractions do not overflow.
reimar
parents:
34631
diff
changeset
|
445 stream_seek(s,demuxer->movi_end-128); |
34630 | 446 stream_read(s,hdr,3); |
447 if(!memcmp(hdr,"TAG",3)) { | |
4694 | 448 char buf[31]; |
449 uint8_t g; | |
34826
26d77af0f13a
Add some additional checks to ensure subtractions do not overflow.
reimar
parents:
34631
diff
changeset
|
450 demuxer->movi_end -= 128; |
4694 | 451 stream_read(s,buf,30); |
452 buf[30] = '\0'; | |
453 demux_info_add(demuxer,"Title",buf); | |
454 stream_read(s,buf,30); | |
455 buf[30] = '\0'; | |
456 demux_info_add(demuxer,"Artist",buf); | |
457 stream_read(s,buf,30); | |
458 buf[30] = '\0'; | |
459 demux_info_add(demuxer,"Album",buf); | |
460 stream_read(s,buf,4); | |
4764
9579496a91db
Added pts for mp3 and wav. And perfect seeking for mp3, unless flags & 2
albeu
parents:
4720
diff
changeset
|
461 buf[4] = '\0'; |
4694 | 462 demux_info_add(demuxer,"Year",buf); |
463 stream_read(s,buf,30); | |
464 buf[30] = '\0'; | |
465 demux_info_add(demuxer,"Comment",buf); | |
466 if(buf[28] == 0 && buf[29] != 0) { | |
467 uint8_t trk = (uint8_t)buf[29]; | |
468 sprintf(buf,"%d",trk); | |
469 demux_info_add(demuxer,"Track",buf); | |
470 } | |
471 g = stream_read_char(s); | |
472 demux_info_add(demuxer,"Genre",genres[g]); | |
473 } | |
34826
26d77af0f13a
Add some additional checks to ensure subtractions do not overflow.
reimar
parents:
34631
diff
changeset
|
474 } |
26d77af0f13a
Add some additional checks to ensure subtractions do not overflow.
reimar
parents:
34631
diff
changeset
|
475 if(demuxer->movi_end >= 10) { |
34631
fde6f34c5eb0
Detect ID3v2 tag at the end of the file and stop demuxing before
reimar
parents:
34630
diff
changeset
|
476 stream_seek(s,demuxer->movi_end-10); |
fde6f34c5eb0
Detect ID3v2 tag at the end of the file and stop demuxing before
reimar
parents:
34630
diff
changeset
|
477 stream_read(s,hdr,4); |
fde6f34c5eb0
Detect ID3v2 tag at the end of the file and stop demuxing before
reimar
parents:
34630
diff
changeset
|
478 if(!memcmp(hdr,"3DI",3) && hdr[3] >= 4 && hdr[3] != 0xff) { |
fde6f34c5eb0
Detect ID3v2 tag at the end of the file and stop demuxing before
reimar
parents:
34630
diff
changeset
|
479 unsigned int len = id3v2_tag_size(hdr[3], s); |
fde6f34c5eb0
Detect ID3v2 tag at the end of the file and stop demuxing before
reimar
parents:
34630
diff
changeset
|
480 if(len > 0) { |
fde6f34c5eb0
Detect ID3v2 tag at the end of the file and stop demuxing before
reimar
parents:
34630
diff
changeset
|
481 if(len > demuxer->movi_end - demuxer->movi_start) { |
fde6f34c5eb0
Detect ID3v2 tag at the end of the file and stop demuxing before
reimar
parents:
34630
diff
changeset
|
482 mp_msg(MSGT_DEMUX,MSGL_WARN,MSGTR_MPDEMUX_AUDIO_BadID3v2TagSize,len); |
fde6f34c5eb0
Detect ID3v2 tag at the end of the file and stop demuxing before
reimar
parents:
34630
diff
changeset
|
483 len = FFMIN(10,demuxer->movi_end-demuxer->movi_start); |
fde6f34c5eb0
Detect ID3v2 tag at the end of the file and stop demuxing before
reimar
parents:
34630
diff
changeset
|
484 } else { |
fde6f34c5eb0
Detect ID3v2 tag at the end of the file and stop demuxing before
reimar
parents:
34630
diff
changeset
|
485 stream_seek(s,demuxer->movi_end-len); |
fde6f34c5eb0
Detect ID3v2 tag at the end of the file and stop demuxing before
reimar
parents:
34630
diff
changeset
|
486 stream_read(s,hdr,4); |
fde6f34c5eb0
Detect ID3v2 tag at the end of the file and stop demuxing before
reimar
parents:
34630
diff
changeset
|
487 if(memcmp(hdr,"ID3",3) || hdr[3] < 4 || hdr[3] == 0xff || id3v2_tag_size(hdr[3], s) != len) { |
fde6f34c5eb0
Detect ID3v2 tag at the end of the file and stop demuxing before
reimar
parents:
34630
diff
changeset
|
488 mp_msg(MSGT_DEMUX,MSGL_WARN,MSGTR_MPDEMUX_AUDIO_DamagedAppendedID3v2Tag); |
fde6f34c5eb0
Detect ID3v2 tag at the end of the file and stop demuxing before
reimar
parents:
34630
diff
changeset
|
489 len = FFMIN(10,demuxer->movi_end-demuxer->movi_start); |
fde6f34c5eb0
Detect ID3v2 tag at the end of the file and stop demuxing before
reimar
parents:
34630
diff
changeset
|
490 } |
fde6f34c5eb0
Detect ID3v2 tag at the end of the file and stop demuxing before
reimar
parents:
34630
diff
changeset
|
491 } |
fde6f34c5eb0
Detect ID3v2 tag at the end of the file and stop demuxing before
reimar
parents:
34630
diff
changeset
|
492 demuxer->movi_end -= len; |
fde6f34c5eb0
Detect ID3v2 tag at the end of the file and stop demuxing before
reimar
parents:
34630
diff
changeset
|
493 } |
fde6f34c5eb0
Detect ID3v2 tag at the end of the file and stop demuxing before
reimar
parents:
34630
diff
changeset
|
494 } |
4694 | 495 } |
34826
26d77af0f13a
Add some additional checks to ensure subtractions do not overflow.
reimar
parents:
34631
diff
changeset
|
496 } |
34185
05306b88b675
Fix wrong runtime and average bitrate for VBR (variable bitrate) MP3.
ib
parents:
34184
diff
changeset
|
497 if (duration && demuxer->movi_end && demuxer->movi_end > demuxer->movi_start) sh_audio->wf->nAvgBytesPerSec = (demuxer->movi_end - demuxer->movi_start) / duration; |
05306b88b675
Fix wrong runtime and average bitrate for VBR (variable bitrate) MP3.
ib
parents:
34184
diff
changeset
|
498 sh_audio->i_bps = sh_audio->wf->nAvgBytesPerSec; |
4694 | 499 break; |
500 case WAV: { | |
4720
10ad330c1733
fixed WAV demuxer so that it skips to the actual start of the audio data
melanson
parents:
4717
diff
changeset
|
501 unsigned int chunk_type; |
10ad330c1733
fixed WAV demuxer so that it skips to the actual start of the audio data
melanson
parents:
4717
diff
changeset
|
502 unsigned int chunk_size; |
4694 | 503 WAVEFORMATEX* w; |
504 int l; | |
505 l = stream_read_dword_le(s); | |
9596 | 506 if(l < 16) { |
9591
3904b95fce8f
Read extradata for wav files, based on patch by <dimakar(at)yahoo.com>. Required for truespeech files.
rtognimp
parents:
8359
diff
changeset
|
507 mp_msg(MSGT_DEMUX,MSGL_ERR,"[demux_audio] Bad wav header length: too short (%d)!!!\n",l); |
20334
5fcc8a3b1e88
Try playing files with wrong wav header length, fixes riff_broken_hrdlen.wav
reimar
parents:
19062
diff
changeset
|
508 l = 16; |
4694 | 509 } |
18074
a491d7628cdc
check wav header length against upper limit, should protect against
reimar
parents:
17977
diff
changeset
|
510 if(l > MAX_WAVHDR_LEN) { |
a491d7628cdc
check wav header length against upper limit, should protect against
reimar
parents:
17977
diff
changeset
|
511 mp_msg(MSGT_DEMUX,MSGL_ERR,"[demux_audio] Bad wav header length: too long (%d)!!!\n",l); |
20334
5fcc8a3b1e88
Try playing files with wrong wav header length, fixes riff_broken_hrdlen.wav
reimar
parents:
19062
diff
changeset
|
512 l = 16; |
18074
a491d7628cdc
check wav header length against upper limit, should protect against
reimar
parents:
17977
diff
changeset
|
513 } |
32111 | 514 sh_audio->wf = w = malloc(l > sizeof(*w) ? l : sizeof(*w)); |
4694 | 515 w->wFormatTag = sh_audio->format = stream_read_word_le(s); |
516 w->nChannels = sh_audio->channels = stream_read_word_le(s); | |
517 w->nSamplesPerSec = sh_audio->samplerate = stream_read_dword_le(s); | |
518 w->nAvgBytesPerSec = stream_read_dword_le(s); | |
519 w->nBlockAlign = stream_read_word_le(s); | |
22419
4cfb8def78c1
Fix wrong setting of samplesize (must be bytes per sample, not bits)
reimar
parents:
22103
diff
changeset
|
520 w->wBitsPerSample = stream_read_word_le(s); |
4cfb8def78c1
Fix wrong setting of samplesize (must be bytes per sample, not bits)
reimar
parents:
22103
diff
changeset
|
521 sh_audio->samplesize = (w->wBitsPerSample + 7) / 8; |
9616
a6bbab17a87f
10l cbSize not inited for l=16.\n Could give problem in print_wave_header
rtognimp
parents:
9596
diff
changeset
|
522 w->cbSize = 0; |
16162
b5c2254d13f8
set i_bps in demux_audio for WAV and MP3 to avoid division by zero before
reimar
parents:
15215
diff
changeset
|
523 sh_audio->i_bps = sh_audio->wf->nAvgBytesPerSec; |
9596 | 524 l -= 16; |
27217
28f249556ecc
Only read wav header cbSize when there is enough space in header.
reimar
parents:
27216
diff
changeset
|
525 if (l >= 2) { |
27243
e0641ed3cefd
100l, do not use macros on functions that are not idempotent
reimar
parents:
27218
diff
changeset
|
526 w->cbSize = stream_read_word_le(s); |
27215 | 527 l -= 2; |
9591
3904b95fce8f
Read extradata for wav files, based on patch by <dimakar(at)yahoo.com>. Required for truespeech files.
rtognimp
parents:
8359
diff
changeset
|
528 if (l < w->cbSize) { |
3904b95fce8f
Read extradata for wav files, based on patch by <dimakar(at)yahoo.com>. Required for truespeech files.
rtognimp
parents:
8359
diff
changeset
|
529 mp_msg(MSGT_DEMUX,MSGL_ERR,"[demux_audio] truncated extradata (%d < %d)\n", |
27215 | 530 l,w->cbSize); |
27216
b05556cd284d
100l, assignment introduced in r27246 was exactly the wrong way around.
reimar
parents:
27215
diff
changeset
|
531 w->cbSize = l; |
27214 | 532 } |
32111 | 533 stream_read(s,(char*)(w + 1),w->cbSize); |
27215 | 534 l -= w->cbSize; |
32551 | 535 if (w->wFormatTag == 0xfffe && w->cbSize >= 22) |
32550 | 536 sh_audio->format = av_le2ne16(((WAVEFORMATEXTENSIBLE *)w)->SubFormat); |
9596 | 537 } |
9591
3904b95fce8f
Read extradata for wav files, based on patch by <dimakar(at)yahoo.com>. Required for truespeech files.
rtognimp
parents:
8359
diff
changeset
|
538 |
17977
f70772d02eaa
Convert printfs in aviprint.c to mp_msg and give the information printing
diego
parents:
17932
diff
changeset
|
539 if( mp_msg_test(MSGT_DEMUX,MSGL_V) ) print_wave_header(w, MSGL_V); |
4694 | 540 if(l) |
541 stream_skip(s,l); | |
4720
10ad330c1733
fixed WAV demuxer so that it skips to the actual start of the audio data
melanson
parents:
4717
diff
changeset
|
542 do |
10ad330c1733
fixed WAV demuxer so that it skips to the actual start of the audio data
melanson
parents:
4717
diff
changeset
|
543 { |
10ad330c1733
fixed WAV demuxer so that it skips to the actual start of the audio data
melanson
parents:
4717
diff
changeset
|
544 chunk_type = stream_read_fourcc(demuxer->stream); |
10ad330c1733
fixed WAV demuxer so that it skips to the actual start of the audio data
melanson
parents:
4717
diff
changeset
|
545 chunk_size = stream_read_dword_le(demuxer->stream); |
10ad330c1733
fixed WAV demuxer so that it skips to the actual start of the audio data
melanson
parents:
4717
diff
changeset
|
546 if (chunk_type != mmioFOURCC('d', 'a', 't', 'a')) |
10ad330c1733
fixed WAV demuxer so that it skips to the actual start of the audio data
melanson
parents:
4717
diff
changeset
|
547 stream_skip(demuxer->stream, chunk_size); |
22586 | 548 } while (!s->eof && chunk_type != mmioFOURCC('d', 'a', 't', 'a')); |
4694 | 549 demuxer->movi_start = stream_tell(s); |
22103
0427f8190a12
Do not read beyond end of data chunk if chunk_size is set.
reimar
parents:
21651
diff
changeset
|
550 demuxer->movi_end = chunk_size ? demuxer->movi_start + chunk_size : s->end_pos; |
7847 | 551 // printf("wav: %X .. %X\n",(int)demuxer->movi_start,(int)demuxer->movi_end); |
13006 | 552 // Check if it contains dts audio |
553 if((w->wFormatTag == 0x01) && (w->nChannels == 2) && (w->nSamplesPerSec == 44100)) { | |
35246
db605820eef9
Remove completely unnecessary huge on-stack buffer.
reimar
parents:
35239
diff
changeset
|
554 uint32_t value = stream_read_dword(demuxer->stream); |
13006 | 555 unsigned int i; |
35246
db605820eef9
Remove completely unnecessary huge on-stack buffer.
reimar
parents:
35239
diff
changeset
|
556 // vlc uses 16384*4 (4 dts frames) |
db605820eef9
Remove completely unnecessary huge on-stack buffer.
reimar
parents:
35239
diff
changeset
|
557 for (i = 0; i < 16384; i += 2) { |
db605820eef9
Remove completely unnecessary huge on-stack buffer.
reimar
parents:
35239
diff
changeset
|
558 uint16_t next = stream_read_word(demuxer->stream); |
13006 | 559 // DTS, 14 bit, LE |
35246
db605820eef9
Remove completely unnecessary huge on-stack buffer.
reimar
parents:
35239
diff
changeset
|
560 if(value == 0xff1f00e8u && (next & 0xfeff) == 0xf007) { |
13006 | 561 sh_audio->format = 0x2001; |
562 mp_msg(MSGT_DEMUX,MSGL_V,"[demux_audio] DTS audio in wav, 14 bit, LE\n"); | |
563 break; | |
564 } | |
565 // DTS, 14 bit, BE | |
35246
db605820eef9
Remove completely unnecessary huge on-stack buffer.
reimar
parents:
35239
diff
changeset
|
566 if(value == 0x1fffe800u && (next & 0xfffe) == 0x07f0) { |
13006 | 567 sh_audio->format = 0x2001; |
568 mp_msg(MSGT_DEMUX,MSGL_V,"[demux_audio] DTS audio in wav, 14 bit, BE\n"); | |
569 break; | |
570 } | |
571 // DTS, 16 bit, BE | |
35246
db605820eef9
Remove completely unnecessary huge on-stack buffer.
reimar
parents:
35239
diff
changeset
|
572 if(value == 0x7ffe8001u) { |
13006 | 573 sh_audio->format = 0x2001; |
574 mp_msg(MSGT_DEMUX,MSGL_V,"[demux_audio] DTS audio in wav, 16 bit, BE\n"); | |
575 break; | |
576 } | |
577 // DTS, 16 bit, LE | |
35246
db605820eef9
Remove completely unnecessary huge on-stack buffer.
reimar
parents:
35239
diff
changeset
|
578 if(value == 0xfe7f0180u) { |
13006 | 579 sh_audio->format = 0x2001; |
580 mp_msg(MSGT_DEMUX,MSGL_V,"[demux_audio] DTS audio in wav, 16 bit, LE\n"); | |
581 break; | |
582 } | |
35246
db605820eef9
Remove completely unnecessary huge on-stack buffer.
reimar
parents:
35239
diff
changeset
|
583 value <<= 16; |
db605820eef9
Remove completely unnecessary huge on-stack buffer.
reimar
parents:
35239
diff
changeset
|
584 value |= next; |
13006 | 585 } |
32581 | 586 if (sh_audio->format == 0x2001) { |
13006 | 587 mp_msg(MSGT_DEMUX,MSGL_DBG2,"[demux_audio] DTS sync offset = %u\n", i); |
32581 | 588 } |
13006 | 589 |
590 } | |
34956 | 591 // All formats that have a parser will need it when stored in WAV |
592 sh_audio->needs_parsing = 1; | |
13006 | 593 stream_seek(s,demuxer->movi_start); |
4694 | 594 } break; |
11004 | 595 case fLaC: |
596 sh_audio->format = mmioFOURCC('f', 'L', 'a', 'C'); | |
18075
2373ed2ee546
try to detect flac bitrate early on to avoid division by zero problems.
reimar
parents:
18074
diff
changeset
|
597 demuxer->movi_start = stream_tell(s) - 4; |
11004 | 598 demuxer->movi_end = s->end_pos; |
18075
2373ed2ee546
try to detect flac bitrate early on to avoid division by zero problems.
reimar
parents:
18074
diff
changeset
|
599 if (demuxer->movi_end > demuxer->movi_start) { |
2373ed2ee546
try to detect flac bitrate early on to avoid division by zero problems.
reimar
parents:
18074
diff
changeset
|
600 // try to find out approx. bitrate |
2373ed2ee546
try to detect flac bitrate early on to avoid division by zero problems.
reimar
parents:
18074
diff
changeset
|
601 int64_t size = demuxer->movi_end - demuxer->movi_start; |
31619 | 602 int64_t num_samples; |
603 int32_t srate; | |
18075
2373ed2ee546
try to detect flac bitrate early on to avoid division by zero problems.
reimar
parents:
18074
diff
changeset
|
604 stream_skip(s, 14); |
31619 | 605 srate = stream_read_int24(s) >> 4; |
35375 | 606 num_samples = stream_read_char(s) & 0xf; |
607 num_samples <<= 32; | |
608 num_samples |= stream_read_dword(s); | |
18075
2373ed2ee546
try to detect flac bitrate early on to avoid division by zero problems.
reimar
parents:
18074
diff
changeset
|
609 if (num_samples && srate) |
2373ed2ee546
try to detect flac bitrate early on to avoid division by zero problems.
reimar
parents:
18074
diff
changeset
|
610 sh_audio->i_bps = size * srate / num_samples; |
2373ed2ee546
try to detect flac bitrate early on to avoid division by zero problems.
reimar
parents:
18074
diff
changeset
|
611 } |
2373ed2ee546
try to detect flac bitrate early on to avoid division by zero problems.
reimar
parents:
18074
diff
changeset
|
612 if (sh_audio->i_bps < 1) // guess value to prevent crash |
2373ed2ee546
try to detect flac bitrate early on to avoid division by zero problems.
reimar
parents:
18074
diff
changeset
|
613 sh_audio->i_bps = 64 * 1024; |
32590
10b9ac971ef6
Add support for FLAC audio parsing, fixes playback time jumping
reimar
parents:
32581
diff
changeset
|
614 sh_audio->needs_parsing = 1; |
25890
374816d4d565
Disable reading of flac metadata, mere metadata is not worth such a mess.
reimar
parents:
25889
diff
changeset
|
615 // get_flac_metadata (demuxer); |
11004 | 616 break; |
4694 | 617 } |
618 | |
19062
83c3afeab35d
drops casts from void * on malloc/calloc from libmpdemux code
reynaldo
parents:
18710
diff
changeset
|
619 priv = malloc(sizeof(da_priv_t)); |
4694 | 620 priv->frmt = frmt; |
24589 | 621 priv->next_pts = 0; |
4694 | 622 demuxer->priv = priv; |
623 demuxer->audio->id = 0; | |
624 demuxer->audio->sh = sh_audio; | |
625 sh_audio->ds = demuxer->audio; | |
10244
a084597140af
don't set audio pts to infinity after seeking in mp3 files :)
rfelker
parents:
9655
diff
changeset
|
626 sh_audio->samplerate = sh_audio->audio.dwRate; |
4694 | 627 |
628 if(stream_tell(s) != demuxer->movi_start) | |
13503
f8347c521898
better, tuneable (via #define) MP3 detection, limit demux_audio to scanning
reimar
parents:
13357
diff
changeset
|
629 { |
f8347c521898
better, tuneable (via #define) MP3 detection, limit demux_audio to scanning
reimar
parents:
13357
diff
changeset
|
630 mp_msg(MSGT_DEMUX, MSGL_V, "demux_audio: seeking from 0x%X to start pos 0x%X\n", |
f8347c521898
better, tuneable (via #define) MP3 detection, limit demux_audio to scanning
reimar
parents:
13357
diff
changeset
|
631 (int)stream_tell(s), (int)demuxer->movi_start); |
4694 | 632 stream_seek(s,demuxer->movi_start); |
13503
f8347c521898
better, tuneable (via #define) MP3 detection, limit demux_audio to scanning
reimar
parents:
13357
diff
changeset
|
633 if (stream_tell(s) != demuxer->movi_start) { |
f8347c521898
better, tuneable (via #define) MP3 detection, limit demux_audio to scanning
reimar
parents:
13357
diff
changeset
|
634 mp_msg(MSGT_DEMUX, MSGL_V, "demux_audio: seeking failed, now at 0x%X!\n", |
f8347c521898
better, tuneable (via #define) MP3 detection, limit demux_audio to scanning
reimar
parents:
13357
diff
changeset
|
635 (int)stream_tell(s)); |
f8347c521898
better, tuneable (via #define) MP3 detection, limit demux_audio to scanning
reimar
parents:
13357
diff
changeset
|
636 if (next_frame_pos) { |
f8347c521898
better, tuneable (via #define) MP3 detection, limit demux_audio to scanning
reimar
parents:
13357
diff
changeset
|
637 mp_msg(MSGT_DEMUX, MSGL_V, "demux_audio: seeking to 0x%X instead\n", |
f8347c521898
better, tuneable (via #define) MP3 detection, limit demux_audio to scanning
reimar
parents:
13357
diff
changeset
|
638 (int)next_frame_pos); |
f8347c521898
better, tuneable (via #define) MP3 detection, limit demux_audio to scanning
reimar
parents:
13357
diff
changeset
|
639 stream_seek(s, next_frame_pos); |
f8347c521898
better, tuneable (via #define) MP3 detection, limit demux_audio to scanning
reimar
parents:
13357
diff
changeset
|
640 } |
f8347c521898
better, tuneable (via #define) MP3 detection, limit demux_audio to scanning
reimar
parents:
13357
diff
changeset
|
641 } |
f8347c521898
better, tuneable (via #define) MP3 detection, limit demux_audio to scanning
reimar
parents:
13357
diff
changeset
|
642 } |
4694 | 643 |
13503
f8347c521898
better, tuneable (via #define) MP3 detection, limit demux_audio to scanning
reimar
parents:
13357
diff
changeset
|
644 mp_msg(MSGT_DEMUX,MSGL_V,"demux_audio: audio data 0x%X - 0x%X \n",(int)demuxer->movi_start,(int)demuxer->movi_end); |
4712 | 645 |
16175 | 646 return DEMUXER_TYPE_AUDIO; |
4694 | 647 } |
648 | |
649 | |
29635
c7d88fcfd784
Get rid of useless indirection and use the demuxer argument directly instead of
reimar
parents:
29263
diff
changeset
|
650 static int demux_audio_fill_buffer(demuxer_t *demux, demux_stream_t *ds) { |
14608
9595f1de1393
Fix possible hang when playing broken MP3 from linear stream and remove
reimar
parents:
13503
diff
changeset
|
651 int l; |
9595f1de1393
Fix possible hang when playing broken MP3 from linear stream and remove
reimar
parents:
13503
diff
changeset
|
652 demux_packet_t* dp; |
24592
664366177d29
Simplify: initialize at declaration at the start of the function
reimar
parents:
24591
diff
changeset
|
653 sh_audio_t* sh_audio = ds->sh; |
664366177d29
Simplify: initialize at declaration at the start of the function
reimar
parents:
24591
diff
changeset
|
654 da_priv_t* priv = demux->priv; |
664366177d29
Simplify: initialize at declaration at the start of the function
reimar
parents:
24591
diff
changeset
|
655 double this_pts = priv->next_pts; |
664366177d29
Simplify: initialize at declaration at the start of the function
reimar
parents:
24591
diff
changeset
|
656 stream_t* s = demux->stream; |
4694 | 657 |
16438
871e94131840
Ignore movi_end (except on error) to allow playing growing files.
reimar
parents:
16346
diff
changeset
|
658 if(s->eof) |
4694 | 659 return 0; |
660 | |
661 switch(priv->frmt) { | |
662 case MP3 : | |
14608
9595f1de1393
Fix possible hang when playing broken MP3 from linear stream and remove
reimar
parents:
13503
diff
changeset
|
663 while(1) { |
4694 | 664 uint8_t hdr[4]; |
665 stream_read(s,hdr,4); | |
16438
871e94131840
Ignore movi_end (except on error) to allow playing growing files.
reimar
parents:
16346
diff
changeset
|
666 if (s->eof) |
14608
9595f1de1393
Fix possible hang when playing broken MP3 from linear stream and remove
reimar
parents:
13503
diff
changeset
|
667 return 0; |
9595f1de1393
Fix possible hang when playing broken MP3 from linear stream and remove
reimar
parents:
13503
diff
changeset
|
668 l = mp_decode_mp3_header(hdr); |
9595f1de1393
Fix possible hang when playing broken MP3 from linear stream and remove
reimar
parents:
13503
diff
changeset
|
669 if(l < 0) { |
16438
871e94131840
Ignore movi_end (except on error) to allow playing growing files.
reimar
parents:
16346
diff
changeset
|
670 if (demux->movi_end && stream_tell(s) >= demux->movi_end) |
871e94131840
Ignore movi_end (except on error) to allow playing growing files.
reimar
parents:
16346
diff
changeset
|
671 return 0; // might be ID3 tag, i.e. EOF |
4694 | 672 stream_skip(s,-3); |
673 } else { | |
14608
9595f1de1393
Fix possible hang when playing broken MP3 from linear stream and remove
reimar
parents:
13503
diff
changeset
|
674 dp = new_demux_packet(l); |
4694 | 675 memcpy(dp->buffer,hdr,4); |
16438
871e94131840
Ignore movi_end (except on error) to allow playing growing files.
reimar
parents:
16346
diff
changeset
|
676 if (stream_read(s,dp->buffer + 4,l-4) != l-4) |
17790
99a2481164ac
fix leak on read error (forgot to free demux packet)
reimar
parents:
17775
diff
changeset
|
677 { |
99a2481164ac
fix leak on read error (forgot to free demux packet)
reimar
parents:
17775
diff
changeset
|
678 free_demux_packet(dp); |
16438
871e94131840
Ignore movi_end (except on error) to allow playing growing files.
reimar
parents:
16346
diff
changeset
|
679 return 0; |
17790
99a2481164ac
fix leak on read error (forgot to free demux packet)
reimar
parents:
17775
diff
changeset
|
680 } |
24589 | 681 priv->next_pts += sh_audio->audio.dwScale/(double)sh_audio->samplerate; |
14608
9595f1de1393
Fix possible hang when playing broken MP3 from linear stream and remove
reimar
parents:
13503
diff
changeset
|
682 break; |
4694 | 683 } |
4700
30131db5dfbb
Improved mp3 detection (don't detect mpeg1/2 as mp3 anymore)
albeu
parents:
4694
diff
changeset
|
684 } break; |
4694 | 685 case WAV : { |
17554 | 686 unsigned align = sh_audio->wf->nBlockAlign; |
14608
9595f1de1393
Fix possible hang when playing broken MP3 from linear stream and remove
reimar
parents:
13503
diff
changeset
|
687 l = sh_audio->wf->nAvgBytesPerSec; |
25772 | 688 if (l <= 0) l = 65536; |
22103
0427f8190a12
Do not read beyond end of data chunk if chunk_size is set.
reimar
parents:
21651
diff
changeset
|
689 if (demux->movi_end && l > demux->movi_end - stream_tell(s)) { |
0427f8190a12
Do not read beyond end of data chunk if chunk_size is set.
reimar
parents:
21651
diff
changeset
|
690 // do not read beyond end, there might be junk after data chunk |
0427f8190a12
Do not read beyond end of data chunk if chunk_size is set.
reimar
parents:
21651
diff
changeset
|
691 l = demux->movi_end - stream_tell(s); |
0427f8190a12
Do not read beyond end of data chunk if chunk_size is set.
reimar
parents:
21651
diff
changeset
|
692 if (l <= 0) return 0; |
0427f8190a12
Do not read beyond end of data chunk if chunk_size is set.
reimar
parents:
21651
diff
changeset
|
693 } |
17554 | 694 if (align) |
695 l = (l + align - 1) / align * align; | |
14608
9595f1de1393
Fix possible hang when playing broken MP3 from linear stream and remove
reimar
parents:
13503
diff
changeset
|
696 dp = new_demux_packet(l); |
10891
65ed62e138fa
Fixed 'reading after EOF'. demuxers didn't check, how many they've read!
lumag
parents:
10882
diff
changeset
|
697 l = stream_read(s,dp->buffer,l); |
24589 | 698 priv->next_pts += l/(double)sh_audio->i_bps; |
14608
9595f1de1393
Fix possible hang when playing broken MP3 from linear stream and remove
reimar
parents:
13503
diff
changeset
|
699 break; |
4694 | 700 } |
11004 | 701 case fLaC: { |
14608
9595f1de1393
Fix possible hang when playing broken MP3 from linear stream and remove
reimar
parents:
13503
diff
changeset
|
702 l = 65535; |
9595f1de1393
Fix possible hang when playing broken MP3 from linear stream and remove
reimar
parents:
13503
diff
changeset
|
703 dp = new_demux_packet(l); |
11004 | 704 l = stream_read(s,dp->buffer,l); |
32591
4cd3a8a22748
Do not generate nonsensical pts values for FLAC audio.
reimar
parents:
32590
diff
changeset
|
705 priv->next_pts = MP_NOPTS_VALUE; |
14608
9595f1de1393
Fix possible hang when playing broken MP3 from linear stream and remove
reimar
parents:
13503
diff
changeset
|
706 break; |
11004 | 707 } |
4694 | 708 default: |
18176
f72bc5754209
Part3 of Otvos Attila's oattila AT chello-hu mp_msg changes, with lots of modifications as usual
reynaldo
parents:
18117
diff
changeset
|
709 mp_msg(MSGT_DEMUXER,MSGL_WARN,MSGTR_MPDEMUX_AUDIO_UnknownFormat,priv->frmt); |
14608
9595f1de1393
Fix possible hang when playing broken MP3 from linear stream and remove
reimar
parents:
13503
diff
changeset
|
710 return 0; |
4694 | 711 } |
712 | |
14608
9595f1de1393
Fix possible hang when playing broken MP3 from linear stream and remove
reimar
parents:
13503
diff
changeset
|
713 resize_demux_packet(dp, l); |
24589 | 714 dp->pts = this_pts; |
14608
9595f1de1393
Fix possible hang when playing broken MP3 from linear stream and remove
reimar
parents:
13503
diff
changeset
|
715 ds_add_packet(ds, dp); |
9595f1de1393
Fix possible hang when playing broken MP3 from linear stream and remove
reimar
parents:
13503
diff
changeset
|
716 return 1; |
4694 | 717 } |
718 | |
4764
9579496a91db
Added pts for mp3 and wav. And perfect seeking for mp3, unless flags & 2
albeu
parents:
4720
diff
changeset
|
719 static void high_res_mp3_seek(demuxer_t *demuxer,float time) { |
9579496a91db
Added pts for mp3 and wav. And perfect seeking for mp3, unless flags & 2
albeu
parents:
4720
diff
changeset
|
720 uint8_t hdr[4]; |
9579496a91db
Added pts for mp3 and wav. And perfect seeking for mp3, unless flags & 2
albeu
parents:
4720
diff
changeset
|
721 int len,nf; |
9579496a91db
Added pts for mp3 and wav. And perfect seeking for mp3, unless flags & 2
albeu
parents:
4720
diff
changeset
|
722 da_priv_t* priv = demuxer->priv; |
9579496a91db
Added pts for mp3 and wav. And perfect seeking for mp3, unless flags & 2
albeu
parents:
4720
diff
changeset
|
723 sh_audio_t* sh = (sh_audio_t*)demuxer->audio->sh; |
9579496a91db
Added pts for mp3 and wav. And perfect seeking for mp3, unless flags & 2
albeu
parents:
4720
diff
changeset
|
724 |
15199
980910eb6f0c
assign correct tag, dwScale and dwBlockAlign to mpeg audio; optionally assign layer and samples_per_frame when parsing mpa header
nicodvb
parents:
14910
diff
changeset
|
725 nf = time*sh->samplerate/sh->audio.dwScale; |
4764
9579496a91db
Added pts for mp3 and wav. And perfect seeking for mp3, unless flags & 2
albeu
parents:
4720
diff
changeset
|
726 while(nf > 0) { |
9579496a91db
Added pts for mp3 and wav. And perfect seeking for mp3, unless flags & 2
albeu
parents:
4720
diff
changeset
|
727 stream_read(demuxer->stream,hdr,4); |
9579496a91db
Added pts for mp3 and wav. And perfect seeking for mp3, unless flags & 2
albeu
parents:
4720
diff
changeset
|
728 len = mp_decode_mp3_header(hdr); |
9579496a91db
Added pts for mp3 and wav. And perfect seeking for mp3, unless flags & 2
albeu
parents:
4720
diff
changeset
|
729 if(len < 0) { |
9579496a91db
Added pts for mp3 and wav. And perfect seeking for mp3, unless flags & 2
albeu
parents:
4720
diff
changeset
|
730 stream_skip(demuxer->stream,-3); |
9579496a91db
Added pts for mp3 and wav. And perfect seeking for mp3, unless flags & 2
albeu
parents:
4720
diff
changeset
|
731 continue; |
9579496a91db
Added pts for mp3 and wav. And perfect seeking for mp3, unless flags & 2
albeu
parents:
4720
diff
changeset
|
732 } |
9579496a91db
Added pts for mp3 and wav. And perfect seeking for mp3, unless flags & 2
albeu
parents:
4720
diff
changeset
|
733 stream_skip(demuxer->stream,len-4); |
24589 | 734 priv->next_pts += sh->audio.dwScale/(double)sh->samplerate; |
4764
9579496a91db
Added pts for mp3 and wav. And perfect seeking for mp3, unless flags & 2
albeu
parents:
4720
diff
changeset
|
735 nf--; |
9579496a91db
Added pts for mp3 and wav. And perfect seeking for mp3, unless flags & 2
albeu
parents:
4720
diff
changeset
|
736 } |
9579496a91db
Added pts for mp3 and wav. And perfect seeking for mp3, unless flags & 2
albeu
parents:
4720
diff
changeset
|
737 } |
9579496a91db
Added pts for mp3 and wav. And perfect seeking for mp3, unless flags & 2
albeu
parents:
4720
diff
changeset
|
738 |
17636 | 739 static void demux_audio_seek(demuxer_t *demuxer,float rel_seek_secs,float audio_delay,int flags){ |
4694 | 740 sh_audio_t* sh_audio; |
741 stream_t* s; | |
27904
f6d60ccb095f
Use 64 bit numbers for file positions in the seek function in audio demuxer.
reimar
parents:
27707
diff
changeset
|
742 int64_t base,pos; |
4694 | 743 float len; |
744 da_priv_t* priv; | |
745 | |
4764
9579496a91db
Added pts for mp3 and wav. And perfect seeking for mp3, unless flags & 2
albeu
parents:
4720
diff
changeset
|
746 if(!(sh_audio = demuxer->audio->sh)) |
9579496a91db
Added pts for mp3 and wav. And perfect seeking for mp3, unless flags & 2
albeu
parents:
4720
diff
changeset
|
747 return; |
4694 | 748 s = demuxer->stream; |
749 priv = demuxer->priv; | |
750 | |
25883
baf32110d3fc
Use defines to give names to the different seek flags.
reimar
parents:
25772
diff
changeset
|
751 if(priv->frmt == MP3 && hr_mp3_seek && !(flags & SEEK_FACTOR)) { |
baf32110d3fc
Use defines to give names to the different seek flags.
reimar
parents:
25772
diff
changeset
|
752 len = (flags & SEEK_ABSOLUTE) ? rel_seek_secs - priv->next_pts : rel_seek_secs; |
4764
9579496a91db
Added pts for mp3 and wav. And perfect seeking for mp3, unless flags & 2
albeu
parents:
4720
diff
changeset
|
753 if(len < 0) { |
9579496a91db
Added pts for mp3 and wav. And perfect seeking for mp3, unless flags & 2
albeu
parents:
4720
diff
changeset
|
754 stream_seek(s,demuxer->movi_start); |
24589 | 755 len = priv->next_pts + len; |
756 priv->next_pts = 0; | |
4764
9579496a91db
Added pts for mp3 and wav. And perfect seeking for mp3, unless flags & 2
albeu
parents:
4720
diff
changeset
|
757 } |
9579496a91db
Added pts for mp3 and wav. And perfect seeking for mp3, unless flags & 2
albeu
parents:
4720
diff
changeset
|
758 if(len > 0) |
9579496a91db
Added pts for mp3 and wav. And perfect seeking for mp3, unless flags & 2
albeu
parents:
4720
diff
changeset
|
759 high_res_mp3_seek(demuxer,len); |
9579496a91db
Added pts for mp3 and wav. And perfect seeking for mp3, unless flags & 2
albeu
parents:
4720
diff
changeset
|
760 return; |
9579496a91db
Added pts for mp3 and wav. And perfect seeking for mp3, unless flags & 2
albeu
parents:
4720
diff
changeset
|
761 } |
9579496a91db
Added pts for mp3 and wav. And perfect seeking for mp3, unless flags & 2
albeu
parents:
4720
diff
changeset
|
762 |
25883
baf32110d3fc
Use defines to give names to the different seek flags.
reimar
parents:
25772
diff
changeset
|
763 base = flags&SEEK_ABSOLUTE ? demuxer->movi_start : stream_tell(s); |
baf32110d3fc
Use defines to give names to the different seek flags.
reimar
parents:
25772
diff
changeset
|
764 if(flags&SEEK_FACTOR) |
5796 | 765 pos = base + ((demuxer->movi_end - demuxer->movi_start)*rel_seek_secs); |
766 else | |
767 pos = base + (rel_seek_secs*sh_audio->i_bps); | |
4694 | 768 |
769 if(demuxer->movi_end && pos >= demuxer->movi_end) { | |
8359 | 770 pos = demuxer->movi_end; |
4694 | 771 } else if(pos < demuxer->movi_start) |
772 pos = demuxer->movi_start; | |
4764
9579496a91db
Added pts for mp3 and wav. And perfect seeking for mp3, unless flags & 2
albeu
parents:
4720
diff
changeset
|
773 |
24589 | 774 priv->next_pts = (pos-demuxer->movi_start)/(double)sh_audio->i_bps; |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
775 |
4694 | 776 switch(priv->frmt) { |
777 case WAV: | |
16818
67ce689b5764
Fix seeking in wav files: align relative to start of data, not start of file
reimar
parents:
16438
diff
changeset
|
778 pos -= (pos - demuxer->movi_start) % |
67ce689b5764
Fix seeking in wav files: align relative to start of data, not start of file
reimar
parents:
16438
diff
changeset
|
779 (sh_audio->wf->nBlockAlign ? sh_audio->wf->nBlockAlign : |
67ce689b5764
Fix seeking in wav files: align relative to start of data, not start of file
reimar
parents:
16438
diff
changeset
|
780 (sh_audio->channels * sh_audio->samplesize)); |
4694 | 781 break; |
782 } | |
783 | |
784 stream_seek(s,pos); | |
785 } | |
4764
9579496a91db
Added pts for mp3 and wav. And perfect seeking for mp3, unless flags & 2
albeu
parents:
4720
diff
changeset
|
786 |
16175 | 787 static void demux_close_audio(demuxer_t* demuxer) { |
5812 | 788 da_priv_t* priv = demuxer->priv; |
789 | |
790 free(priv); | |
791 } | |
792 | |
16175 | 793 static int demux_audio_control(demuxer_t *demuxer,int cmd, void *arg){ |
10882
e46e5a6c53b8
get_percent_pos support in demux_audio, patch by ROSEN Jeremy <jeremy.rosen at c-s.fr>
faust3
parents:
10244
diff
changeset
|
794 sh_audio_t *sh_audio=demuxer->audio->sh; |
34827
ef7be22beabe
Take start offset into account when calculating amount of audio data.
reimar
parents:
34826
diff
changeset
|
795 int audio_length = sh_audio->i_bps && demuxer->movi_end > demuxer->movi_start ? |
ef7be22beabe
Take start offset into account when calculating amount of audio data.
reimar
parents:
34826
diff
changeset
|
796 (demuxer->movi_end - demuxer->movi_start) / sh_audio->i_bps : 0; |
10882
e46e5a6c53b8
get_percent_pos support in demux_audio, patch by ROSEN Jeremy <jeremy.rosen at c-s.fr>
faust3
parents:
10244
diff
changeset
|
797 da_priv_t* priv = demuxer->priv; |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
798 |
10882
e46e5a6c53b8
get_percent_pos support in demux_audio, patch by ROSEN Jeremy <jeremy.rosen at c-s.fr>
faust3
parents:
10244
diff
changeset
|
799 switch(cmd) { |
e46e5a6c53b8
get_percent_pos support in demux_audio, patch by ROSEN Jeremy <jeremy.rosen at c-s.fr>
faust3
parents:
10244
diff
changeset
|
800 case DEMUXER_CTRL_GET_TIME_LENGTH: |
e46e5a6c53b8
get_percent_pos support in demux_audio, patch by ROSEN Jeremy <jeremy.rosen at c-s.fr>
faust3
parents:
10244
diff
changeset
|
801 if (audio_length<=0) return DEMUXER_CTRL_DONTKNOW; |
16346
6ff303d2876b
Make -identify's 'ID_LENGTH=' print a float and not an integer.. The
ods15
parents:
16175
diff
changeset
|
802 *((double *)arg)=(double)audio_length; |
10882
e46e5a6c53b8
get_percent_pos support in demux_audio, patch by ROSEN Jeremy <jeremy.rosen at c-s.fr>
faust3
parents:
10244
diff
changeset
|
803 return DEMUXER_CTRL_GUESS; |
e46e5a6c53b8
get_percent_pos support in demux_audio, patch by ROSEN Jeremy <jeremy.rosen at c-s.fr>
faust3
parents:
10244
diff
changeset
|
804 |
e46e5a6c53b8
get_percent_pos support in demux_audio, patch by ROSEN Jeremy <jeremy.rosen at c-s.fr>
faust3
parents:
10244
diff
changeset
|
805 case DEMUXER_CTRL_GET_PERCENT_POS: |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
806 if (audio_length<=0) |
10882
e46e5a6c53b8
get_percent_pos support in demux_audio, patch by ROSEN Jeremy <jeremy.rosen at c-s.fr>
faust3
parents:
10244
diff
changeset
|
807 return DEMUXER_CTRL_DONTKNOW; |
24589 | 808 *((int *)arg)=(int)( (priv->next_pts*100) / audio_length); |
10882
e46e5a6c53b8
get_percent_pos support in demux_audio, patch by ROSEN Jeremy <jeremy.rosen at c-s.fr>
faust3
parents:
10244
diff
changeset
|
809 return DEMUXER_CTRL_OK; |
e46e5a6c53b8
get_percent_pos support in demux_audio, patch by ROSEN Jeremy <jeremy.rosen at c-s.fr>
faust3
parents:
10244
diff
changeset
|
810 |
e46e5a6c53b8
get_percent_pos support in demux_audio, patch by ROSEN Jeremy <jeremy.rosen at c-s.fr>
faust3
parents:
10244
diff
changeset
|
811 default: |
e46e5a6c53b8
get_percent_pos support in demux_audio, patch by ROSEN Jeremy <jeremy.rosen at c-s.fr>
faust3
parents:
10244
diff
changeset
|
812 return DEMUXER_CTRL_NOTIMPL; |
e46e5a6c53b8
get_percent_pos support in demux_audio, patch by ROSEN Jeremy <jeremy.rosen at c-s.fr>
faust3
parents:
10244
diff
changeset
|
813 } |
e46e5a6c53b8
get_percent_pos support in demux_audio, patch by ROSEN Jeremy <jeremy.rosen at c-s.fr>
faust3
parents:
10244
diff
changeset
|
814 } |
16175 | 815 |
816 | |
25707
d4fe6e23283e
Make all demuxer_desc_t const, thus moving them to .rodata
reimar
parents:
24592
diff
changeset
|
817 const demuxer_desc_t demuxer_desc_audio = { |
16175 | 818 "Audio demuxer", |
819 "audio", | |
27333
16251c34062d
changed 'Audio file' to 'Audio only' (to not get 'Audio file file' when played)
ptt
parents:
27243
diff
changeset
|
820 "Audio only", |
16175 | 821 "?", |
822 "Audio only files", | |
823 DEMUXER_TYPE_AUDIO, | |
824 0, // unsafe autodetect | |
825 demux_audio_open, | |
826 demux_audio_fill_buffer, | |
827 NULL, | |
828 demux_close_audio, | |
829 demux_audio_seek, | |
830 demux_audio_control | |
831 }; |