⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 decode_mpeg.c

📁 基于linux的DVD播放器程序
💻 C
字号:
/* Ogle - A video player * Copyright (C) 2001, 2002 Bj鰎n Englund, H錵an Hjort * * This program 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. * * This program 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 this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */#include <stdlib.h>#include <stdio.h>#include <string.h>#include <inttypes.h>#include <libogleao/ogle_ao.h> // Remove me#include <mad.h>#include "decode.h"#include "decode_private.h"#include "debug_print.h"#include "audio_config.h"#include "conversion.h"#include "audio_play.h"#include "decode_mpeg.h"// should be at least max size of an mpeg audio frame#define CODED_BUF_SIZE_MPEG 2048*2 typedef struct {  adec_handle_t handle;  uint64_t PTS;  int pts_valid;  int scr_nr;  uint8_t *coded_buf;  uint8_t *buf_ptr;  int sample_rate;  int bytes_needed;  int availflags;  int output_flags;  int decoding_flags;  /* libmad */  struct mad_stream stream;  struct mad_frame frame;  struct mad_synth synth;  mad_timer_t timer;} adec_mpeg_handle_t;static int decode_mpeg(adec_mpeg_handle_t *h, uint8_t *start, int len,		       int pts_offset, uint64_t new_PTS, int scr_nr){  int bytes_left;  int pts_valid;  static int prev_scr_nr;  static uint64_t prev_PTS;  static int prev_pts_valid = 0;  uint8_t *packet_start = NULL;  int first = 1;  bytes_left = len;    if(pts_offset == -1) {    pts_valid = 0;  } else {    pts_valid = 1;  }    while(bytes_left > 0) {    int avail_buf;    avail_buf = CODED_BUF_SIZE_MPEG - (h->buf_ptr - h->coded_buf);    if(avail_buf <= 0) {      FATAL("mpeg coded buf full: %d\n", avail_buf);    }    /*    fprintf(stderr, "avail: %d, len: %d, ptr: %d\n",	    avail_buf, bytes_left, h->buf_ptr - h->coded_buf);    */    if(avail_buf >= bytes_left) {       memcpy(h->buf_ptr, start, bytes_left);      if(first) {	packet_start = h->buf_ptr;      }      h->buf_ptr += bytes_left;      bytes_left = 0;    } else {      memcpy(h->buf_ptr, start, avail_buf);      if(first) {	packet_start = h->buf_ptr;      }      bytes_left -= avail_buf;      start += avail_buf;      h->buf_ptr += avail_buf;    }    first = 0;              mad_stream_buffer(&h->stream, h->coded_buf,		      h->buf_ptr - h->coded_buf);    h->stream.error = 0;        while(1) {      if(mad_frame_decode(&h->frame, &h->stream)) {	if(MAD_RECOVERABLE(h->stream.error)) {	  if(h->stream.error == MAD_ERROR_LOSTSYNC) {	    NOTE("%s", "mpeg lost sync\n");	  } else {	    DNOTE("mpeg recoverable: %d\n", h->stream.error);	  }	} else {	  /*	  fprintf(stderr, "unrec curframe: %u, nextframe: %u\n",		  h->stream.this_frame - h->coded_buf,		  h->stream.next_frame - h->coded_buf);	  */	  if(h->stream.error == MAD_ERROR_BUFLEN) {	    memmove(h->coded_buf, h->stream.next_frame,		    h->buf_ptr - h->stream.next_frame);	    h->buf_ptr-= (h->stream.next_frame - h->coded_buf); 	    packet_start-= (h->stream.next_frame - h->coded_buf);	    if(pts_valid) {	      prev_pts_valid = 1;	      prev_PTS = new_PTS;	      prev_scr_nr = scr_nr;	    } else {	      prev_pts_valid = 0;	    }	    break;	  } else {	    FATAL("mpeg unrecoverable error: %d\n", h->stream.error);	  }	}      } else {	int frame_pts_valid;	uint64_t frame_PTS = 0; /* init to shut up compiler */	int frame_scr_nr;	mad_synth_frame(&h->synth, &h->frame);		if(h->frame.header.samplerate != h->sample_rate) {	  audio_format_t new_format;	  	  h->sample_rate = h->frame.header.samplerate;	  audio_config(h->handle.config, 2, h->sample_rate, 16);	  	  new_format.ch_array = malloc(2 * sizeof(ChannelType_t));	  new_format.ch_array[0] = ChannelType_Left;	  new_format.ch_array[1] = ChannelType_Right;	  	  new_format.sample_rate = h->sample_rate;	  new_format.sample_resolution = 16;	  new_format.sample_format = SampleFormat_MadFixed;	  init_sample_conversion((adec_handle_t *)h, &new_format, 1152);	  	  free(new_format.ch_array);	}	convert_samples_start((adec_handle_t *)h);	convert_samples((adec_handle_t *)h, h->synth.pcm.samples,			h->synth.pcm.length);	if(h->stream.this_frame >= packet_start) {	  if(pts_valid) {	    frame_pts_valid = 1;	    frame_PTS = new_PTS;	    frame_scr_nr = scr_nr;	    //fprintf(stderr, "PTS: %llu\n", new_PTS);	    pts_valid = 0;	  } else {	    frame_pts_valid = 0;	    frame_scr_nr = scr_nr;	    //fprintf(stderr, "no PTS:\n");	  }	} else {	  if(prev_pts_valid) {	    frame_pts_valid = 1;	    frame_PTS = prev_PTS;	    frame_scr_nr = prev_scr_nr;	    // fprintf(stderr, "prev PTS: %llu\n", prev_PTS);	    prev_pts_valid = 0;	  } else {	    frame_pts_valid = 0;	    frame_scr_nr = scr_nr;	    //fprintf(stderr, "no prev PTS:\n");	  }	}	play_samples((adec_handle_t *)h, frame_scr_nr, 		     frame_PTS, frame_pts_valid);	/*	  fprintf(stderr, "curframe: %u, nextframe: %u\n",	  h->stream.this_frame - h->coded_buf,	  h->stream.next_frame - h->coded_buf);	*/	      }    }  }    return 0;}staticint flush_mpeg(adec_mpeg_handle_t *handle){  handle->pts_valid = 0;  handle->buf_ptr = handle->coded_buf;  handle->bytes_needed = 7;    // Fix this.. not the right way to do things I belive.  if(handle->handle.config && handle->handle.config->adev_handle)    ogle_ao_flush(handle->handle.config->adev_handle);  return 0;}staticvoid free_mpeg(adec_mpeg_handle_t *handle){  mad_synth_finish(&handle->synth);  mad_frame_finish(&handle->frame);  mad_stream_finish(&handle->stream);  audio_config_close(handle->handle.config);  free(handle->coded_buf);  free(handle);  return;}adec_handle_t *init_mpeg(void){  adec_mpeg_handle_t *handle;    if(!(handle = (adec_mpeg_handle_t *)malloc(sizeof(adec_mpeg_handle_t)))) {    return NULL;  }    memset(&handle->handle, 0, sizeof(struct adec_handle_s));  // not set: drain  handle->handle.decode = (audio_decode_t) decode_mpeg;  // function pointers  handle->handle.flush  = (audio_flush_t)  flush_mpeg;  handle->handle.free   = (audio_free_t)   free_mpeg;  handle->handle.output_buf = NULL;  handle->handle.output_buf_size = 0;  handle->handle.output_buf_ptr = handle->handle.output_buf;  handle->PTS = 0;  handle->pts_valid = 0;  handle->scr_nr = 0;  handle->coded_buf = (uint8_t *)malloc(CODED_BUF_SIZE_MPEG);  handle->buf_ptr = (uint8_t *)handle->coded_buf;  handle->bytes_needed = 7;  handle->sample_rate = 0;  //  handle->decoded_format = NULL;  {        mad_stream_init(&handle->stream);    mad_frame_init(&handle->frame);    mad_synth_init(&handle->synth);    mad_timer_reset(&handle->timer);  }    return (adec_handle_t *)handle;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -