summaryrefslogtreecommitdiffstats
path: root/demux/demux_rawaudio.c
blob: 50e4e4a68baf8cb90a81f286992ce01ef078d48d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
/*
 * This file is part of MPlayer.
 *
 * MPlayer is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * MPlayer is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with MPlayer; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

#include "config.h"

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>

#include "core/m_option.h"

#include "stream/stream.h"
#include "demux.h"
#include "stheader.h"
#include "audio/format.h"


static struct mp_chmap channels = MP_CHMAP_INIT_STEREO;
static int samplerate = 44100;
static int format = AF_FORMAT_S16_NE;

const m_option_t demux_rawaudio_opts[] = {
  { "channels", &channels, &m_option_type_chmap, CONF_MIN, 1 },
  { "rate", &samplerate, CONF_TYPE_INT,CONF_RANGE,1000,8*48000, NULL },
  { "format", &format, CONF_TYPE_AFMT, 0, 0, 0, NULL },
  {NULL, NULL, 0, 0, 0, 0, NULL}
};


static demuxer_t* demux_rawaudio_open(demuxer_t* demuxer) {
  struct sh_stream *sh;
  sh_audio_t* sh_audio;
  WAVEFORMATEX* w;

  if ((format & AF_FORMAT_SPECIAL_MASK) != 0)
      return NULL;

  sh = new_sh_stream(demuxer, STREAM_AUDIO);
  sh_audio = sh->audio;
  sh_audio->gsh->codec = "mp-pcm";
  sh_audio->format = format;
  sh_audio->wf = w = malloc(sizeof(*w));
  w->wFormatTag = 0;
  sh_audio->channels = channels;
  w->nChannels = sh_audio->channels.num;
  w->nSamplesPerSec = sh_audio->samplerate = samplerate;
  int samplesize = (af_fmt2bits(format) + 7) / 8;
  w->nAvgBytesPerSec = samplerate * samplesize * w->nChannels;
  w->nBlockAlign = w->nChannels * samplesize;
  w->wBitsPerSample = 8 * samplesize;
  w->cbSize = 0;

  demuxer->movi_start = demuxer->stream->start_pos;
  demuxer->movi_end = demuxer->stream->end_pos;

  return demuxer;
}

static int demux_rawaudio_fill_buffer(demuxer_t* demuxer, demux_stream_t *ds) {
  sh_audio_t* sh_audio = demuxer->audio->gsh->audio;
  int l = sh_audio->wf->nAvgBytesPerSec;
  int64_t spos = stream_tell(demuxer->stream);
  demux_packet_t*  dp;

  if(demuxer->stream->eof)
    return 0;

  dp = new_demux_packet(l);
  dp->pts = (spos - demuxer->movi_start)  / (float)(sh_audio->wf->nAvgBytesPerSec);
  dp->pos = (spos - demuxer->movi_start);

  l = stream_read(demuxer->stream,dp->buffer,l);
  resize_demux_packet(dp, l);
  ds_add_packet(ds,dp);

  return 1;
}

static void demux_rawaudio_seek(demuxer_t *demuxer,float rel_seek_secs,float audio_delay,int flags){
  stream_t* s = demuxer->stream;
  sh_audio_t* sh_audio = demuxer->audio->gsh->audio;
  int64_t base,pos;

  base = (flags & SEEK_ABSOLUTE) ? demuxer->movi_start : stream_tell(s);
  if(flags & SEEK_FACTOR)
    pos = base + ((demuxer->movi_end - demuxer->movi_start)*rel_seek_secs);
  else
    pos = base + (rel_seek_secs*sh_audio->i_bps);

  pos -= (pos % (sh_audio->channels.num * sh_audio->samplesize) );
  stream_seek(s,pos);
//  printf("demux_rawaudio: streamtell=%d\n",(int)stream_tell(demuxer->stream));
}

const demuxer_desc_t demuxer_desc_rawaudio = {
  "Raw audio demuxer",
  "rawaudio",
  "rawaudio",
  "?",
  "",
  DEMUXER_TYPE_RAWAUDIO,
  0, // no autodetect
  NULL,
  demux_rawaudio_fill_buffer,
  demux_rawaudio_open,
  NULL,
  demux_rawaudio_seek,
};