static int open_f(stream_t *stream, int mode, void *opts, int *file_format) { int flags = 0; const char *filename; AVIOContext *ctx = NULL; int res = STREAM_ERROR; int64_t size; int dummy; init_avformat(); if (mode == STREAM_READ) flags = AVIO_FLAG_READ; else if (mode == STREAM_WRITE) flags = AVIO_FLAG_WRITE; else { mp_msg(MSGT_OPEN, MSGL_ERR, "[ffmpeg] Unknown open mode %d\n", mode); res = STREAM_UNSUPPORTED; goto out; } #ifdef AVIO_FLAG_DIRECT flags |= AVIO_FLAG_DIRECT; #else mp_msg(MSGT_OPEN, MSGL_WARN, "[ffmpeg] No support for AVIO_FLAG_DIRECT, might cause performance and other issues.\n" "Please update to and rebuild against an FFmpeg version supporting it.\n"); #endif if (stream->url) filename = stream->url; else { mp_msg(MSGT_OPEN, MSGL_ERR, "[ffmpeg] No URL\n"); goto out; } if (!strncmp(filename, prefix, strlen(prefix))) filename += strlen(prefix); dummy = !strncmp(filename, "rtsp:", 5); mp_msg(MSGT_OPEN, MSGL_V, "[ffmpeg] Opening %s\n", filename); if (!dummy && avio_open(&ctx, filename, flags) < 0) goto out; stream->priv = ctx; size = dummy ? 0 : avio_size(ctx); if (size >= 0) stream->end_pos = size; stream->type = STREAMTYPE_FILE; stream->seek = seek; if (dummy || !ctx->seekable) { stream->type = STREAMTYPE_STREAM; stream->seek = NULL; } if (!dummy) { stream->fill_buffer = fill_buffer; stream->write_buffer = write_buffer; stream->control = control; stream->close = close_f; } res = STREAM_OK; out: return res; }
static int lavf_check_file(demuxer_t *demuxer){ AVProbeData avpd; lavf_priv_t *priv; int probe_data_size = 0; int read_size = INITIAL_PROBE_SIZE; int score; if(!demuxer->priv) demuxer->priv=calloc(sizeof(lavf_priv_t),1); priv= demuxer->priv; init_avformat(); 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; } avpd.buf = av_mallocz(FFMAX(BIO_BUFFER_SIZE, PROBE_BUF_SIZE) + FF_INPUT_BUFFER_PADDING_SIZE); do { read_size = stream_read(demuxer->stream, avpd.buf + probe_data_size, read_size); if(read_size < 0) { av_free(avpd.buf); return 0; } probe_data_size += read_size; avpd.filename= demuxer->stream->url; if (!avpd.filename) { mp_msg(MSGT_DEMUX, MSGL_WARN, "Stream url is not set!\n"); avpd.filename = ""; } if (!strncmp(avpd.filename, "ffmpeg://", 9)) avpd.filename += 9; avpd.buf_size= probe_data_size; score = 0; priv->avif= av_probe_input_format2(&avpd, probe_data_size > 0, &score); read_size = FFMIN(2*read_size, PROBE_BUF_SIZE - probe_data_size); } while ((demuxer->desc->type != DEMUXER_TYPE_LAVF_PREFERRED || probe_data_size < SMALL_MAX_PROBE_SIZE) && score <= AVPROBE_SCORE_MAX / 4 && read_size > 0 && probe_data_size < PROBE_BUF_SIZE); av_free(avpd.buf); 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; }
int muxer_init_muxer_lavf(muxer_t *muxer) { muxer_priv_t *priv; AVOutputFormat *fmt = NULL; init_avformat(); if (conf_format && strcmp(conf_format, "help") == 0) { list_formats(); return 0; } mp_msg(MSGT_MUXER, MSGL_WARN, "** MUXER_LAVF *****************************************************************\n"); mp_msg(MSGT_MUXER, MSGL_WARN, "REMEMBER: MEncoder's libavformat muxing is presently broken and can generate\n" "INCORRECT files in the presence of B-frames. Moreover, due to bugs MPlayer\n" "will play these INCORRECT files as if nothing were wrong!\n" "*******************************************************************************\n"); priv = calloc(1, sizeof(muxer_priv_t)); if(priv == NULL) return 0; priv->oc = avformat_alloc_context(); if(!priv->oc) { mp_msg(MSGT_MUXER, MSGL_FATAL, "Could not get format context.\n"); goto fail; } if(conf_format) fmt = av_guess_format(conf_format, NULL, NULL); if(! fmt) fmt = av_guess_format(NULL, out_filename, NULL); if(! fmt) { mp_msg(MSGT_MUXER, MSGL_FATAL, "Cannot get specified format.\n"); goto fail; } priv->oc->oformat = fmt; priv->oc->packet_size= mux_packet_size; priv->oc->max_delay= (int)(mux_max_delay*AV_TIME_BASE); if (info_name) av_dict_set(&priv->oc->metadata, "title", info_name, 0); if (info_artist) av_dict_set(&priv->oc->metadata, "author", info_artist, 0); if (info_genre) av_dict_set(&priv->oc->metadata, "genre", info_genre, 0); if (info_copyright) av_dict_set(&priv->oc->metadata, "copyright", info_copyright, 0); if (info_comment) av_dict_set(&priv->oc->metadata, "comment", info_comment, 0); if(mux_avopt){ if(parse_avopts(priv->oc, mux_avopt) < 0){ mp_msg(MSGT_MUXER,MSGL_ERR, "Your options /%s/ look like gibberish to me pal.\n", mux_avopt); goto fail; } } priv->oc->pb = avio_alloc_context(priv->buffer, BIO_BUFFER_SIZE, 1, muxer, NULL, mp_write, mp_seek); if ((muxer->stream->flags & MP_STREAM_SEEK) != MP_STREAM_SEEK) priv->oc->pb->seekable = 0; muxer->priv = priv; muxer->cont_new_stream = &lavf_new_stream; muxer->cont_write_chunk = &write_chunk; muxer->cont_write_header = &write_header; muxer->cont_write_index = &write_trailer; muxer->fix_stream_parameters = &fix_parameters; mp_msg(MSGT_MUXER, MSGL_INFO, "OK, exit.\n"); return 1; fail: free(priv); return 0; }
static int init(sh_audio_t *sh) { int i, x, in_size, srate, bps, *dtshd_rate; unsigned char *start; double pts; static const struct { const char *name; enum AVCodecID id; } fmt_id_type[] = { { "aac" , AV_CODEC_ID_AAC }, { "ac3" , AV_CODEC_ID_AC3 }, { "dca" , AV_CODEC_ID_DTS }, { "eac3", AV_CODEC_ID_EAC3 }, { "mpa" , AV_CODEC_ID_MP3 }, { "thd" , AV_CODEC_ID_TRUEHD }, { NULL , 0 } }; AVFormatContext *lavf_ctx = NULL; AVStream *stream = NULL; const AVOption *opt = NULL; struct spdifContext *spdif_ctx = NULL; spdif_ctx = av_mallocz(sizeof(*spdif_ctx)); if (!spdif_ctx) goto fail; spdif_ctx->lavf_ctx = avformat_alloc_context(); if (!spdif_ctx->lavf_ctx) goto fail; sh->context = spdif_ctx; lavf_ctx = spdif_ctx->lavf_ctx; init_avformat(); lavf_ctx->oformat = av_guess_format(FILENAME_SPDIFENC, NULL, NULL); if (!lavf_ctx->oformat) goto fail; lavf_ctx->priv_data = av_mallocz(lavf_ctx->oformat->priv_data_size); if (!lavf_ctx->priv_data) goto fail; lavf_ctx->pb = avio_alloc_context(spdif_ctx->pb_buffer, OUTBUF_SIZE, 1, spdif_ctx, read_packet, write_packet, seek); if (!lavf_ctx->pb) goto fail; stream = avformat_new_stream(lavf_ctx, 0); if (!stream) goto fail; lavf_ctx->duration = AV_NOPTS_VALUE; lavf_ctx->start_time = AV_NOPTS_VALUE; for (i = 0; fmt_id_type[i].name; i++) { if (!strcmp(sh->codec->dll, fmt_id_type[i].name)) { lavf_ctx->streams[0]->codec->codec_id = fmt_id_type[i].id; break; } } lavf_ctx->internal->raw_packet_buffer_remaining_size = RAW_PACKET_BUFFER_SIZE; if (AVERROR_PATCHWELCOME == lavf_ctx->oformat->write_header(lavf_ctx)) { mp_msg(MSGT_DECAUDIO,MSGL_INFO, "This codec is not supported by spdifenc.\n"); goto fail; } // get sample_rate & bitrate from parser x = ds_get_packet_pts(sh->ds, &start, &pts); in_size = x; if (x <= 0) { pts = MP_NOPTS_VALUE; x = 0; } ds_parse(sh->ds, &start, &x, pts, 0); srate = 48000; //fake value bps = 768000/8; //fake value if (x && sh->avctx) { // we have parser and large enough buffer if (sh->avctx->sample_rate < 44100) { mp_msg(MSGT_DECAUDIO,MSGL_INFO, "This stream sample_rate[%d Hz] may be broken. " "Force reset 48000Hz.\n", sh->avctx->sample_rate); srate = 48000; //fake value } else srate = sh->avctx->sample_rate; bps = sh->avctx->bit_rate/8; } sh->ds->buffer_pos -= in_size; switch (lavf_ctx->streams[0]->codec->codec_id) { case AV_CODEC_ID_AAC: spdif_ctx->iec61937_packet_size = 16384; sh->sample_format = AF_FORMAT_IEC61937_LE; sh->samplerate = srate; sh->channels = 2; sh->i_bps = bps; break; case AV_CODEC_ID_AC3: spdif_ctx->iec61937_packet_size = 6144; sh->sample_format = AF_FORMAT_AC3_LE; sh->samplerate = srate; sh->channels = 2; sh->i_bps = bps; break; case AV_CODEC_ID_DTS: // FORCE USE DTS-HD opt = av_opt_find(&lavf_ctx->oformat->priv_class, "dtshd_rate", NULL, 0, 0); if (!opt) goto fail; dtshd_rate = (int*)(((uint8_t*)lavf_ctx->priv_data) + opt->offset); *dtshd_rate = 192000*4; spdif_ctx->iec61937_packet_size = 32768; sh->sample_format = AF_FORMAT_IEC61937_LE; sh->samplerate = 192000; // DTS core require 48000 sh->channels = 2*4; sh->i_bps = bps; break; case AV_CODEC_ID_EAC3: spdif_ctx->iec61937_packet_size = 24576; sh->sample_format = AF_FORMAT_IEC61937_LE; sh->samplerate = 192000; sh->channels = 2; sh->i_bps = bps; break; case AV_CODEC_ID_MP3: spdif_ctx->iec61937_packet_size = 4608; sh->sample_format = AF_FORMAT_MPEG2; sh->samplerate = srate; sh->channels = 2; sh->i_bps = bps; break; case AV_CODEC_ID_TRUEHD: spdif_ctx->iec61937_packet_size = 61440; sh->sample_format = AF_FORMAT_IEC61937_LE; sh->samplerate = 192000; sh->channels = 8; sh->i_bps = bps; break; default: break; } return 1; fail: uninit(sh); return 0; }
static inline bool mp_media_thread(mp_media_t *m) { os_set_thread_name("mp_media_thread"); if (!init_avformat(m)) { return false; } if (!mp_media_reset(m)) { return false; } for (;;) { bool reset, kill, is_active; bool timeout = false; pthread_mutex_lock(&m->mutex); is_active = m->active; pthread_mutex_unlock(&m->mutex); if (!is_active) { if (os_sem_wait(m->sem) < 0) return false; } else { timeout = mp_media_sleepto(m); } pthread_mutex_lock(&m->mutex); reset = m->reset; kill = m->kill; m->reset = false; m->kill = false; pthread_mutex_unlock(&m->mutex); if (kill) { break; } if (reset) { mp_media_reset(m); continue; } /* frames are ready */ if (is_active && !timeout) { if (m->has_video) mp_media_next_video(m, false); if (m->has_audio) mp_media_next_audio(m); if (!mp_media_prepare_frames(m)) return false; if (mp_media_eof(m)) continue; mp_media_calc_next_ns(m); } } return true; }