yading@11: /* yading@11: * PCM common functions yading@11: * Copyright (c) 2003 Fabrice Bellard yading@11: * yading@11: * This file is part of FFmpeg. yading@11: * yading@11: * FFmpeg is free software; you can redistribute it and/or yading@11: * modify it under the terms of the GNU Lesser General Public yading@11: * License as published by the Free Software Foundation; either yading@11: * version 2.1 of the License, or (at your option) any later version. yading@11: * yading@11: * FFmpeg is distributed in the hope that it will be useful, yading@11: * but WITHOUT ANY WARRANTY; without even the implied warranty of yading@11: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU yading@11: * Lesser General Public License for more details. yading@11: * yading@11: * You should have received a copy of the GNU Lesser General Public yading@11: * License along with FFmpeg; if not, write to the Free Software yading@11: * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA yading@11: */ yading@11: yading@11: #include "libavutil/mathematics.h" yading@11: #include "avformat.h" yading@11: #include "pcm.h" yading@11: yading@11: #define RAW_SAMPLES 1024 yading@11: yading@11: int ff_pcm_read_packet(AVFormatContext *s, AVPacket *pkt) yading@11: { yading@11: int ret, size; yading@11: yading@11: size= RAW_SAMPLES*s->streams[0]->codec->block_align; yading@11: if (size <= 0) yading@11: return AVERROR(EINVAL); yading@11: yading@11: ret= av_get_packet(s->pb, pkt, size); yading@11: yading@11: pkt->flags &= ~AV_PKT_FLAG_CORRUPT; yading@11: pkt->stream_index = 0; yading@11: if (ret < 0) yading@11: return ret; yading@11: yading@11: return ret; yading@11: } yading@11: yading@11: int ff_pcm_read_seek(AVFormatContext *s, yading@11: int stream_index, int64_t timestamp, int flags) yading@11: { yading@11: AVStream *st; yading@11: int block_align, byte_rate; yading@11: int64_t pos, ret; yading@11: yading@11: st = s->streams[0]; yading@11: yading@11: block_align = st->codec->block_align ? st->codec->block_align : yading@11: (av_get_bits_per_sample(st->codec->codec_id) * st->codec->channels) >> 3; yading@11: byte_rate = st->codec->bit_rate ? st->codec->bit_rate >> 3 : yading@11: block_align * st->codec->sample_rate; yading@11: yading@11: if (block_align <= 0 || byte_rate <= 0) yading@11: return -1; yading@11: if (timestamp < 0) timestamp = 0; yading@11: yading@11: /* compute the position by aligning it to block_align */ yading@11: pos = av_rescale_rnd(timestamp * byte_rate, yading@11: st->time_base.num, yading@11: st->time_base.den * (int64_t)block_align, yading@11: (flags & AVSEEK_FLAG_BACKWARD) ? AV_ROUND_DOWN : AV_ROUND_UP); yading@11: pos *= block_align; yading@11: yading@11: /* recompute exact position */ yading@11: st->cur_dts = av_rescale(pos, st->time_base.den, byte_rate * (int64_t)st->time_base.num); yading@11: if ((ret = avio_seek(s->pb, pos + s->data_offset, SEEK_SET)) < 0) yading@11: return ret; yading@11: return 0; yading@11: }