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

📄 rmff.c

📁 mplayer播放器的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * This file was ported to MPlayer from xine CVS rmff.c,v 1.3 2002/12/24 01:30:22 *//* * Copyright (C) 2002 the xine project * * This file is part of xine, a free video player. * * xine 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. * * xine 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 * * * functions for real media file format * adopted from joschkas real tools */#include "rmff.h"#include "xbuffer.h"#include "mp_msg.h"#include "libavutil/intreadwrite.h"/*#define LOG*/static void hexdump (const char *buf, int length) {  int i;  printf ("rmff: ascii>");  for (i = 0; i < length; i++) {    unsigned char c = buf[i];    if ((c >= 32) && (c <= 128))      printf ("%c", c);    else      printf (".");  }  printf ("\n");  printf ("rmff: hexdump> ");  for (i = 0; i < length; i++) {    unsigned char c = buf[i];    printf ("%02x", c);    if ((i % 16) == 15)      printf ("\nrmff:         ");    if ((i % 2) == 1)      printf (" ");  }  printf ("\n");}/* * writes header data to a buffer */static int rmff_dump_fileheader(rmff_fileheader_t *fileheader, char *buffer, int bufsize) {  if (!fileheader) return 0;  if (bufsize < RMFF_FILEHEADER_SIZE)    return -1;  AV_WB32(buffer, fileheader->object_id);  AV_WB32(buffer+4, fileheader->size);  AV_WB16(buffer+8, fileheader->object_version);  AV_WB32(buffer+10, fileheader->file_version);  AV_WB32(buffer+14, fileheader->num_headers);  return RMFF_FILEHEADER_SIZE;}static int rmff_dump_prop(rmff_prop_t *prop, char *buffer, int bufsize) {  if (!prop) return 0;  if (bufsize < RMFF_PROPHEADER_SIZE)    return -1;  AV_WB32(buffer, prop->object_id);  AV_WB32(buffer+4, prop->size);  AV_WB16(buffer+8, prop->object_version);  AV_WB32(buffer+10, prop->max_bit_rate);  AV_WB32(buffer+14, prop->avg_bit_rate);  AV_WB32(buffer+18, prop->max_packet_size);  AV_WB32(buffer+22, prop->avg_packet_size);  AV_WB32(buffer+26, prop->num_packets);  AV_WB32(buffer+30, prop->duration);  AV_WB32(buffer+34, prop->preroll);  AV_WB32(buffer+38, prop->index_offset);  AV_WB32(buffer+42, prop->data_offset);  AV_WB16(buffer+46, prop->num_streams);  AV_WB16(buffer+48, prop->flags);  return RMFF_PROPHEADER_SIZE;}static int rmff_dump_mdpr(rmff_mdpr_t *mdpr, char *buffer, int bufsize) {  int s1, s2, s3;  if (!mdpr) return 0;  if (!(bufsize > RMFF_MDPRHEADER_SIZE + mdpr->stream_name_size + mdpr->mime_type_size &&        (unsigned)bufsize - RMFF_MDPRHEADER_SIZE - mdpr->stream_name_size - mdpr->mime_type_size > mdpr->type_specific_len))    return -1;  AV_WB32(buffer, mdpr->object_id);  AV_WB32(buffer+4, mdpr->size);  AV_WB16(buffer+8, mdpr->object_version);  AV_WB16(buffer+10, mdpr->stream_number);  AV_WB32(buffer+12, mdpr->max_bit_rate);  AV_WB32(buffer+16, mdpr->avg_bit_rate);  AV_WB32(buffer+20, mdpr->max_packet_size);  AV_WB32(buffer+24, mdpr->avg_packet_size);  AV_WB32(buffer+28, mdpr->start_time);  AV_WB32(buffer+32, mdpr->preroll);  AV_WB32(buffer+36, mdpr->duration);  buffer[40] = mdpr->stream_name_size;  s1=mdpr->stream_name_size;  memcpy(&buffer[41], mdpr->stream_name, s1);  buffer[41+s1] = mdpr->mime_type_size;  s2=mdpr->mime_type_size;  memcpy(&buffer[42+s1], mdpr->mime_type, s2);    AV_WB32(buffer+42+s1+s2, mdpr->type_specific_len);  s3=mdpr->type_specific_len;  memcpy(&buffer[46+s1+s2], mdpr->type_specific_data, s3);  return RMFF_MDPRHEADER_SIZE + s1 + s2 + s3;}static int rmff_dump_cont(rmff_cont_t *cont, char *buffer, int bufsize) {  int p;  if (!cont) return 0;  if (bufsize < RMFF_CONTHEADER_SIZE + cont->title_len + cont->author_len +      cont->copyright_len + cont->comment_len)    return -1;  AV_WB32(buffer, cont->object_id);  AV_WB32(buffer+4, cont->size);  AV_WB16(buffer+8, cont->object_version);    AV_WB16(buffer+10, cont->title_len);  memcpy(&buffer[12], cont->title, cont->title_len);  p=12+cont->title_len;  AV_WB16(buffer+p, cont->author_len);  memcpy(&buffer[p+2], cont->author, cont->author_len);  p+=2+cont->author_len;  AV_WB16(buffer+p, cont->copyright_len);  memcpy(&buffer[p+2], cont->copyright, cont->copyright_len);  p+=2+cont->copyright_len;  AV_WB16(buffer+p, cont->comment_len);  memcpy(&buffer[p+2], cont->comment, cont->comment_len);  return RMFF_CONTHEADER_SIZE + cont->title_len + cont->author_len +         cont->copyright_len + cont->comment_len;}static int rmff_dump_dataheader(rmff_data_t *data, char *buffer, int bufsize) {  if (!data) return 0;  if (bufsize < RMFF_DATAHEADER_SIZE)    return -1;  AV_WB32(buffer, data->object_id);  AV_WB32(buffer+4, data->size);  AV_WB16(buffer+8, data->object_version);  AV_WB32(buffer+10, data->num_packets);  AV_WB32(buffer+14, data->next_data_header);  return RMFF_DATAHEADER_SIZE;}int rmff_dump_header(rmff_header_t *h, char *buffer, int max) {  int written=0, size;  rmff_mdpr_t **stream=h->streams;  if ((size=rmff_dump_fileheader(h->fileheader, &buffer[written], max)) < 0)    goto buftoosmall;  written+=size;  max -= size;  if ((size=rmff_dump_prop(h->prop, &buffer[written], max)) < 0)    goto buftoosmall;  written+=size;  max -= size;  if ((size=rmff_dump_cont(h->cont, &buffer[written], max)) < 0)    goto buftoosmall;  written+=size;  max -= size;  if (stream)  {    while(*stream)    {      if ((size=rmff_dump_mdpr(*stream, &buffer[written], max)) < 0)        goto buftoosmall;      written+=size;      max -= size;      stream++;    }  }      if ((size=rmff_dump_dataheader(h->data, &buffer[written], max)) < 0)    goto buftoosmall;  written+=size;  return written;buftoosmall:  mp_msg(MSGT_STREAM, MSGL_ERR, "rmff_dumpheader: buffer too small, aborting. Please report\n");  return -1;}void rmff_dump_pheader(rmff_pheader_t *h, char *data) {  data[0]=(h->object_version>>8) & 0xff;  data[1]=h->object_version & 0xff;  data[2]=(h->length>>8) & 0xff;  data[3]=h->length & 0xff;  data[4]=(h->stream_number>>8) & 0xff;  data[5]=h->stream_number & 0xff;  data[6]=(h->timestamp>>24) & 0xff;  data[7]=(h->timestamp>>16) & 0xff;  data[8]=(h->timestamp>>8) & 0xff;  data[9]=h->timestamp & 0xff;  data[10]=h->reserved;  data[11]=h->flags;}static rmff_fileheader_t *rmff_scan_fileheader(const char *data) {  rmff_fileheader_t *fileheader=malloc(sizeof(rmff_fileheader_t));  fileheader->object_id=AV_RB32(data);  fileheader->size=AV_RB32(&data[4]);  fileheader->object_version=AV_RB16(&data[8]);  if (fileheader->object_version != 0)  {    mp_msg(MSGT_STREAM, MSGL_WARN, "warning: unknown object version in .RMF: 0x%04x\n",      fileheader->object_version);  }  fileheader->file_version=AV_RB32(&data[10]);  fileheader->num_headers=AV_RB32(&data[14]);  return fileheader;}static rmff_prop_t *rmff_scan_prop(const char *data) {  rmff_prop_t *prop=malloc(sizeof(rmff_prop_t));  prop->object_id=AV_RB32(data);  prop->size=AV_RB32(&data[4]);  prop->object_version=AV_RB16(&data[8]);  if (prop->object_version != 0)  {    mp_msg(MSGT_STREAM, MSGL_WARN, "warning: unknown object version in PROP: 0x%04x\n",      prop->object_version);  }  prop->max_bit_rate=AV_RB32(&data[10]);  prop->avg_bit_rate=AV_RB32(&data[14]);  prop->max_packet_size=AV_RB32(&data[18]);  prop->avg_packet_size=AV_RB32(&data[22]);  prop->num_packets=AV_RB32(&data[26]);  prop->duration=AV_RB32(&data[30]);  prop->preroll=AV_RB32(&data[34]);  prop->index_offset=AV_RB32(&data[38]);  prop->data_offset=AV_RB32(&data[42]);  prop->num_streams=AV_RB16(&data[46]);  prop->flags=AV_RB16(&data[48]);  return prop;}static rmff_mdpr_t *rmff_scan_mdpr(const char *data) {  rmff_mdpr_t *mdpr=malloc(sizeof(rmff_mdpr_t));  mdpr->object_id=AV_RB32(data);  mdpr->size=AV_RB32(&data[4]);  mdpr->object_version=AV_RB16(&data[8]);  if (mdpr->object_version != 0)  {    mp_msg(MSGT_STREAM, MSGL_WARN, "warning: unknown object version in MDPR: 0x%04x\n",      mdpr->object_version);  }  mdpr->stream_number=AV_RB16(&data[10]);  mdpr->max_bit_rate=AV_RB32(&data[12]);  mdpr->avg_bit_rate=AV_RB32(&data[16]);  mdpr->max_packet_size=AV_RB32(&data[20]);  mdpr->avg_packet_size=AV_RB32(&data[24]);  mdpr->start_time=AV_RB32(&data[28]);  mdpr->preroll=AV_RB32(&data[32]);  mdpr->duration=AV_RB32(&data[36]);    mdpr->stream_name_size=data[40];  mdpr->stream_name=malloc(mdpr->stream_name_size+1);  memcpy(mdpr->stream_name, &data[41], mdpr->stream_name_size);  mdpr->stream_name[mdpr->stream_name_size]=0;    mdpr->mime_type_size=data[41+mdpr->stream_name_size];  mdpr->mime_type=malloc(mdpr->mime_type_size+1);  memcpy(mdpr->mime_type, &data[42+mdpr->stream_name_size], mdpr->mime_type_size);  mdpr->mime_type[mdpr->mime_type_size]=0;    mdpr->type_specific_len=AV_RB32(&data[42+mdpr->stream_name_size+mdpr->mime_type_size]);  mdpr->type_specific_data=malloc(mdpr->type_specific_len);  memcpy(mdpr->type_specific_data,       &data[46+mdpr->stream_name_size+mdpr->mime_type_size], mdpr->type_specific_len);    return mdpr;}static rmff_cont_t *rmff_scan_cont(const char *data) {  rmff_cont_t *cont=malloc(sizeof(rmff_cont_t));  int pos;  cont->object_id=AV_RB32(data);  cont->size=AV_RB32(&data[4]);  cont->object_version=AV_RB16(&data[8]);  if (cont->object_version != 0)  {    mp_msg(MSGT_STREAM, MSGL_WARN, "warning: unknown object version in CONT: 0x%04x\n",      cont->object_version);  }  cont->title_len=AV_RB16(&data[10]);  cont->title=malloc(cont->title_len+1);  memcpy(cont->title, &data[12], cont->title_len);  cont->title[cont->title_len]=0;  pos=cont->title_len+12;  cont->author_len=AV_RB16(&data[pos]);  cont->author=malloc(cont->author_len+1);  memcpy(cont->author, &data[pos+2], cont->author_len);  cont->author[cont->author_len]=0;  pos=pos+2+cont->author_len;  cont->copyright_len=AV_RB16(&data[pos]);  cont->copyright=malloc(cont->copyright_len+1);  memcpy(cont->copyright, &data[pos+2], cont->copyright_len);  cont->copyright[cont->copyright_len]=0;  pos=pos+2+cont->copyright_len;  cont->comment_len=AV_RB16(&data[pos]);  cont->comment=malloc(cont->comment_len+1);  memcpy(cont->comment, &data[pos+2], cont->comment_len);  cont->comment[cont->comment_len]=0;  return cont;}static rmff_data_t *rmff_scan_dataheader(const char *data) {  rmff_data_t *dh=malloc(sizeof(rmff_data_t));  dh->object_id=AV_RB32(data);  dh->size=AV_RB32(&data[4]);  dh->object_version=AV_RB16(&data[8]);  if (dh->object_version != 0)  {    mp_msg(MSGT_STREAM, MSGL_WARN, "warning: unknown object version in DATA: 0x%04x\n",      dh->object_version);  }  dh->num_packets=AV_RB32(&data[10]);  dh->next_data_header=AV_RB32(&data[14]);  return dh;} rmff_header_t *rmff_scan_header(const char *data) {	rmff_header_t *header=malloc(sizeof(rmff_header_t));	rmff_mdpr_t   *mdpr=NULL;	int           chunk_size;	uint32_t      chunk_type;  const char    *ptr=data;  int           i;  header->fileheader=NULL;	header->prop=NULL;	header->cont=NULL;	header->data=NULL;  chunk_type = AV_RB32(ptr);  if (chunk_type != RMF_TAG)  {    mp_msg(MSGT_STREAM, MSGL_ERR, "rmff: not an real media file header (.RMF tag not found).\n");    free(header);    return NULL;  }  header->fileheader=rmff_scan_fileheader(ptr);  ptr += header->fileheader->size;		header->streams=malloc(sizeof(rmff_mdpr_t*)*(header->fileheader->num_headers));  for (i=0; i<header->fileheader->num_headers; i++) {    header->streams[i]=NULL;  }    for (i=1; i<header->fileheader->num_headers; i++) {    chunk_type = AV_RB32(ptr);      if (ptr[0] == 0)    {      mp_msg(MSGT_STREAM, MSGL_WARN, "rmff: warning: only %d of %d header found.\n", i, header->fileheader->num_headers);      break;    }        chunk_size=1;    switch (chunk_type) {    case PROP_TAG:      header->prop=rmff_scan_prop(ptr);      chunk_size=header->prop->size;      break;    case MDPR_TAG:

⌨️ 快捷键说明

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