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

📄 mpeg3atrack.c

📁 网络MPEG4IP流媒体开发源代码
💻 C
字号:
#include "libmpeg3.h"#include "mpeg3protos.h"#include "mpeg3demux.h"#include "mp4av.h"#include <stdlib.h>static int mpeg3_atrack_get_mp3_info (mpeg3_atrack_t *atrack){  uint8_t hdr[4];  mpeg3_demuxer_t *demux;  MP4AV_Mp3Header temp;  demux = atrack->demuxer;  hdr[1] = mpeg3demux_read_char(demux);  do {    hdr[0] = hdr[1];    hdr[1] = mpeg3demux_read_char(demux);  } while (((hdr[0] != 0xff) || 	   ((hdr[1] & 0xe0) != 0xe0)) && 	   !mpeg3demux_eof(demux));    if (mpeg3demux_eof(demux)) return -1;  hdr[2] = mpeg3demux_read_char(demux);  hdr[3] = mpeg3demux_read_char(demux);  temp = MP4AV_Mp3HeaderFromBytes(hdr);  atrack->sample_rate = MP4AV_Mp3GetHdrSamplingRate(temp);  atrack->channels = MP4AV_Mp3GetChannels(temp);  atrack->samples_per_frame = MP4AV_Mp3GetHdrSamplingWindow(temp);  return 0;}static int mpeg3_atrack_get_aac_info (mpeg3_atrack_t *atrack){  uint8_t hdr[16];  mpeg3_demuxer_t *demux;  uint16_t hdr_size;  uint16_t ix;  demux = atrack->demuxer;  hdr[1] = mpeg3demux_read_char(demux);  do {    hdr[0] = hdr[1];    hdr[1] = mpeg3demux_read_char(demux);  } while (((hdr[0] != 0xff) || 	   ((hdr[1] & 0xf0) != 0xf0)) && 	   !mpeg3demux_eof(demux));  if (mpeg3demux_eof(demux)) return -1;  hdr_size = MP4AV_AdtsGetHeaderByteSize(hdr);  if (hdr_size > sizeof(hdr)) return -1;  for (ix = 2; ix < hdr_size; ix++) {    hdr[ix] = mpeg3demux_read_char(demux);  }  if (mpeg3demux_eof(demux)) return -1;    atrack->sample_rate = MP4AV_AdtsGetSamplingRate(hdr);  atrack->channels = MP4AV_AdtsGetChannels(hdr);  atrack->samples_per_frame = 1024; // always the same    return 0;}static int mpeg3_ac3_samplerates[] = { 48000, 44100, 32000 };struct mpeg3_framesize_s{	unsigned short bit_rate;	unsigned short frm_size[3];};static struct mpeg3_framesize_s framesize_codes[] = {      { 32  ,{64   ,69   ,96   } },      { 32  ,{64   ,70   ,96   } },      { 40  ,{80   ,87   ,120  } },      { 40  ,{80   ,88   ,120  } },      { 48  ,{96   ,104  ,144  } },      { 48  ,{96   ,105  ,144  } },      { 56  ,{112  ,121  ,168  } },      { 56  ,{112  ,122  ,168  } },      { 64  ,{128  ,139  ,192  } },      { 64  ,{128  ,140  ,192  } },      { 80  ,{160  ,174  ,240  } },      { 80  ,{160  ,175  ,240  } },      { 96  ,{192  ,208  ,288  } },      { 96  ,{192  ,209  ,288  } },      { 112 ,{224  ,243  ,336  } },      { 112 ,{224  ,244  ,336  } },      { 128 ,{256  ,278  ,384  } },      { 128 ,{256  ,279  ,384  } },      { 160 ,{320  ,348  ,480  } },      { 160 ,{320  ,349  ,480  } },      { 192 ,{384  ,417  ,576  } },      { 192 ,{384  ,418  ,576  } },      { 224 ,{448  ,487  ,672  } },      { 224 ,{448  ,488  ,672  } },      { 256 ,{512  ,557  ,768  } },      { 256 ,{512  ,558  ,768  } },      { 320 ,{640  ,696  ,960  } },      { 320 ,{640  ,697  ,960  } },      { 384 ,{768  ,835  ,1152 } },      { 384 ,{768  ,836  ,1152 } },      { 448 ,{896  ,975  ,1344 } },      { 448 ,{896  ,976  ,1344 } },      { 512 ,{1024 ,1114 ,1536 } },      { 512 ,{1024 ,1115 ,1536 } },      { 576 ,{1152 ,1253 ,1728 } },      { 576 ,{1152 ,1254 ,1728 } },      { 640 ,{1280 ,1393 ,1920 } },      { 640 ,{1280 ,1394 ,1920 } }};/* Audio channel modes */static short mpeg3_ac3_acmodes[] = {2, 1, 2, 3, 3, 4, 4, 5};static int mpeg3_atrack_get_ac3_info (mpeg3_atrack_t *atrack){  uint16_t code, mask;  unsigned int sampling_freq_code, framesize_code;  unsigned int acmod;  unsigned int skipbits;  mpeg3_demuxer_t *demux;  demux = atrack->demuxer;  code = mpeg3demux_read_char(demux);  do {    code &= 0xff;    code <<= 8;    code |= mpeg3demux_read_char(demux);  } while (!mpeg3demux_eof(demux) && code != MPEG3_AC3_START_CODE);  if (mpeg3demux_eof(demux)) return -1;    // 2 bytes CRC  mpeg3demux_read_char(demux);  mpeg3demux_read_char(demux);    code = mpeg3demux_read_char(demux);  sampling_freq_code = (code >> 6) & 0x3;  framesize_code = code & 0x3f;  // bsid and bsmod  mpeg3demux_read_char(demux);  // acmod is 3 bits  code = mpeg3demux_read_char(demux) << 8;  code |= mpeg3demux_read_char(demux);  if (mpeg3demux_eof(demux)) return -1;  atrack->sample_rate =     mpeg3_ac3_samplerates[sampling_freq_code];  atrack->framesize =     2 * framesize_codes[framesize_code].frm_size[sampling_freq_code];  atrack->samples_per_frame = 1536; // fixed amount from rfc draft  acmod = (code >> 13) & 0x7;  atrack->channels = mpeg3_ac3_acmodes[acmod];  skipbits = 3;  if ((acmod & 0x1) && (acmod != 1)) {    skipbits += 2;  }  if (acmod & 0x4) skipbits += 2;  if (acmod == 0x2) skipbits += 2;  mask = 1 << (15 - skipbits);  if ((code & mask) != 0) atrack->channels++;  return 0;}static int mpeg3_atrack_suck_frame_info (mpeg3_atrack_t *atrack){  mpeg3_demuxer_t *demux;  demux = atrack->demuxer;  if (atrack->format == AUDIO_UNKNOWN) {    uint16_t code;    code = mpeg3demux_read_char(demux);    code <<= 8;    code |= mpeg3demux_read_char(demux);    if (code == MPEG3_AC3_START_CODE) {      atrack->format = AUDIO_AC3;    } else if ((code & 0xfff8) == 0xfff8) {      atrack->format = AUDIO_MPEG;    } else {      atrack->format = AUDIO_AAC;    }    code = mpeg3demux_read_prev_char(demux);    code = mpeg3demux_read_prev_char(demux);  }    switch (atrack->format) {  case AUDIO_PCM:    atrack->sample_rate = 48000;    atrack->channels = 2;    atrack->framesize = 0x7db;    break;  case AUDIO_MPEG:    if (mpeg3_atrack_get_mp3_info(atrack) < 0) return -1;    break;  case AUDIO_AC3:    if (mpeg3_atrack_get_ac3_info(atrack) < 0) return -1;    break;  case AUDIO_AAC:    if (mpeg3_atrack_get_aac_info(atrack) < 0) return -1;    break;  }  mpeg3demux_seek_start(demux);}mpeg3_atrack_t* mpeg3_new_atrack(mpeg3_t *file, 	int stream_id, 	int format, 	mpeg3_demuxer_t *demuxer,	int number){	mpeg3_atrack_t *new_atrack;	new_atrack = calloc(1, sizeof(mpeg3_atrack_t));	new_atrack->file = file;	new_atrack->channels = 0;	new_atrack->sample_rate = 0;	new_atrack->total_samples = 0;	new_atrack->percentage_seek = -1;	new_atrack->demuxer = mpeg3_new_demuxer(file, 1, 0, stream_id);	if(new_atrack->demuxer) mpeg3demux_copy_titles(new_atrack->demuxer, demuxer);	new_atrack->current_position = 0;	new_atrack->format = format;	if (mpeg3_atrack_suck_frame_info(new_atrack) < 0 ||	    new_atrack->format == AUDIO_UNKNOWN) {/* Failed */	  mpeg3_delete_atrack(file, new_atrack);	  new_atrack = NULL;	}	//printf("mpeg3 demux length %g\n", mpeg3demux_length(new_atrack->demuxer));// Copy pointers	if(file->sample_offsets)	{		new_atrack->sample_offsets = file->sample_offsets[number];		new_atrack->total_sample_offsets = file->total_sample_offsets[number];		new_atrack->total_frames = new_atrack->total_sample_offsets / 		  new_atrack->samples_per_frame;	} else {	  double time;	  if (new_atrack->samples_per_frame != 0) {	    time = mpeg3demux_length(new_atrack->demuxer);	    time *= new_atrack->sample_rate;	    time /= new_atrack->samples_per_frame;	    new_atrack->total_frames = (uint32_t)time;	    new_atrack->total_sample_offsets = new_atrack->total_frames * 	      new_atrack->samples_per_frame;	    //printf("total frames %d\n", new_atrack->total_frames);	  } else {	    new_atrack->total_frames = 0;	    new_atrack->total_sample_offsets = 0;	  }	} 	//printf("total offsets %ld\n", new_atrack->total_sample_offsets);	return new_atrack;}int mpeg3_delete_atrack(mpeg3_t *file, mpeg3_atrack_t *atrack){	if(atrack->demuxer) mpeg3_delete_demuxer(atrack->demuxer);	free(atrack);	return 0;}static int mpeg3_atrack_check_length (unsigned char **output, 				      uint32_t cmplen,				      uint32_t *maxlen){  if (cmplen > *maxlen) {    *output = (unsigned char *)realloc(*output, cmplen);    if (*output == NULL) return -1;    *maxlen = cmplen;  }  return 0;}   static int mpeg3_atrack_read_pcm_frame (mpeg3_atrack_t *atrack,					unsigned char **output,					uint32_t *len,					uint32_t *maxlen){  uint16_t code;  mpeg3_demuxer_t *demux;  uint32_t frame_sample;  int ret;  demux = atrack->demuxer;  code = mpeg3demux_read_char(demux);  do {    code <<= 8;    code |= mpeg3demux_read_char(demux);  } while (!mpeg3demux_eof(demux) && code != MPEG3_PCM_START_CODE);  if (mpeg3demux_eof(demux)) return -1;  frame_sample = (atrack->framesize - 3) / atrack->channels / 2;  *len = frame_sample * atrack->channels * (sizeof(uint16_t));  if (mpeg3_atrack_check_length(output, *len, maxlen) < 0) return -1;   ret = mpeg3demux_read_data(demux, *output, *len);  if (ret != *len) return -1;  return 0;}static int mpeg3_atrack_read_mp3_frame (mpeg3_atrack_t *atrack,					unsigned char **output,					uint32_t *len,					uint32_t *maxlen){  uint8_t code[4];  mpeg3_demuxer_t *demux;  uint32_t frame_samples;  int ret;  MP4AV_Mp3Header temp;  int cnt = 1;  demux = atrack->demuxer;  code[1] = mpeg3demux_read_char(demux);  do {    code[0] = code[1];    code[1] = mpeg3demux_read_char(demux);    cnt++;  } while (!mpeg3demux_eof(demux) && 	   (code[0] != 0xff || ((code[1] & 0xe0) != 0xe0)));  if (mpeg3demux_eof(demux)) return -1;  code[2] = mpeg3demux_read_char(demux);  code[3] = mpeg3demux_read_char(demux);  temp = MP4AV_Mp3HeaderFromBytes(code);  *len = MP4AV_Mp3GetFrameSize(temp);  //printf("header is %08x framesize %d\n", temp, *len);  if (mpeg3_atrack_check_length(output, *len, maxlen) < 0) return -1;  memcpy(*output, code, 4);  ret = mpeg3demux_read_data(demux, *output + 4, *len - 4);  if (ret != *len - 4) return -1;  return 0;}static int mpeg3_atrack_read_aac_frame (mpeg3_atrack_t *atrack,					unsigned char **output, 					uint32_t *len, 					uint32_t *maxlen){  mpeg3_demuxer_t *demux;  uint16_t hdr_size, ix;  uint32_t bytes;  unsigned char hdr[16];  int ret;  demux = atrack->demuxer;  hdr[1] = mpeg3demux_read_char(demux);  do {    hdr[0] = hdr[1];    hdr[1] = mpeg3demux_read_char(demux);  } while (((hdr[0] != 0xff) || 	   ((hdr[1] & 0xf0) != 0xf0)) && 	   !mpeg3demux_eof(demux));  bytes = atrack->channels * sizeof(uint16_t) * atrack->samples_per_frame;  if (mpeg3demux_eof(demux)) return -1;  hdr_size = MP4AV_AdtsGetHeaderByteSize(hdr);  if (hdr_size > sizeof(hdr)) return -1;  for (ix = 2; ix < hdr_size; ix++) {    hdr[ix] = mpeg3demux_read_char(demux);  }  if (mpeg3demux_eof(demux)) return -1;  bytes = MP4AV_AdtsGetFrameSize(hdr);  *len = bytes;  if (mpeg3_atrack_check_length(output, *len, maxlen) < 0) return -1;  memcpy(*output, hdr, hdr_size);  ret = mpeg3demux_read_data(demux, *output + hdr_size, *len - hdr_size);  if (ret != *len - hdr_size) return -1;  return 0;}static int mpeg3_atrack_read_ac3_frame (mpeg3_atrack_t *atrack,					unsigned char **output, 					uint32_t *len, 					uint32_t *maxlen){  uint16_t code;  mpeg3_demuxer_t *demux;  int ret;  demux = atrack->demuxer;  code = mpeg3demux_read_char(demux);  do {    code &= 0xff;    code <<= 8;    code |= mpeg3demux_read_char(demux);  } while (!mpeg3demux_eof(demux) && code != MPEG3_AC3_START_CODE);  if (mpeg3demux_eof(demux)) return -1;  *len = atrack->framesize;  if (mpeg3_atrack_check_length(output, *len, maxlen) < 0) return -1;  *output[0] = code >> 8;  *output[1] = code & 0xff;  ret = mpeg3demux_read_data(demux, *output + 2, *len - 2);  if (ret != *len - 2) return -1;  return 0;}int mpeg3_atrack_read_frame (mpeg3_atrack_t *atrack, 			     unsigned char **output,			     uint32_t *len,			     uint32_t *maxlen){  if (atrack->percentage_seek >= 0) {    mpeg3demux_seek_percentage(atrack->demuxer, atrack->percentage_seek);    atrack->percentage_seek = -1;  }  switch (atrack->format) {  case AUDIO_PCM:    return (mpeg3_atrack_read_pcm_frame(atrack, output, len, maxlen));  case AUDIO_MPEG:    return (mpeg3_atrack_read_mp3_frame(atrack, output, len, maxlen));  case AUDIO_AC3:    return (mpeg3_atrack_read_ac3_frame(atrack, output, len, maxlen));  case AUDIO_AAC:    return (mpeg3_atrack_read_aac_frame(atrack, output, len, maxlen));  }  return -1;}int mpeg3atrack_seek_percentage(mpeg3_atrack_t *atrack, double percentage){  atrack->percentage_seek = percentage;  return 0;}

⌨️ 快捷键说明

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