Chinaunix首页 | 论坛 | 博客
  • 博客访问: 511919
  • 博文数量: 174
  • 博客积分: 8001
  • 博客等级: 中将
  • 技术积分: 1840
  • 用 户 组: 普通用户
  • 注册时间: 2009-03-04 19:30
文章分类

全部博文(174)

文章存档

2011年(1)

2010年(24)

2009年(149)

我的朋友

分类: LINUX

2009-04-16 09:32:19

通过重定位标准输入输出文件来实现输入输出。
关键的函数:

static int decode(unsigned char const *start, unsigned long length);

注意:这不是libmad的底层函数。
这个函数完成的工作是:
1.初始化decoder:

mad_decoder_init(&decoder, &buffer,
         input, 0 /* header */, 0 /* filter */, output,
         error, 0 /* message */);


在decoder.c中定义如下:

void mad_decoder_init(struct mad_decoder *decoder, void *data,
         enum mad_flow (*input_func)(void *,
                         struct mad_stream *),
         enum mad_flow (*header_func)(void *,
                         struct mad_header const *),
         enum mad_flow (*filter_func)(void *,
                         struct mad_stream const *,
                         struct mad_frame *),
         enum mad_flow (*output_func)(void *,
                         struct mad_header const *,
                         struct mad_pcm *),
         enum mad_flow (*error_func)(void *,
                         struct mad_stream *,
                         struct mad_frame *),
         enum mad_flow (*message_func)(void *,
                         void *, unsigned int *));

初始化一个mad_decoder的实例。

注意到data时void *,那么程序如何得知处理data的方法呢?


mad_decoder的结构:

struct mad_decoder {
  enum mad_decoder_mode mode;

(notes:

enum mad_decoder_mode { MAD_DECODER_MODE_SYNC = 0, MAD_DECODER_MODE_ASYNC }

同步/异步方式

)

  int options;

  struct {
    long pid; //异步方式进程号
    int in;
    int out;
  } async;

  struct {
    struct mad_stream stream;
    struct mad_frame frame;
    struct mad_synth synth;
  } *sync;

  void *cb_data;

  enum mad_flow (*input_func)(void *, struct mad_stream *);
  enum mad_flow (*header_func)(void *, struct mad_header const *);
  enum mad_flow (*filter_func)(void *,
             struct mad_stream const *, struct mad_frame *);
  enum mad_flow (*output_func)(void *,
             struct mad_header const *, struct mad_pcm *);
  enum mad_flow (*error_func)(void *, struct mad_stream *, struct mad_frame*);
  enum mad_flow (*message_func)(void *, void *, unsigned int *);
};


解码器运行:

int mad_decoder_run(struct mad_decoder *decoder, enum mad_decoder_mode mode)
{
  int result;
  int (*run)(struct mad_decoder *) = 0; //用于指定使用异步还是同步的运行函数

  switch (decoder->mode = mode) {
  case MAD_DECODER_MODE_SYNC:
    run = run_sync;
    break;

  case MAD_DECODER_MODE_ASYNC:
# if defined(USE_ASYNC)
    run = run_async;
# endif
    break;
  }

  if (run == 0)
    return -1;

  decoder->sync = malloc(sizeof(*decoder->sync));
  if (decoder->sync == 0)
    return -1;

  result = run(decoder);

  free(decoder->sync);
  decoder->sync = 0;

  return result;
}


同步运行:

static
int run_sync(struct mad_decoder *decoder)
{
  enum mad_flow (*error_func)(void *, struct mad_stream *, struct mad_frame*);
  void *error_data;
  int bad_last_frame = 0;
  struct mad_stream *stream;
  struct mad_frame *frame;
  struct mad_synth *synth;
  int result = 0;

...

  if (decoder->error_func) {
    error_func = decoder->error_func;
    error_data = decoder->cb_data;
  }
  else {
    error_func = error_default;
    error_data = &bad_last_frame;
  }
...
  mad_stream_init(stream);
  mad_frame_init(frame);
  mad_synth_init(synth);

  mad_stream_options(stream, decoder->options);

  do {

//调用input_func,把cb_data的信息复制到stream中。

 switch (decoder->input_func(decoder->cb_data, stream)) {

    case MAD_FLOW_STOP:
      goto done;
    case MAD_FLOW_BREAK:
      goto fail;
    case MAD_FLOW_IGNORE:
      continue;
    case MAD_FLOW_CONTINUE:
      break;
    }

    while (1) {
# if defined(USE_ASYNC)
...
# endif

      if (decoder->header_func) {
    if (mad_header_decode(&frame->header, stream) == -1) {
...
    }

    switch (decoder->header_func(decoder->cb_data, &frame->header)) {
 ...
    }
      }

      if (mad_frame_decode(frame, stream) == -1) {

...
      }
      else
    bad_last_frame = 0;

      if (decoder->filter_func) {
...
      }
...
      if (decoder->output_func) {
    switch (decoder->output_func(decoder->cb_data,
                 &frame->header, &synth->pcm)) {
    case MAD_FLOW_STOP:
     goto done;
    case MAD_FLOW_BREAK:
     goto fail;
    case MAD_FLOW_IGNORE:
    case MAD_FLOW_CONTINUE:
     break;
    }
      }
    }
  }while (stream->error == MAD_ERROR_BUFLEN);

 fail:
  result = -1;

 done:
  mad_synth_finish(synth);
  mad_frame_finish(frame);
  mad_stream_finish(stream);

  return result;
}


input_func在minimad中的实现是非常简单的:

static
enum mad_flow input(void *data,
         struct mad_stream *stream)
{
  struct buffer *buffer = data;

  if (!buffer->length)
    return MAD_FLOW_STOP;

  mad_stream_buffer(stream, buffer->start, buffer->length);

  buffer->length = 0;

  return MAD_FLOW_CONTINUE;


output_func在minimad中的实现是:

mad_stream--输入音频数据比特流关联到解码流
mad_frame--解码流关联到解码器
--mad_header--MPEG帧的基本信息
----mad_mode--声道模型
----....
mad_synth--解码器关联到PCM数据合成
--mad_pcm--合成的PCM数据
程序基本流程:
1.初始化stream, synth, frame
2.关联输入流到解码流
3.调用解码器
4.合成PCM数据
5.释放stream, synth, frame



阅读(1969) | 评论(0) | 转发(0) |
0

上一篇:chmod的参数

下一篇:源码分析开篇

给主人留下些什么吧!~~