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

📄 avi_strl.c

📁 这个库实现了录象功能
💻 C
字号:
/******************************************************************************* avi_strl.c libquicktime - A library for reading and writing quicktime/avi/mp4 files. http://libquicktime.sourceforge.net Copyright (C) 2002 Heroine Virtual Ltd. Copyright (C) 2002-2007 Members of the libquicktime project. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA*******************************************************************************/ #include "lqt_private.h"#include <stdlib.h>#include <string.h>// Update during close:// length// samples per chunk#define PADDING_SIZE 2048 /* Must be increased for codecs with really                             large extradata (like Vorbis in AVI),                             but we won't do such nonsense, will we? */quicktime_strl_t* quicktime_new_strl(){	quicktime_strl_t *strl = calloc(1, sizeof(quicktime_strl_t));	return strl;}void quicktime_init_strl(quicktime_t *file,                          quicktime_audio_map_t *atrack,                         quicktime_video_map_t *vtrack,                         quicktime_trak_t *trak,                         quicktime_strl_t *strl)  {  quicktime_atom_t list_atom;  quicktime_atom_t junk_atom;  int i;  trak->strl = strl;  /* Construct tag */  if(vtrack)    {    strl->tag[0] = '0' + (trak->tkhd.track_id - 1) / 10;    strl->tag[1] = '0' + (trak->tkhd.track_id - 1) % 10;    strl->tag[2] = 'd';    strl->tag[3] = 'c';    }  else    if(atrack)      {      strl->tag[0] = '0' + (trak->tkhd.track_id - 1) / 10;      strl->tag[1] = '0' + (trak->tkhd.track_id - 1) % 10;      strl->tag[2] = 'w';      strl->tag[3] = 'b';      }  /* LIST 'strl' */  quicktime_atom_write_header(file, &list_atom, "LIST");  quicktime_write_char32(file, "strl");    /* vids */  if(vtrack)    {    strncpy(strl->strh.fccType, "vids", 4);    strncpy(strl->strh.fccHandler, trak->mdia.minf.stbl.stsd.table[0].format, 4);        /* framerate denominator */    strl->strh.dwScale = trak->mdia.minf.stbl.stts.table[0].sample_duration;    /* framerate numerator */    strl->strh.dwRate  = trak->mdia.mdhd.time_scale;    strl->strh.dwQuality = 10000;    //    strl->strh.dwSampleSize = (int)(trak->tkhd.track_width * trak->tkhd.track_height) * 3;    strl->strh.rcFrame.right  = trak->tkhd.track_width;    strl->strh.rcFrame.bottom = trak->tkhd.track_height;        strl->is_video = 1;    }  else if(atrack)    {    strncpy(strl->strh.fccType, "auds", 4);    strl->strh.dwQuality = -1;    strl->is_audio = 1;    }  strl->strh_offset = quicktime_position(file);  quicktime_write_strh(file, &strl->strh);    /* strf */    if(vtrack)    {    strl->strf.bh.biSize = 40;    strl->strf.bh.biWidth = trak->tkhd.track_width;    strl->strf.bh.biHeight = trak->tkhd.track_height;    strl->strf.bh.biPlanes = 1;    strl->strf.bh.biBitCount = 24;    strncpy(strl->strf.bh.biCompression, trak->mdia.minf.stbl.stsd.table[0].format, 4);     strl->strf.bh.biSizeImage = trak->tkhd.track_width * trak->tkhd.track_height * 3; // biSizeImage    quicktime_write_strf_video(file, &strl->strf);    }  else if(atrack)    {    /* By now the codec is instantiated so the WAV ID is available. */    strl->strf.wf.type = LQT_WAVEFORMAT_WAVEFORMATEX;    strl->strf.wf.f.WAVEFORMAT.wFormatTag = atrack->wav_id;    strl->strf.wf.f.WAVEFORMAT.nChannels =      trak->mdia.minf.stbl.stsd.table[0].channels;    strl->strf.wf.f.WAVEFORMAT.nSamplesPerSec = atrack->samplerate;    quicktime_write_strf_audio(file, &strl->strf);    }  strl->end_pos = quicktime_position(file);      /* We write junk for 2 reasons:   *   *  1. The strf chunks might grow   *  2. The indx chunk might come as well   */    quicktime_atom_write_header(file, &junk_atom, "JUNK");  for(i = 0; i < PADDING_SIZE; i ++)    quicktime_write_char(file, 0);  quicktime_atom_write_footer(file, &junk_atom);    /* Initialize super index */  if(file->file_type == LQT_FILE_AVI_ODML)    quicktime_init_indx(file, &strl->indx, strl);    quicktime_atom_write_footer(file, &list_atom);  }void quicktime_delete_strl(quicktime_strl_t *strl)  {  if(strl->is_video) quicktime_strf_delete_video(&strl->strf);  if(strl->is_audio) quicktime_strf_delete_audio(&strl->strf);  quicktime_delete_indx(&strl->indx);  free(strl);  }void quicktime_read_strl(quicktime_t *file,                         quicktime_strl_t *strl,                          quicktime_atom_t *parent_atom)  {  quicktime_atom_t leaf_atom;    /* AVI translation: */  /* vids -> trak */  /* auds -> trak */  /* Only one track is in each strl object */  do    {    quicktime_atom_read_header(file, &leaf_atom);    // strh    if(quicktime_atom_is(&leaf_atom, "strh"))      {      quicktime_read_strh(file, &strl->strh, &leaf_atom);      }    else if(quicktime_atom_is(&leaf_atom, "strf"))      {      if(quicktime_match_32(strl->strh.fccType, "vids"))        quicktime_read_strf_video(file, &strl->strf, &leaf_atom);      else if(quicktime_match_32(strl->strh.fccType, "auds"))        quicktime_read_strf_audio(file, &strl->strf, &leaf_atom);      }    else if(quicktime_atom_is(&leaf_atom, "indx"))      // Super index.      // Read the super index + all the partial indexes now      {      quicktime_read_indx(file, strl, &leaf_atom);      strl->have_indx = 1;      }    quicktime_atom_skip(file, &leaf_atom);    } while(quicktime_position(file) < parent_atom->end);    }void quicktime_strl_2_qt(quicktime_t *file,                         quicktime_strl_t *strl)  {  // These are 0 if no track is currently being processed.  // Set to 1 if audio or video track is being processed.  uint8_t codec[4] = { 0x00, 0x00, 0x00, 0x00 };  //	int denominator;  //	int numerator;  int frame_duration = 0;  int timescale = 0;  int width = 0;  int height = 0;  int depth = 0;  int frames = 0;  int bytes_per_sample = 0;  int bits_per_sample = 0;  int samples;  //	int samples_per_chunk = 0;  int channels = 0;  int sample_rate = 0;  //	int bytes_per_second;  quicktime_trak_t *trak = 0;    /* AVI translation: */  /* vids -> trak */  /* auds -> trak */  /* Only one track is in each strl object */      if(quicktime_match_32(strl->strh.fccType, "vids"))    {    /* Video */        trak = quicktime_add_trak(file);    trak->strl = strl;    width = 0;    height = 0;    depth = 24;    frames = 0;    strl->is_video = 1;            trak->tkhd.track_id = file->moov.mvhd.next_track_id;    file->moov.mvhd.next_track_id++;        if(strl->strh.dwScale != 0)      {      timescale = strl->strh.dwRate;      frame_duration = strl->strh.dwScale;      //  frame_rate = (double)strl->dwRate / strl->dwScale;      }    else      {      // frame_rate = strl->dwRate;      timescale = strl->strh.dwRate;      frame_duration = 1;      }    frames = strl->strh.dwLength;      // dwLength    width  = strl->strf.bh.biWidth;    height = strl->strf.bh.biHeight;        /* Depth in bits */    depth = strl->strf.bh.biBitCount;        /* Generate quicktime structures */    quicktime_trak_init_video(file,                               trak,                               width,                               height,                               frame_duration,                              timescale,                              strl->strf.bh.biCompression);    quicktime_mhvd_init_video(file,                               &file->moov.mvhd,                               timescale);    trak->mdia.mdhd.duration = frames;    //			trak->mdia.mdhd.time_scale = 1;    trak->mdia.minf.stbl.stsd.table[0].depth = depth;        }  else if(quicktime_match_32(strl->strh.fccType, "auds"))    {    trak = quicktime_add_trak(file);    trak->strl = strl;    channels = 2;    sample_rate = 0;    strl->is_audio = 1;        trak->tkhd.track_id = file->moov.mvhd.next_track_id;    file->moov.mvhd.next_track_id++;    samples = strl->strh.dwLength;           // dwLength    bytes_per_sample = strl->strh.dwSampleSize; // dwSampleSize    if(strl->strf.wf.type != LQT_WAVEFORMAT_WAVEFORMAT)      {      bits_per_sample = strl->strf.wf.f.PCMWAVEFORMAT.wBitsPerSample;      }    else      bits_per_sample = 8;            channels       = strl->strf.wf.f.WAVEFORMAT.nChannels;    sample_rate    = strl->strf.wf.f.WAVEFORMAT.nSamplesPerSec;        quicktime_trak_init_audio(file,                               trak,                               channels,                               sample_rate,                               bits_per_sample,                               (char*)codec);        // We store a constant samples per chunk based on the     // packet size if sample_size zero    // and calculate the samples per chunk based on the chunk size if sample_size     // is nonzero.    //		trak->mdia.minf.stbl.stsd.table[0].sample_size = bytes_per_sample;    trak->mdia.minf.stbl.stsd.table[0].compression_id =      strl->strf.wf.f.WAVEFORMAT.wFormatTag;        /* Synthesize stsc table for constant samples per chunk */    if(!bytes_per_sample)      {      /* Should be enough entries allocated in quicktime_stsc_init_table */      trak->mdia.minf.stbl.stsc.table[0].samples = strl->strh.dwScale;      trak->mdia.minf.stbl.stsc.total_entries = 1;      }    }  }void quicktime_finalize_strl(quicktime_t *file, quicktime_trak_t * trak,                             quicktime_strl_t *strl)  {  int i;  quicktime_atom_t junk_atom;    int64_t old_pos, end_pos;  /* Rewrite stream headers */  if(!strl->strh.dwLength)    strl->strh.dwLength = quicktime_track_samples(file, trak);    //  if(trak->mdia.minf.is_audio)  //    strl->strh.dwSuggestedBufferSize = strl->strf.wf.f.WAVEFORMAT.nAvgBytesPerSec / 2;    old_pos = quicktime_position(file);   quicktime_set_position(file, strl->strh_offset);  quicktime_write_strh(file, &strl->strh);  if(trak->mdia.minf.is_video)    {    quicktime_write_strf_video(file, &strl->strf);    }  else if(trak->mdia.minf.is_audio)    {    quicktime_write_strf_audio(file, &strl->strf);    }  end_pos = quicktime_position(file);    // Finalize super indexes  if(file->file_type == LQT_FILE_AVI_ODML)    strl->indx.offset = end_pos;    quicktime_atom_write_header(file, &junk_atom, "JUNK");  for(i = 0; i < PADDING_SIZE - (end_pos - strl->end_pos); i ++)    quicktime_write_char(file, 0);  quicktime_atom_write_footer(file, &junk_atom);    strl->indx.size = quicktime_position(file) - strl->indx.offset;  }void quicktime_strl_dump(quicktime_strl_t *strl)  {  lqt_dump("strl\n");  quicktime_strh_dump(&strl->strh);  if(!strncmp(strl->strh.fccType, "auds", 4))    quicktime_strf_dump_audio(&strl->strf);  if(!strncmp(strl->strh.fccType, "vids", 4))    quicktime_strf_dump_video(&strl->strf);  if(strl->have_indx)    {    quicktime_indx_dump(&strl->indx);    }  }

⌨️ 快捷键说明

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