demux_lavf.c
来自「君正早期ucos系统(只有早期的才不没有打包成库),MPLAYER,文件系统,图」· C语言 代码 · 共 714 行 · 第 1/2 页
C
714 行
/* Copyright (C) 2004 Michael Niedermayer <michaelni@gmx.at> 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA*/// #include <mplaylib.h>#include <mplaylib.h>// #include <mplaylib.h>#include "config.h"#include "mp_msg.h"#include "help_mp.h"#include "stream/stream.h"#include "demuxer.h"#include "stheader.h"#include "m_option.h"#include "libvo/sub.h"#ifdef USE_LIBAVFORMAT_SO#include <ffmpeg/avformat.h>#include <ffmpeg/avutil.h>#include <ffmpeg/opt.h>#else#include "avformat.h"#include "avutil.h"#include "avi.h"#include "opt.h"#endif#include "riff.h"#undef memcpy#define memcpy uc_memcpy#define PROBE_BUF_SIZE 2048extern char *audio_lang;static unsigned int opt_probesize = 0;static unsigned int opt_analyzeduration = 0;static char *opt_format;m_option_t lavfdopts_conf[] = { {"probesize", &(opt_probesize), CONF_TYPE_INT, CONF_RANGE, 32, INT_MAX, NULL}, {"format", &(opt_format), CONF_TYPE_STRING, 0, 0, 0, NULL}, {"analyzeduration", &(opt_analyzeduration), CONF_TYPE_INT, CONF_RANGE, 0, INT_MAX, NULL}, {NULL, NULL, 0, 0, 0, 0, NULL}};typedef struct lavf_priv_t{ AVInputFormat *avif; AVFormatContext *avfc; ByteIOContext pb; int audio_streams; int video_streams; int sub_streams; int64_t last_pts; int astreams[MAX_A_STREAMS]; int vstreams[MAX_V_STREAMS]; int sstreams[MAX_S_STREAMS];}lavf_priv_t;extern void print_wave_header(WAVEFORMATEX *h, int verbose_level);extern void print_video_header(BITMAPINFOHEADER *h, int verbose_level);static const AVCodecTag mp_wav_tags[] = { { CODEC_ID_ADPCM_4XM, MKTAG('4', 'X', 'M', 'A')}, { CODEC_ID_ADPCM_EA, MKTAG('A', 'D', 'E', 'A')}, { CODEC_ID_ADPCM_IMA_WS, MKTAG('A', 'I', 'W', 'S')}, { CODEC_ID_ADPCM_THP, MKTAG('T', 'H', 'P', 'A')}, { CODEC_ID_AMR_NB, MKTAG('n', 'b', 0, 0)}, { CODEC_ID_COOK, MKTAG('c', 'o', 'o', 'k')}, { CODEC_ID_DSICINAUDIO, MKTAG('D', 'C', 'I', 'A')}, { CODEC_ID_INTERPLAY_DPCM, MKTAG('I', 'N', 'P', 'A')}, { CODEC_ID_MUSEPACK7, MKTAG('M', 'P', 'C', ' ')}, { CODEC_ID_PCM_S24BE, MKTAG('i', 'n', '2', '4')}, { CODEC_ID_PCM_S16BE, MKTAG('t', 'w', 'o', 's')}, { CODEC_ID_PCM_S8, MKTAG('t', 'w', 'o', 's')}, { CODEC_ID_ROQ_DPCM, MKTAG('R', 'o', 'Q', 'A')}, { CODEC_ID_SHORTEN, MKTAG('s', 'h', 'r', 'n')}, { CODEC_ID_TTA, MKTAG('T', 'T', 'A', '1')}, { CODEC_ID_WAVPACK, MKTAG('W', 'V', 'P', 'K')}, { CODEC_ID_WESTWOOD_SND1, MKTAG('S', 'N', 'D', '1')}, { CODEC_ID_XAN_DPCM, MKTAG('A', 'x', 'a', 'n')}, { 0, 0 },};const struct AVCodecTag *mp_wav_taglists[] = {codec_wav_tags, mp_wav_tags, 0};static const AVCodecTag mp_bmp_tags[] = { { CODEC_ID_AMV, MKTAG('A', 'M', 'V', 'V')}, { CODEC_ID_BETHSOFTVID, MKTAG('B', 'E', 'T', 'H')}, { CODEC_ID_C93, MKTAG('C', '9', '3', 'V')}, { CODEC_ID_DSICINVIDEO, MKTAG('D', 'C', 'I', 'V')}, { CODEC_ID_DXA, MKTAG('D', 'X', 'A', '1')}, { CODEC_ID_FLIC, MKTAG('F', 'L', 'I', 'C')}, { CODEC_ID_IDCIN, MKTAG('I', 'D', 'C', 'I')}, { CODEC_ID_INTERPLAY_VIDEO, MKTAG('I', 'N', 'P', 'V')}, { CODEC_ID_ROQ, MKTAG('R', 'o', 'Q', 'V')}, { CODEC_ID_THP, MKTAG('T', 'H', 'P', 'V')}, { CODEC_ID_TIERTEXSEQVIDEO, MKTAG('T', 'S', 'E', 'Q')}, { CODEC_ID_TXD, MKTAG('T', 'X', 'D', 'V')}, { CODEC_ID_VMDVIDEO, MKTAG('V', 'M', 'D', 'V')}, { CODEC_ID_WS_VQA, MKTAG('V', 'Q', 'A', 'V')}, { CODEC_ID_XAN_WC3, MKTAG('W', 'C', '3', 'V')}, { CODEC_ID_NUV, MKTAG('N', 'U', 'V', '1')}, { 0, 0 },};const struct AVCodecTag *mp_bmp_taglists[] = {codec_bmp_tags, mp_bmp_tags, 0};static int mp_open(URLContext *h, const char *filename, int flags){ return 0;}static int mp_read(URLContext *h, unsigned char *buf, int size){ stream_t *stream = (stream_t*)h->priv_data; int ret; if(stream_eof(stream)) //needed? return -1; ret=stream_read(stream, buf, size); mp_msg(MSGT_HEADER,MSGL_DBG2,"%d=mp_read(%p, %p, %d), eof:%d\n", ret, h, buf, size, stream->eof); return ret;}static int mp_write(URLContext *h, unsigned char *buf, int size){ return -1;}static offset_t mp_seek(URLContext *h, offset_t pos, int whence){ stream_t *stream = (stream_t*)h->priv_data; mp_msg(MSGT_HEADER,MSGL_DBG2,"mp_seek(%p, %d, %d)\n", h, (int)pos, whence); if(whence == SEEK_CUR) pos +=stream_tell(stream); else if(whence == SEEK_END && stream->end_pos > 0) pos += stream->end_pos; else if(whence == SEEK_SET) pos += stream->start_pos; else if(whence == AVSEEK_SIZE && stream->end_pos > 0) return stream->end_pos - stream->start_pos; else return -1; if(pos<0) return -1; if(pos<stream->end_pos && stream->eof) stream_reset(stream); if(stream_seek(stream, pos)==0) return -1; return pos - stream->start_pos;}static int mp_close(URLContext *h){ return 0;}static URLProtocol mp_protocol = { "mp", mp_open, mp_read, mp_write, mp_seek, mp_close,};static void list_formats(void) { AVInputFormat *fmt; mp_msg(MSGT_DEMUX, MSGL_INFO, "Available lavf input formats:\n"); for (fmt = first_iformat; fmt; fmt = fmt->next) mp_msg(MSGT_DEMUX, MSGL_INFO, "%15s : %s\n", fmt->name, fmt->long_name);}static int lavf_check_file(demuxer_t *demuxer){ AVProbeData avpd; uint8_t buf[PROBE_BUF_SIZE]; lavf_priv_t *priv; F("1\n"); if(!demuxer->priv) demuxer->priv=calloc(sizeof(lavf_priv_t),1); F("2\n"); priv= demuxer->priv; av_register_all(); F("3\n"); if(stream_read(demuxer->stream, buf, PROBE_BUF_SIZE)!=PROBE_BUF_SIZE) return 0; F("4\n"); avpd.filename= demuxer->stream->url; avpd.buf= buf; avpd.buf_size= PROBE_BUF_SIZE; F("5\n"); if (opt_format) { if (strcmp(opt_format, "help") == 0) { list_formats(); return 0; } priv->avif= av_find_input_format(opt_format); if (!priv->avif) { mp_msg(MSGT_DEMUX,MSGL_FATAL,"Unknown lavf format %s\n", opt_format); return 0; } mp_msg(MSGT_DEMUX,MSGL_INFO,"Forced lavf %s demuxer\n", priv->avif->long_name); return DEMUXER_TYPE_LAVF; } F("6\n"); priv->avif= av_probe_input_format(&avpd, 1); F("7\n"); if(!priv->avif){ mp_msg(MSGT_HEADER,MSGL_V,"LAVF_check: no clue about this gibberish!\n"); return 0; }else mp_msg(MSGT_HEADER,MSGL_V,"LAVF_check: %s\n", priv->avif->long_name); return DEMUXER_TYPE_LAVF;}static const char *preferred_list[] = { "dxa", "wv", "nuv", "nut", "gxf", "mxf", "flv", "swf", NULL};static int lavf_check_preferred_file(demuxer_t *demuxer){ if (lavf_check_file(demuxer)) { char **p = preferred_list; lavf_priv_t *priv = demuxer->priv; while (*p) { if (strcmp(*p, priv->avif->name) == 0) return DEMUXER_TYPE_LAVF_PREFERRED; p++; } } return 0;} static demuxer_t* demux_open_lavf(demuxer_t *demuxer){ AVFormatContext *avfc; AVFormatParameters ap; const AVOption *opt; lavf_priv_t *priv= demuxer->priv; int i,g; char mp_filename[256]="mp:"; memset(&ap, 0, sizeof(AVFormatParameters)); stream_seek(demuxer->stream, 0); register_protocol(&mp_protocol); avfc = av_alloc_format_context(); if (correct_pts) avfc->flags |= AVFMT_FLAG_GENPTS; if (index_mode == 0) avfc->flags |= AVFMT_FLAG_IGNIDX; ap.prealloced_context = 1; if(opt_probesize) { opt = av_set_int(avfc, "probesize", opt_probesize); if(!opt) mp_msg(MSGT_HEADER,MSGL_ERR, "demux_lavf, couldn't set option probesize to %u\n", opt_probesize); } if(opt_analyzeduration) { opt = av_set_int(avfc, "analyzeduration", opt_analyzeduration * AV_TIME_BASE); if(!opt) mp_msg(MSGT_HEADER,MSGL_ERR, "demux_lavf, couldn't set option analyzeduration to %u\n", opt_analyzeduration); } if(demuxer->stream->url) strncpy(mp_filename + 3, demuxer->stream->url, sizeof(mp_filename)-3); else strncpy(mp_filename + 3, "foobar.dummy", sizeof(mp_filename)-3); url_fopen(&priv->pb, mp_filename, URL_RDONLY); ((URLContext*)(priv->pb.opaque))->priv_data= demuxer->stream; if(av_open_input_stream(&avfc, &priv->pb, mp_filename, priv->avif, &ap)<0){ mp_msg(MSGT_HEADER,MSGL_ERR,"LAVF_header: av_open_input_stream() failed\n"); return NULL; } priv->avfc= avfc; if(av_find_stream_info(avfc) < 0){ mp_msg(MSGT_HEADER,MSGL_ERR,"LAVF_header: av_find_stream_info() failed\n"); return NULL; } if(avfc->title [0]) demux_info_add(demuxer, "name" , avfc->title ); if(avfc->author [0]) demux_info_add(demuxer, "author" , avfc->author ); if(avfc->copyright[0]) demux_info_add(demuxer, "copyright", avfc->copyright); if(avfc->comment [0]) demux_info_add(demuxer, "comments" , avfc->comment ); if(avfc->album [0]) demux_info_add(demuxer, "album" , avfc->album );// if(avfc->year ) demux_info_add(demuxer, "year" , avfc->year );// if(avfc->track ) demux_info_add(demuxer, "track" , avfc->track ); if(avfc->genre [0]) demux_info_add(demuxer, "genre" , avfc->genre ); for(i=0; i<avfc->nb_streams; i++){ AVStream *st= avfc->streams[i]; AVCodecContext *codec= st->codec; switch(codec->codec_type){ case CODEC_TYPE_AUDIO:{ WAVEFORMATEX *wf= calloc(sizeof(WAVEFORMATEX) + codec->extradata_size, 1); sh_audio_t* sh_audio; if(priv->audio_streams >= MAX_A_STREAMS) break; sh_audio=new_sh_audio(demuxer, i); mp_msg(MSGT_DEMUX, MSGL_INFO, MSGTR_AudioID, "lavf", i); if(!sh_audio) break; priv->astreams[priv->audio_streams] = i; priv->audio_streams++; // mp4a tag is used for all mp4 files no matter what they actually contain if(codec->codec_tag == MKTAG('m', 'p', '4', 'a')) codec->codec_tag= 0; if(codec->codec_id == CODEC_ID_ADPCM_IMA_AMV) codec->codec_tag= MKTAG('A','M','V','A'); if(!codec->codec_tag) codec->codec_tag= av_codec_get_tag(mp_wav_taglists, codec->codec_id); wf->wFormatTag= codec->codec_tag; wf->nChannels= codec->channels; wf->nSamplesPerSec= codec->sample_rate; wf->nAvgBytesPerSec= codec->bit_rate/8; wf->nBlockAlign= codec->block_align ? codec->block_align : 1; wf->wBitsPerSample= codec->bits_per_sample; wf->cbSize= codec->extradata_size; if(codec->extradata_size){ memcpy( wf + 1, codec->extradata, codec->extradata_size); } sh_audio->wf= wf; sh_audio->audio.dwSampleSize= codec->block_align; if(codec->frame_size && codec->sample_rate){
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?