2 * Copyright (c) 2006 Aurelien Jacobs <aurel@gnuage.org>
4 * This file is part of FFmpeg.
6 * FFmpeg is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * FFmpeg is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with FFmpeg; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 #include "libavutil/intreadwrite.h"
27 ff_voc_get_packet(AVFormatContext
*s
, AVPacket
*pkt
, AVStream
*st
, int max_size
)
29 VocDecContext
*voc
= s
->priv_data
;
30 AVCodecParameters
*par
= st
->codecpar
;
31 AVIOContext
*pb
= s
->pb
;
33 int size
, tmp_codec
=-1;
39 av_add_index_entry(st
,
46 while (!voc
->remaining_size
) {
50 if (type
== VOC_TYPE_EOF
)
52 voc
->remaining_size
= avio_rl24(pb
);
53 if (!voc
->remaining_size
) {
55 if (!(s
->pb
->seekable
& AVIO_SEEKABLE_NORMAL
))
57 filesize
= avio_size(pb
);
58 if (filesize
- avio_tell(pb
) > INT_MAX
)
59 return AVERROR_INVALIDDATA
;
60 voc
->remaining_size
= filesize
- avio_tell(pb
);
65 case VOC_TYPE_VOICE_DATA
:
66 if (voc
->remaining_size
< 2) {
67 voc
->remaining_size
= 0;
68 return AVERROR_INVALIDDATA
;
70 if (!par
->sample_rate
) {
71 par
->sample_rate
= 1000000 / (256 - avio_r8(pb
));
73 par
->sample_rate
= sample_rate
;
74 avpriv_set_pts_info(st
, 64, 1, par
->sample_rate
);
75 par
->channels
= channels
;
76 par
->bits_per_coded_sample
= av_get_bits_per_sample(par
->codec_id
);
79 tmp_codec
= avio_r8(pb
);
80 voc
->remaining_size
-= 2;
85 case VOC_TYPE_VOICE_DATA_CONT
:
88 case VOC_TYPE_EXTENDED
:
89 sample_rate
= avio_rl16(pb
);
91 channels
= avio_r8(pb
) + 1;
92 sample_rate
= 256000000 / (channels
* (65536 - sample_rate
));
93 voc
->remaining_size
= 0;
97 case VOC_TYPE_NEW_VOICE_DATA
:
98 if (voc
->remaining_size
< 12) {
99 voc
->remaining_size
= 0;
100 return AVERROR_INVALIDDATA
;
102 if (!par
->sample_rate
) {
103 par
->sample_rate
= avio_rl32(pb
);
104 avpriv_set_pts_info(st
, 64, 1, par
->sample_rate
);
105 par
->bits_per_coded_sample
= avio_r8(pb
);
106 par
->channels
= avio_r8(pb
);
109 tmp_codec
= avio_rl16(pb
);
111 voc
->remaining_size
-= 12;
116 avio_skip(pb
, voc
->remaining_size
);
117 max_size
-= voc
->remaining_size
;
118 voc
->remaining_size
= 0;
123 if (par
->sample_rate
<= 0) {
124 av_log(s
, AV_LOG_ERROR
, "Invalid sample rate %d\n", par
->sample_rate
);
125 return AVERROR_INVALIDDATA
;
128 if (tmp_codec
>= 0) {
129 tmp_codec
= ff_codec_get_id(ff_voc_codec_tags
, tmp_codec
);
130 if (par
->codec_id
== AV_CODEC_ID_NONE
)
131 par
->codec_id
= tmp_codec
;
132 else if (par
->codec_id
!= tmp_codec
)
133 av_log(s
, AV_LOG_WARNING
, "Ignoring mid-stream change in audio codec\n");
134 if (par
->codec_id
== AV_CODEC_ID_NONE
) {
135 if (s
->audio_codec_id
== AV_CODEC_ID_NONE
) {
136 av_log(s
, AV_LOG_ERROR
, "unknown codec tag\n");
137 return AVERROR(EINVAL
);
139 av_log(s
, AV_LOG_WARNING
, "unknown codec tag\n");
143 par
->bit_rate
= (int64_t)par
->sample_rate
* par
->channels
* par
->bits_per_coded_sample
;
147 size
= FFMIN(voc
->remaining_size
, max_size
);
148 voc
->remaining_size
-= size
;
150 ret
= av_get_packet(pb
, pkt
, size
);
151 pkt
->dts
= pkt
->pts
= voc
->pts
;
153 duration
= av_get_audio_frame_duration2(st
->codecpar
, size
);
154 if (duration
> 0 && voc
->pts
!= AV_NOPTS_VALUE
)
155 voc
->pts
+= duration
;
157 voc
->pts
= AV_NOPTS_VALUE
;