int
decoder_load_info( Decoder *pDecoder ) {

	unsigned int i = 0;
	AVProbeData prbData;
	uint8_t *pBuffer, *pIoBuffer;
	AVInputFormat *pInputFmt;
	ByteIOContext *pIoCtx;

	prbData.filename = "DUMMY";
	prbData.buf_size = LARGE_BUFFER_SIZE;
	pBuffer = (uint8_t*) av_mallocz( LARGE_BUFFER_SIZE );
	memset( pBuffer + INBUF_SIZE, 0, FF_INPUT_BUFFER_PADDING_SIZE );

	pDecoder->fpRead( pDecoder->pOpaqueSource, pBuffer, LARGE_BUFFER_SIZE );
	prbData.buf = pBuffer;

	pInputFmt = av_probe_input_format( &prbData, 1 );

	pDecoder->fpSeek( pDecoder->pOpaqueSource, 0, SEEK_SET );

	pIoBuffer = (uint8_t*) av_mallocz( INBUF_SIZE + FF_INPUT_BUFFER_PADDING_SIZE );

	pIoCtx = av_alloc_put_byte( pIoBuffer, INBUF_SIZE + FF_INPUT_BUFFER_PADDING_SIZE,
		0, pDecoder->pOpaqueSource, pDecoder->fpRead, pDecoder->fpWrite, pDecoder->fpSeek );

	if( pIoCtx == NULL )
	{
		printf("Failed getting the byte io context \n");
		goto error;
	}

	if( av_open_input_stream( &pDecoder->pFmtCtx, pIoCtx, "DUMMY", pInputFmt, NULL ) < 0 )
	{
		error("Failed opening input stream");
		goto error;
	}

	if( __load_codec_ctx( pDecoder ) < 0 )
	{
		error("Failed loading the codec details");
		goto error;
	}

	av_free( pBuffer );
	pBuffer = NULL;
	
	return SUCCESS;

error:
	av_free( pBuffer );
	pBuffer = NULL;
	return ERROR;

}
Example #2
0
bool MediaConverter::initializeInput(const LPRImage *pRawImage)
{
	//LPRImage *pImage = NULL;
	//LPRDecodeImage(&pImage, pRawImage->pData, pRawImage->imageSize, LPR_ENCODE_FORMAT_JPG, 0);
	//mOutputWidth = pImage->width;
	//mOutputHeight = pImage->height;
	//LPRReleaseImage(pImage);
	//// pRawImage现在还没有输出到视频,还不能释放
	if (NULL == mInputFmtPtr)
	{
		AVProbeData pd = {"fake.jpg", NULL, 0};
		mInputFmtPtr = av_probe_input_format(&pd, 0);
		mInputFmtPtr->flags = 0;
	}
	AVIOContext *pIOCtx = avio_alloc_context(pRawImage->pData, pRawImage->imageSize, 0, NULL, NULL, NULL, NULL);
	AVFormatContext *pInputFormatCtx = avformat_alloc_context();
	pInputFormatCtx->pb = pIOCtx;
	if (avformat_open_input(&pInputFormatCtx, "fake.jpg", mInputFmtPtr, NULL) != 0)
	{
		printf("Failed to open %s.\n", "fake.jpg");
		return false;
	}
	if (avformat_find_stream_info(pInputFormatCtx, NULL) < 0)
	{
		printf("Failed to parse %s.\n", "fake.jpg");
		return false;
	}
	av_dump_format(pInputFormatCtx, 0, "fake.jpg", 0);
	int videoStreamIndex = -1;
	for (size_t i = 0; i < pInputFormatCtx->nb_streams; ++ i)
	{
		if (pInputFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO)
		{
			videoStreamIndex = i;
			break;
		}
	}
	if (videoStreamIndex == -1)
	{
		printf("Could not find a video stream.\n");
		return false;
	}
	AVCodecContext *pInputCodecCtx = pInputFormatCtx->streams[videoStreamIndex]->codec;
	// 输入媒体的宽高和输出媒体的宽高保持一致
	mOutputWidth = pInputCodecCtx->width;
	mOutputHeight = pInputCodecCtx->height;
	//////////////////////////////////////////////////////////////////////////
	// 参数已经读取完毕,释放资源
	avcodec_close(pInputCodecCtx);
	av_free(pIOCtx);
	avformat_close_input(&pInputFormatCtx);

	mInputFramePtr = avcodec_alloc_frame();
	return true;
}
AVInputFormat*
FFmpegTagger::probeInputFormat(std::istream& istr)
{
    AVProbeData probeData;
    probeData.filename = "";
    LOGNS(Omm::AvStream, avstream, debug, "probing stream ...");

    probeData.buf_size = _tagBufferSize;
    unsigned char buffer[_tagBufferSize];
    probeData.buf = buffer;
    istr.read((char*)probeData.buf, _tagBufferSize);
    int bytes = istr.gcount();
    LOGNS(Omm::AvStream, avstream, debug, "read " + Poco::NumberFormatter::format(bytes) + " bytes from stream");
    if (istr.bad() || bytes == 0) {
        LOGNS(Omm::AvStream, avstream, error, "error reading probe data");
        return 0;
    }

    LOGNS(Omm::AvStream, avstream, debug, "detecting format ...");
    LOG(ffmpeg, trace, "ffmpeg::av_probe_input_format() ...");
    AVInputFormat* pInputFormat = av_probe_input_format(&probeData, 1 /*int is_opened*/);
    if (pInputFormat) {
        LOGNS(Omm::AvStream, avstream, information, "AV stream format: " + std::string(pInputFormat->name) + " (" + std::string(pInputFormat->long_name) + ")");
    }
    else {
        LOGNS(Omm::AvStream, avstream, error, "AV stream format unknown");
        return 0;
    }

    // this stops ffmpeg from seeking the stream, but av_probe_input_format() returns 0 when called after setting this flag.
//     pInputFormat->flags |= AVFMT_NOFILE;

    // TODO: reset the stream after probing (if seekable)
    // Seek back to 0
    // copied from url_fseek
//     long offset1 = 0 - (_pIoContext->pos - (_pIoContext->buf_end - _pIoContext->buffer));
//     if (offset1 >= 0 && offset1 <= (_pIoContext->buf_end - _pIoContext->buffer)) {
//             /* can do the seek inside the buffer */
//         _pIoContext->buf_ptr = _pIoContext->buffer + offset1;
//     } else {
//         if (!d->src->seek(0)) {
//             return false;
//         } else {
//             _pIoContext->pos = 0;
//             _pIoContext->buf_ptr = d->file_buffer;
//             _pIoContext->buf_end = d->file_buffer;
//         }
//     }

    return pInputFormat;
}
Example #4
0
ComponentResult FFAvi_MovieImportValidateDataRef(ff_global_ptr storage, Handle dataRef, OSType dataRefType, UInt8 *valid)
{
	ComponentResult result = noErr;
	DataHandler dataHandler = NULL;
	uint8_t buf[PROBE_BUF_SIZE + FF_INPUT_BUFFER_PADDING_SIZE] = {0};
	AVProbeData pd;
	ByteIOContext *byteContext;

	/* default */
	*valid = 0;
	
	/* Get a data handle and read a probe of data */
	result = OpenADataHandler(dataRef, dataRefType, NULL, 0, NULL, kDataHCanRead, &dataHandler);
	if(result || !dataHandler) goto bail;
	
	pd.buf = buf;
	pd.buf_size = PROBE_BUF_SIZE;
	
	result = DataHScheduleData(dataHandler, (Ptr)pd.buf, 0, PROBE_BUF_SIZE, 0, NULL, NULL);
	require_noerr(result,bail);
	
	FFInitFFmpeg();
	storage->format = av_probe_input_format(&pd, 1);
	if(storage->format != NULL) {
		*valid = 255; /* This means we can read the data */
		
		/* we don't do MJPEG's Huffman tables right yet, and DV video seems to have 
		an aspect ratio coded in the bitstream that ffmpeg doesn't read, so let Apple's 
		AVI importer handle AVIs with these two video types */
		if (IS_AVI(storage->componentType)) {
			/* Prepare the iocontext structure */
			result = url_open_dataref(&byteContext, dataRef, dataRefType, NULL, NULL, NULL);
			require_noerr(result, bail);
			
			OSType fourcc = get_avi_strf_fourcc(byteContext);
			enum CodecID id = ff_codec_get_id(ff_codec_bmp_tags, BSWAP(fourcc));
			
			if (id == CODEC_ID_MJPEG || id == CODEC_ID_DVVIDEO || id == CODEC_ID_RAWVIDEO || id == CODEC_ID_MSVIDEO1 || id == CODEC_ID_MSRLE)
				*valid = 0;
			
			url_fclose(byteContext);
		}
	}
		
bail:
		if(dataHandler)
			CloseComponent(dataHandler);
	
	return result;
} /* FFAvi_MovieImportValidateDataRef() */
static int lavf_check_file(demuxer_t *demuxer){
    AVProbeData avpd;
    uint8_t buf[PROBE_BUF_SIZE];
    lavf_priv_t *priv;
    
    if(!demuxer->priv) 
        demuxer->priv=calloc(sizeof(lavf_priv_t),1);
    priv= demuxer->priv;

    av_register_all();

    if(stream_read(demuxer->stream, buf, PROBE_BUF_SIZE)!=PROBE_BUF_SIZE)
        return 0;
    avpd.filename= demuxer->stream->url;
    avpd.buf= buf;
    avpd.buf_size= PROBE_BUF_SIZE;

    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;
    }
    priv->avif= av_probe_input_format(&avpd, 1);
    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;
}
Example #6
0
bool FFMPEGDecoder::openFile() {
    d->src->openRO();
    d->src->fadvise();

    // The following duplicates what av_open_input_file would normally do

    // url_fdopen
    init_put_byte(&d->stream, d->file_buffer, FILE_BUFFER_SIZE, 0, d->src, akode_read, akode_write, akode_seek);
    d->stream.is_streamed = !d->src->seekable();
    d->stream.max_packet_size = FILE_BUFFER_SIZE;

    {
        // 2048 is PROBE_BUF_SIZE from libavformat/utils.c
        AVProbeData pd;
        uint8_t buf[2048];
        pd.filename = d->src->filename;
        pd.buf = buf;
        pd.buf_size = 0;
        pd.buf_size = get_buffer(&d->stream, buf, 2048);
        d->fmt = av_probe_input_format(&pd, 1);
        // Seek back to 0
        // copied from url_fseek
        long offset1 = 0 - (d->stream.pos - (d->stream.buf_end - d->stream.buffer));
        if (offset1 >= 0 && offset1 <= (d->stream.buf_end - d->stream.buffer)) {
            /* can do the seek inside the buffer */
            d->stream.buf_ptr = d->stream.buffer + offset1;
        } else {
            if (!d->src->seek(0)) {
                d->src->close();
                return false;
            } else {
                d->stream.pos = 0;
                d->stream.buf_ptr = d->file_buffer;
                d->stream.buf_end = d->file_buffer;
            }
        }
    }
    if (!d->fmt) {
        std::cerr << "akode: FFMPEG: Format not found\n";
        closeFile();
        return false;
    }

    if (av_open_input_stream(&d->ic, &d->stream, d->src->filename, d->fmt, 0) != 0)
    {
        closeFile();
        return false;
    }

    av_find_stream_info( d->ic );

    // Find the first a/v streams
    d->audioStream = -1;
    d->videoStream = -1;
    for (int i = 0; i < d->ic->nb_streams; i++) {
        if (d->ic->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO)
            d->audioStream = i;
        else
        if (d->ic->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO)
            d->videoStream = i;
    }
    if (d->audioStream == -1)
    {
        std::cerr << "akode: FFMPEG: Audio stream not found\n";
        // for now require an audio stream
        closeFile();
        return false;
    }

    // Set config
    if (!setAudioConfiguration(&d->config, d->ic->streams[d->audioStream]->codec))
    {
        closeFile();
        return false;
    }

    d->codec = avcodec_find_decoder(d->ic->streams[d->audioStream]->codec->codec_id);
    if (!d->codec) {
        std::cerr << "akode: FFMPEG: Codec not found\n";
        closeFile();
        return false;
    }
    avcodec_open( d->ic->streams[d->audioStream]->codec, d->codec );

    double ffpos = (double)d->ic->streams[d->audioStream]->start_time / (double)AV_TIME_BASE;
    d->position = (long)(ffpos * d->config.sample_rate);

    return true;
}
Example #7
0
static GF_Err FFD_ConnectService(GF_InputService *plug, GF_ClientService *serv, const char *url)
{
	GF_Err e;
	s64 last_aud_pts;
	u32 i;
	s32 res;
	Bool is_local;
	const char *sOpt;
	char *ext, szName[1024];
	FFDemux *ffd = plug->priv;
	AVInputFormat *av_in = NULL;
	char szExt[20];

	if (ffd->ctx) return GF_SERVICE_ERROR;

	assert( url && strlen(url) < 1024);
	strcpy(szName, url);
	ext = strrchr(szName, '#');
	ffd->service_type = 0;
	e = GF_NOT_SUPPORTED;
	ffd->service = serv;

	if (ext) {
		if (!stricmp(&ext[1], "video")) ffd->service_type = 1;
		else if (!stricmp(&ext[1], "audio")) ffd->service_type = 2;
		ext[0] = 0;
	}

	/*some extensions not supported by ffmpeg, overload input format*/
	ext = strrchr(szName, '.');
	strcpy(szExt, ext ? ext+1 : "");
	strlwr(szExt);
	if (!strcmp(szExt, "cmp")) av_in = av_find_input_format("m4v");

	is_local = (strnicmp(url, "file://", 7) && strstr(url, "://")) ? 0 : 1;

	GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[FFMPEG] opening file %s - local %d - av_in %08x\n", url, is_local, av_in));

	if (!is_local) {
		AVProbeData   pd;

		/*setup wraper for FFMPEG I/O*/
		ffd->buffer_size = 8192;
		sOpt = gf_modules_get_option((GF_BaseInterface *)plug, "FFMPEG", "IOBufferSize");
		if (sOpt) ffd->buffer_size = atoi(sOpt);
		ffd->buffer = gf_malloc(sizeof(char)*ffd->buffer_size);
#ifdef FFMPEG_DUMP_REMOTE
		ffd->outdbg = gf_f64_open("ffdeb.raw", "wb");
#endif
#ifdef USE_PRE_0_7
		init_put_byte(&ffd->io, ffd->buffer, ffd->buffer_size, 0, ffd, ff_url_read, NULL, NULL);
		ffd->io.is_streamed = 1;
#else
		ffd->io.seekable = 1;
#endif

		ffd->dnload = gf_service_download_new(ffd->service, url, GF_NETIO_SESSION_NOT_THREADED  | GF_NETIO_SESSION_NOT_CACHED, NULL, ffd);
		if (!ffd->dnload) return GF_URL_ERROR;
		while (1) {
			u32 read;
			e = gf_dm_sess_fetch_data(ffd->dnload, ffd->buffer + ffd->buffer_used, ffd->buffer_size - ffd->buffer_used, &read);
			if (e==GF_EOS) break;
			/*we're sync!!*/
			if (e==GF_IP_NETWORK_EMPTY) continue;
			if (e) goto err_exit;
			ffd->buffer_used += read;
			if (ffd->buffer_used == ffd->buffer_size) break;
		}
		if (e==GF_EOS) {
			const char *cache_file = gf_dm_sess_get_cache_name(ffd->dnload);
			res = open_file(&ffd->ctx, cache_file, av_in);
		} else {
			pd.filename = szName;
			pd.buf_size = ffd->buffer_used;
			pd.buf = (u8 *) ffd->buffer;
			av_in = av_probe_input_format(&pd, 1);
			if (!av_in) {
				GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[FFMPEG] error probing file %s - probe start with %c %c %c %c\n", url, ffd->buffer[0], ffd->buffer[1], ffd->buffer[2], ffd->buffer[3]));
				return GF_NOT_SUPPORTED;
			}
			/*setup downloader*/
			av_in->flags |= AVFMT_NOFILE;
#ifdef USE_AVFORMAT_OPEN_INPUT /*commit ffmpeg 603b8bc2a109978c8499b06d2556f1433306eca7*/
			res = avformat_open_input(&ffd->ctx, szName, av_in, NULL);
#else
			res = av_open_input_stream(&ffd->ctx, &ffd->io, szName, av_in, NULL);
#endif
		}
	} else {
		res = open_file(&ffd->ctx, szName, av_in);
	}

	switch (res) {
#ifndef _WIN32_WCE
	case 0:
		e = GF_OK;
		break;
	case AVERROR_IO:
		e = GF_URL_ERROR;
		goto err_exit;
	case AVERROR_INVALIDDATA:
		e = GF_NON_COMPLIANT_BITSTREAM;
		goto err_exit;
	case AVERROR_NOMEM:
		e = GF_OUT_OF_MEM;
		goto err_exit;
	case AVERROR_NOFMT:
		e = GF_NOT_SUPPORTED;
		goto err_exit;
#endif
	default:
		e = GF_SERVICE_ERROR;
		goto err_exit;
	}

	GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[FFMPEG] looking for streams in %s - %d streams - type %s\n", ffd->ctx->filename, ffd->ctx->nb_streams, ffd->ctx->iformat->name));

	res = av_find_stream_info(ffd->ctx);
	if (res <0) {
		GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[FFMPEG] cannot locate streams - error %d\n", res));
		e = GF_NOT_SUPPORTED;
		goto err_exit;
	}
	GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[FFMPEG] file %s opened - %d streams\n", url, ffd->ctx->nb_streams));

	/*figure out if we can use codecs or not*/
	ffd->audio_st = ffd->video_st = -1;
	for (i = 0; i < ffd->ctx->nb_streams; i++) {
		AVCodecContext *enc = ffd->ctx->streams[i]->codec;
		switch(enc->codec_type) {
		case AVMEDIA_TYPE_AUDIO:
			if ((ffd->audio_st<0) && (ffd->service_type!=1)) {
				ffd->audio_st = i;
				ffd->audio_tscale = ffd->ctx->streams[i]->time_base;
			}
			break;
		case AVMEDIA_TYPE_VIDEO:
			if ((ffd->video_st<0) && (ffd->service_type!=2)) {
				ffd->video_st = i;
				ffd->video_tscale = ffd->ctx->streams[i]->time_base;
			}
			break;
		default:
			break;
		}
	}
	if ((ffd->service_type==1) && (ffd->video_st<0)) goto err_exit;
	if ((ffd->service_type==2) && (ffd->audio_st<0)) goto err_exit;
	if ((ffd->video_st<0) && (ffd->audio_st<0)) {
		GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[FFMPEG] No supported streams in file\n"));
		goto err_exit;
	}


	sOpt = gf_modules_get_option((GF_BaseInterface *)plug, "FFMPEG", "DataBufferMS");
	ffd->data_buffer_ms = 0;
	if (sOpt) ffd->data_buffer_ms = atoi(sOpt);
	if (!ffd->data_buffer_ms) ffd->data_buffer_ms = FFD_DATA_BUFFER;

	/*build seek*/
	if (is_local) {
		/*check we do have increasing pts. If not we can't rely on pts, we must skip SL
		we assume video pts is always present*/
		if (ffd->audio_st>=0) {
			last_aud_pts = 0;
			for (i=0; i<20; i++) {
				AVPacket pkt;
				pkt.stream_index = -1;
				if (av_read_frame(ffd->ctx, &pkt) <0) break;
				if (pkt.pts == AV_NOPTS_VALUE) pkt.pts = pkt.dts;
				if (pkt.stream_index==ffd->audio_st) last_aud_pts = pkt.pts;
			}
			if (last_aud_pts*ffd->audio_tscale.den<10*ffd->audio_tscale.num) ffd->unreliable_audio_timing = 1;
		}

		ffd->seekable = (av_seek_frame(ffd->ctx, -1, 0, AVSEEK_FLAG_BACKWARD)<0) ? 0 : 1;
		if (!ffd->seekable) {
#ifndef FF_API_CLOSE_INPUT_FILE
			av_close_input_file(ffd->ctx);
#else
			avformat_close_input(&ffd->ctx);
#endif
			ffd->ctx = NULL;
			open_file(&ffd->ctx, szName, av_in);
			av_find_stream_info(ffd->ctx);
		}
	}

	/*let's go*/
	gf_service_connect_ack(serv, NULL, GF_OK);
	/*if (!ffd->service_type)*/ FFD_SetupObjects(ffd);
	ffd->service_type = 0;
	return GF_OK;

err_exit:
	GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[FFMPEG] Error opening file %s: %s\n", url, gf_error_to_string(e)));
#ifndef FF_API_CLOSE_INPUT_FILE
	if (ffd->ctx) av_close_input_file(ffd->ctx);
#else
	if (ffd->ctx) avformat_close_input(&ffd->ctx);
#endif
	ffd->ctx = NULL;
	gf_service_connect_ack(serv, NULL, e);
	return GF_OK;
}
Example #8
0
File: demux.c Project: mstorsjo/vlc
static int avformat_ProbeDemux( vlc_object_t *p_this,
                                AVInputFormat **pp_fmt, const char *psz_url )
{
    demux_t       *p_demux = (demux_t*)p_this;
    AVProbeData   pd = { 0 };
    const uint8_t *peek;

    /* Init Probe data */
    pd.buf_size = vlc_stream_Peek( p_demux->s, &peek, 2048 + 213 );
    if( pd.buf_size <= 0 )
    {
        msg_Warn( p_demux, "cannot peek" );
        return VLC_EGENERIC;
    }

    pd.buf = malloc( pd.buf_size + AVPROBE_PADDING_SIZE );
    if( unlikely(pd.buf == NULL) )
        return VLC_ENOMEM;

    memcpy( pd.buf, peek, pd.buf_size );
    memset( pd.buf + pd.buf_size, 0, AVPROBE_PADDING_SIZE );

    if( psz_url != NULL )
        msg_Dbg( p_demux, "trying url: %s", psz_url );

    pd.filename = psz_url;

    vlc_init_avformat(p_this);

    /* Guess format */
    char *psz_format = var_InheritString( p_this, "avformat-format" );
    if( psz_format )
    {
        if( (*pp_fmt = av_find_input_format(psz_format)) )
            msg_Dbg( p_demux, "forcing format: %s", (*pp_fmt)->name );
        free( psz_format );
    }

    if( *pp_fmt == NULL )
        *pp_fmt = av_probe_input_format( &pd, 1 );

    free( pd.buf );

    if( *pp_fmt == NULL )
    {
        msg_Dbg( p_demux, "couldn't guess format" );
        return VLC_EGENERIC;
    }

    if( !p_demux->obj.force )
    {
        static const char ppsz_blacklist[][16] = {
            /* Don't handle MPEG unless forced */
            "mpeg", "vcd", "vob", "mpegts",
            /* libavformat's redirector won't work */
            "redir", "sdp",
            /* Don't handle subtitles format */
            "ass", "srt", "microdvd",
            /* No timestamps at all */
            "hevc", "h264",
            ""
        };

        for( int i = 0; *ppsz_blacklist[i]; i++ )
        {
            if( !strcmp( (*pp_fmt)->name, ppsz_blacklist[i] ) )
                return VLC_EGENERIC;
        }
    }

    /* Don't trigger false alarms on bin files */
    if( !p_demux->obj.force && !strcmp( (*pp_fmt)->name, "psxstr" ) )
    {
        int i_len;

        if( !p_demux->psz_filepath )
            return VLC_EGENERIC;

        i_len = strlen( p_demux->psz_filepath );
        if( i_len < 4 )
            return VLC_EGENERIC;

        if( strcasecmp( &p_demux->psz_filepath[i_len - 4], ".str" ) &&
            strcasecmp( &p_demux->psz_filepath[i_len - 4], ".xai" ) &&
            strcasecmp( &p_demux->psz_filepath[i_len - 3], ".xa" ) )
        {
            return VLC_EGENERIC;
        }
    }

    msg_Dbg( p_demux, "detected format: %s", (*pp_fmt)->name );

    return VLC_SUCCESS;
}
Example #9
0
int AudioConvertFunc(const char *outfilename,int sample_rate,int channels,int sec,const char *inputfilename,HWND mParentHwnd,UINT mMsg)
{
	AVCodec *aCodec =NULL;
	AVPacket *packet = NULL;
	AVFormatContext *pFormatCtx =NULL;
    AVCodecContext *aCodecCtx= NULL;
	ReSampleContext* ResampleCtx=NULL;
	AVFrame *decoded_frame = NULL;
	int datasize;
	//int tempcount = 0;
	//long total_out_size=0;
	int64_t total_in_convert_size = 0;
	int audioConvertProgress = 0;
	int tempAudioConvertProgress;
	unsigned int i;
	int len, ret, buffer_size, count, audio_stream_index = -1, totle_samplenum = 0;

	FILE *outfile = NULL;// *infile;
	head_pama pt;

	int16_t *audio_buffer = NULL;
	int16_t *resamplebuff = NULL;
	int ResampleChange=0;
	int ChannelsChange=0;
	int tempret;

	packet = (AVPacket*)malloc(sizeof(AVPacket));
	if (packet==NULL)
	{
		PostMessage(mParentHwnd,mMsg,FAILED_TAG,(LPARAM)(-1));
		return -1;
	}
	packet->data=NULL;

	buffer_size = AVCODEC_MAX_AUDIO_FRAME_SIZE * 100;
	audio_buffer = (int16_t *)av_malloc(buffer_size);
	if (audio_buffer==NULL)
	{
		if (packet->data!=NULL)
		{
			av_free_packet(packet);
			packet->data=NULL;
		}
		if (packet!=NULL)
		{
			free(packet);
			packet=NULL;
		}
		PostMessage(mParentHwnd,mMsg,FAILED_TAG,(LPARAM)(-2));
		return -2;
	}
	
	av_register_all();

	av_init_packet(packet);
#if 0
	/**********尝试分解av_open_input_file函数*************/
	int ret = 0;
	
	AVFormatParameters ap = { 0 };
	AVDictionary *tmp = NULL;
	AVInputFormat *fmt = NULL;
	AVDictionary **options = NULL;
	if (!pFormatCtx && !(pFormatCtx = avformat_alloc_context()))
		return AVERROR(ENOMEM);
	if (fmt)
		pFormatCtx->iformat = fmt;

	if (options)
		av_dict_copy(&tmp, *options, 0);

	if ((ret = av_opt_set_dict(pFormatCtx, &tmp)) < 0)
		goto fail;
	
	AVDictionary *tmp = NULL;

	if (!pFormatCtx && !(pFormatCtx = avformat_alloc_context()))
		return AVERROR(ENOMEM);

	int ret;
	AVProbeData pd = {inputfilename, NULL, 0};

	if (pFormatCtx->pb) {
		pFormatCtx->flags |= AVFMT_FLAG_CUSTOM_IO;
		if (!pFormatCtx->iformat)
			return av_probe_input_buffer(pFormatCtx->pb, &pFormatCtx->iformat, inputfilename, pFormatCtx, 0, 0);
		else if (pFormatCtx->iformat->flags & AVFMT_NOFILE)
			av_log(pFormatCtx, AV_LOG_WARNING, "Custom AVIOContext makes no sense and "
			"will be ignored with AVFMT_NOFILE format.\n");
		return 0;
	}

	if ( (pFormatCtx->iformat && pFormatCtx->iformat->flags & AVFMT_NOFILE) ||
		(!pFormatCtx->iformat && (pFormatCtx->iformat = av_probe_input_format(&pd, 0))))
		return 0;

	URLContext *h;
	int err;

	err = ffurl_open(&h, inputfilename, AVIO_RDONLY);
	if (err < 0)
		return err;
	err = ffio_fdopen(pFormatCtx, h);
	if (err < 0) {
		ffurl_close(h);
		return err;
	}

	if (pFormatCtx->iformat)
		return 0;
	av_probe_input_buffer(pFormatCtx->pb, &pFormatCtx->iformat, inputfilename, pFormatCtx, 0, 0);


	if (pFormatCtx->iformat->flags & AVFMT_NEEDNUMBER) {
		if (!av_filename_number_test(inputfilename)) {
			ret = AVERROR(EINVAL);
			goto fail;
		}
	}

	pFormatCtx->duration = pFormatCtx->start_time = AV_NOPTS_VALUE;
	av_strlcpy(pFormatCtx->filename, inputfilename ? inputfilename : "", sizeof(pFormatCtx->filename));

	/* allocate private data */
	if (pFormatCtx->iformat->priv_data_size > 0) {
		if (!(pFormatCtx->priv_data = av_mallocz(pFormatCtx->iformat->priv_data_size))) {
			ret = AVERROR(ENOMEM);
			goto fail;
		}
		if (pFormatCtx->iformat->priv_class) {
			*(const AVClass**)pFormatCtx->priv_data = pFormatCtx->iformat->priv_class;
			av_opt_set_defaults(pFormatCtx->priv_data);
			if ((ret = av_opt_set_dict(pFormatCtx->priv_data, &tmp)) < 0)
				goto fail;
		}
	}

	/* e.g. AVFMT_NOFILE formats will not have a AVIOContext */
	if (pFormatCtx->pb)
		ff_id3v2_read(pFormatCtx, ID3v2_DEFAULT_MAGIC);

	if (!(pFormatCtx->flags&AVFMT_FLAG_PRIV_OPT) && pFormatCtx->iformat->read_header)
		if ((ret = pFormatCtx->iformat->read_header(pFormatCtx, &ap)) < 0)
			goto fail;

	if (!(pFormatCtx->flags&AVFMT_FLAG_PRIV_OPT) && pFormatCtx->pb && !pFormatCtx->data_offset)
		pFormatCtx->data_offset = avio_tell(pFormatCtx->pb);

	pFormatCtx->raw_packet_buffer_remaining_size = RAW_PACKET_BUFFER_SIZE;

	if (options) {
		av_dict_free(options);
		*options = tmp;
	}
	return 0;

fail:
	av_dict_free(&tmp);
	if (pFormatCtx->pb && !(pFormatCtx->flags & AVFMT_FLAG_CUSTOM_IO))
		avio_close(pFormatCtx->pb);
	avformat_free_context(pFormatCtx);
	pFormatCtx = NULL;
	return ret;

	return err;
	/**********尝试分解av_open_input_file函数*************/
	//pFormatCtx = avformat_alloc_context();
#endif
	ret = av_open_input_file(&pFormatCtx, inputfilename, NULL,0, NULL);

	if(ret < 0)
	{
		if (audio_buffer!=NULL)
		{
			av_free(audio_buffer);
			audio_buffer=NULL;
		}
		
		if (packet->data!=NULL)
		{
			av_free_packet(packet);
			packet->data=NULL;
		}
		if (packet!=NULL)
		{
			free(packet);
			packet=NULL;
		}
		if (pFormatCtx!=NULL)
		{
			av_close_input_file(pFormatCtx);
			pFormatCtx=NULL;
		}
		PostMessage(mParentHwnd,mMsg,FAILED_TAG,(LPARAM)1);
		return 1;  
	}

	ret = av_find_stream_info(pFormatCtx);

	if( ret < 0)
	{
		if (audio_buffer!=NULL)
		{
			av_free(audio_buffer);
			audio_buffer=NULL;
		}

		if (packet->data!=NULL)
		{
			av_free_packet(packet);
			packet->data=NULL;
		}
		if (packet!=NULL)
		{
			free(packet);
			packet=NULL;
		}
		if (pFormatCtx!=NULL)
		{
			av_close_input_file(pFormatCtx);
			pFormatCtx=NULL;
		}
		PostMessage(mParentHwnd,mMsg,FAILED_TAG,(LPARAM)2);
		return 2;
	}

	audio_stream_index=-1;
	for(i=0; i< (signed)pFormatCtx->nb_streams; i++)
	{

		if(pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO && audio_stream_index < 0)
		{
			audio_stream_index = i;
			break;
		}
	}

	if(audio_stream_index == -1)
	{
		if (audio_buffer!=NULL)
		{
			av_free(audio_buffer);
			audio_buffer=NULL;
		}

		if (packet->data!=NULL)
		{
			av_free_packet(packet);
			packet->data=NULL;
		}
		if (packet!=NULL)
		{
			free(packet);
			packet=NULL;
		}
		if (pFormatCtx!=NULL)
		{
			av_close_input_file(pFormatCtx);
			pFormatCtx=NULL;
		}
		PostMessage(mParentHwnd,mMsg,FAILED_TAG,(LPARAM)3);
		return 3;
	}

	aCodecCtx = pFormatCtx->streams[audio_stream_index]->codec;
	if (aCodecCtx==NULL)
	{
		if (audio_buffer!=NULL)
		{
			av_free(audio_buffer);
			audio_buffer=NULL;
		}

		if (packet->data!=NULL)
		{
			av_free_packet(packet);
			packet->data=NULL;
		}
		if (packet!=NULL)
		{
			free(packet);
			packet=NULL;
		}
		if (pFormatCtx!=NULL)
		{
			av_close_input_file(pFormatCtx);
			pFormatCtx=NULL;
		}
		PostMessage(mParentHwnd,mMsg,FAILED_TAG,(LPARAM)4);
		return 4;
	}
	aCodec = avcodec_find_decoder(aCodecCtx->codec_id);
	if(!aCodec) 
	{
		if (audio_buffer!=NULL)
		{
			av_free(audio_buffer);
			audio_buffer=NULL;
		}

		if (packet->data!=NULL)
		{
			av_free_packet(packet);
			packet->data=NULL;
		}
		if (packet!=NULL)
		{
			free(packet);
			packet=NULL;
		}
		if (pFormatCtx!=NULL)
		{
			av_close_input_file(pFormatCtx);
			pFormatCtx=NULL;
		}
		/*if (aCodecCtx!=NULL)
		{
			avcodec_close(aCodecCtx);
			aCodecCtx=NULL;
		}*/
		PostMessage(mParentHwnd,mMsg,FAILED_TAG,(LPARAM)5);
		return 5;
	}
	//resample init
	if (channels==0)
	{
		channels=aCodecCtx->channels;
	}
	if (sample_rate==0)
	{
		sample_rate=aCodecCtx->sample_rate;
	}
	//if (aCodecCtx->channels!=channels)
	//{
	//	ChannelsChange=1;
	//	ResampleChange=1;
	//}
	if (aCodecCtx->sample_rate!=sample_rate||aCodecCtx->channels!=channels)
	{
		ResampleChange=1;
	}
	if (ResampleChange==1)
	{
		ResampleCtx = av_audio_resample_init(channels,aCodecCtx->channels,sample_rate,aCodecCtx->sample_rate,SAMPLE_FMT_S16,SAMPLE_FMT_S16,16,10,0,1.0);
		if (ResampleCtx==NULL)
		{
			if (audio_buffer!=NULL)
			{
				av_free(audio_buffer);
				audio_buffer=NULL;
			}

			if (packet->data!=NULL)
			{
				av_free_packet(packet);
				packet->data=NULL;
			}
			if (packet!=NULL)
			{
				free(packet);
				packet=NULL;
			}
			if (pFormatCtx!=NULL)
			{
				av_close_input_file(pFormatCtx);
				pFormatCtx=NULL;
			}
			/*if (aCodecCtx!=NULL)
			{
				avcodec_close(aCodecCtx);
				aCodecCtx=NULL;
			}*/
			ResampleChange=0;
			PostMessage(mParentHwnd,mMsg,FAILED_TAG,(LPARAM)6);
			return 6;
		}
		resamplebuff=(int16_t *)malloc(buffer_size);
		if (resamplebuff==NULL)
		{
			if (audio_buffer!=NULL)
			{
				av_free(audio_buffer);
				audio_buffer=NULL;
			}

			if (packet->data!=NULL)
			{
				av_free_packet(packet);
				packet->data=NULL;
			}
			if (packet!=NULL)
			{
				free(packet);
				packet=NULL;
			}
			if (pFormatCtx!=NULL)
			{
				av_close_input_file(pFormatCtx);
				pFormatCtx=NULL;
			}
			/*if (aCodecCtx!=NULL)
			{
				avcodec_close(aCodecCtx);
				aCodecCtx=NULL;
			}*/
			
			if (ResampleChange==1&&ResampleCtx!=NULL)
			{
				audio_resample_close(ResampleCtx);
				ResampleCtx=NULL;
			}
			PostMessage(mParentHwnd,mMsg,FAILED_TAG,(LPARAM)7);
			return 7;
		}
	}
	//
	datasize=sec*sample_rate;
	if(avcodec_open(aCodecCtx, aCodec)<0)
	{
		if (audio_buffer!=NULL)
		{
			av_free(audio_buffer);
			audio_buffer=NULL;
		}

		if (packet->data!=NULL)
		{
			av_free_packet(packet);
			packet->data=NULL;
		}
		if (packet!=NULL)
		{
			free(packet);
			packet=NULL;
		}
		if (pFormatCtx!=NULL)
		{
			av_close_input_file(pFormatCtx);
			pFormatCtx=NULL;
		}
		if (aCodecCtx!=NULL)
		{
			avcodec_close(aCodecCtx);
			aCodecCtx=NULL;
		}

		if (ResampleChange==1&&ResampleCtx!=NULL&&resamplebuff!=NULL)
		{
			audio_resample_close(ResampleCtx);
			ResampleCtx=NULL;
			free(resamplebuff);
			resamplebuff=NULL;
		}
		ResampleChange=0;
		PostMessage(mParentHwnd,mMsg,FAILED_TAG,(LPARAM)8);
		return 8;
	}

	pt.bits = 16;
	pt.channels = channels;
	pt.rate = sample_rate;

	outfile = fopen(outfilename, "wb");
	if (!outfile) 
	{
		if (audio_buffer!=NULL)
		{
			av_free(audio_buffer);
			audio_buffer=NULL;
		}

		if (packet->data!=NULL)
		{
			av_free_packet(packet);
			packet->data=NULL;
		}
		if (packet!=NULL)
		{
			free(packet);
			packet=NULL;
		}
		if (pFormatCtx!=NULL)
		{
			av_close_input_file(pFormatCtx);
			pFormatCtx=NULL;
		}
		if (aCodecCtx!=NULL)
		{
			avcodec_close(aCodecCtx);
			aCodecCtx=NULL;
		}

		if (ResampleChange==1&&ResampleCtx!=NULL&&resamplebuff!=NULL)
		{
			audio_resample_close(ResampleCtx);
			ResampleCtx=NULL;
			free(resamplebuff);
			resamplebuff=NULL;
		}
		ResampleChange=0;
		PostMessage(mParentHwnd,mMsg,FAILED_TAG,(LPARAM)9);
		return 9;
	}

	fseek(outfile,44,SEEK_SET);
    while(av_read_frame(pFormatCtx, packet) >= 0) 
	{
		CheckMessageQueue();
	    if(packet->stream_index == audio_stream_index)
	    {
			//while(packet->size > 0)
			//{
				buffer_size = AVCODEC_MAX_AUDIO_FRAME_SIZE * 100;
				len = avcodec_decode_audio3(aCodecCtx, audio_buffer, &buffer_size, packet);

				if (len < 0) 
				{
					break;
				}

				if(buffer_size > 0)
				{
					//resample
					if (ResampleChange==1)
					{
						int samples=buffer_size/ ((aCodecCtx->channels) * 2);
						int resamplenum= 0;
						resamplenum = audio_resample(ResampleCtx, 
							resamplebuff, 
							audio_buffer, 
							samples);
						count = fwrite(resamplebuff, 2*channels, resamplenum, outfile);
					}
					
					else
					{
						count = fwrite(audio_buffer, 2*aCodecCtx->channels, buffer_size/((aCodecCtx->channels)*2), outfile);
					}
					totle_samplenum += count;
				}
				//tempcount++;
				//total_out_size += count*2*aCodecCtx->channels;
				total_in_convert_size += packet->size;
				tempAudioConvertProgress = 100*total_in_convert_size/(pFormatCtx->file_size);
				if(tempAudioConvertProgress != audioConvertProgress)
				{
					if(tempAudioConvertProgress == 100)
						tempAudioConvertProgress = 99;
					audioConvertProgress = tempAudioConvertProgress;
					tempret = PostMessage(mParentHwnd,mMsg,DECING_TAG,audioConvertProgress);
				}
				if (packet->data!=NULL)
				{
					av_free_packet(packet);
					packet->data=NULL;
				}
				//packet->size -= len;
				//packet->data += len;
			//}
			if (datasize!=0&&totle_samplenum>=datasize)
			{
				break;
			}
	    }
	}
	audioConvertProgress = 100;
	PostMessage(mParentHwnd,mMsg,DECING_TAG,audioConvertProgress);
	fseek(outfile,0,SEEK_SET);
	wav_write_header(outfile, pt, totle_samplenum);
	
	if (outfile!=NULL)
	{
		fclose(outfile);
		outfile=NULL;
	}
    
	if (audio_buffer!=NULL)
	{
		av_free(audio_buffer);
		audio_buffer=NULL;
	}
	
	if (aCodecCtx!=NULL)
	{
		avcodec_close(aCodecCtx);
		aCodecCtx=NULL;
	}
	
	if (packet!=NULL)
	{
		free(packet);//
		packet=NULL;
	}
	
	if (pFormatCtx!=NULL)
	{
		av_close_input_file(pFormatCtx);
		pFormatCtx=NULL;
	}
	
	if (ResampleChange==1)
	{
		if (resamplebuff!=NULL)
		{
			free(resamplebuff);
			resamplebuff=NULL;
		}
		if (ResampleCtx!=NULL)
		{
			audio_resample_close(ResampleCtx);
			ResampleCtx=NULL;
		}
	}
	if (totle_samplenum<=sample_rate*5)
	{
		PostMessage(mParentHwnd,mMsg,FAILED_TAG,(LPARAM)10);
		return 10;
	}
	PostMessage(mParentHwnd,mMsg,FINISH_TAG,NULL);
	return 0;
}
Example #10
0
int OpenDemux( vlc_object_t *p_this )
{
    demux_t       *p_demux = (demux_t*)p_this;
    demux_sys_t   *p_sys;
    AVProbeData   pd = { };
    AVInputFormat *fmt = NULL;
    int64_t       i_start_time = -1;
    bool          b_can_seek;
    char         *psz_url;
    const uint8_t *peek;
    int           error;

    /* Init Probe data */
    pd.buf_size = vlc_stream_Peek( p_demux->s, &peek, 2048 + 213 );
    if( pd.buf_size <= 0 )
    {
        msg_Warn( p_demux, "cannot peek" );
        return VLC_EGENERIC;
    }

    pd.buf = malloc( pd.buf_size + AVPROBE_PADDING_SIZE );
    if( unlikely(pd.buf == NULL) )
        return VLC_ENOMEM;

    memcpy( pd.buf, peek, pd.buf_size );
    memset( pd.buf + pd.buf_size, 0, AVPROBE_PADDING_SIZE );

    if( p_demux->psz_file )
        psz_url = strdup( p_demux->psz_file );
    else
    {
        if( asprintf( &psz_url, "%s://%s", p_demux->psz_access,
                      p_demux->psz_location ) == -1)
            psz_url = NULL;
    }

    if( psz_url != NULL )
        msg_Dbg( p_demux, "trying url: %s", psz_url );

    pd.filename = psz_url;

    vlc_stream_Control( p_demux->s, STREAM_CAN_SEEK, &b_can_seek );

    vlc_init_avformat(p_this);

    /* Guess format */
    char *psz_format = var_InheritString( p_this, "avformat-format" );
    if( psz_format )
    {
        if( (fmt = av_find_input_format(psz_format)) )
            msg_Dbg( p_demux, "forcing format: %s", fmt->name );
        free( psz_format );
    }

    if( fmt == NULL )
        fmt = av_probe_input_format( &pd, 1 );

    free( pd.buf );

    if( fmt == NULL )
    {
        msg_Dbg( p_demux, "couldn't guess format" );
        free( psz_url );
        return VLC_EGENERIC;
    }

    if( !p_demux->obj.force )
    {
        static const char ppsz_blacklist[][16] = {
            /* Don't handle MPEG unless forced */
            "mpeg", "vcd", "vob", "mpegts",
            /* libavformat's redirector won't work */
            "redir", "sdp",
            /* Don't handle subtitles format */
            "ass", "srt", "microdvd",
            /* No timestamps at all */
            "hevc", "h264",
            ""
        };

        for( int i = 0; *ppsz_blacklist[i]; i++ )
        {
            if( !strcmp( fmt->name, ppsz_blacklist[i] ) )
            {
                free( psz_url );
                return VLC_EGENERIC;
            }
        }
    }

    /* Don't trigger false alarms on bin files */
    if( !p_demux->obj.force && !strcmp( fmt->name, "psxstr" ) )
    {
        int i_len;

        if( !p_demux->psz_file )
        {
            free( psz_url );
            return VLC_EGENERIC;
        }

        i_len = strlen( p_demux->psz_file );
        if( i_len < 4 )
        {
            free( psz_url );
            return VLC_EGENERIC;
        }

        if( strcasecmp( &p_demux->psz_file[i_len - 4], ".str" ) &&
            strcasecmp( &p_demux->psz_file[i_len - 4], ".xai" ) &&
            strcasecmp( &p_demux->psz_file[i_len - 3], ".xa" ) )
        {
            free( psz_url );
            return VLC_EGENERIC;
        }
    }

    msg_Dbg( p_demux, "detected format: %s", fmt->name );

    /* Fill p_demux fields */
    p_demux->pf_demux = Demux;
    p_demux->pf_control = Control;
    p_demux->p_sys = p_sys = xmalloc( sizeof( demux_sys_t ) );
    p_sys->ic = 0;
    p_sys->fmt = fmt;
    p_sys->i_tk = 0;
    p_sys->tk = NULL;
    p_sys->tk_pcr = NULL;
    p_sys->i_ssa_order = 0;
    TAB_INIT( p_sys->i_attachments, p_sys->attachments);
    p_sys->p_title = NULL;

    /* Create I/O wrapper */
    unsigned char * p_io_buffer = av_malloc( AVFORMAT_IOBUFFER_SIZE );
    if( !p_io_buffer )
    {
        free( psz_url );
        CloseDemux( p_this );
        return VLC_ENOMEM;
    }

    p_sys->ic = avformat_alloc_context();
    if( !p_sys->ic )
    {
        av_free( p_io_buffer );
        free( psz_url );
        CloseDemux( p_this );
        return VLC_ENOMEM;
    }

    AVIOContext *pb = p_sys->ic->pb = avio_alloc_context( p_io_buffer,
        AVFORMAT_IOBUFFER_SIZE, 0, p_demux, IORead, NULL, IOSeek );
    if( !pb )
    {
        av_free( p_io_buffer );
        free( psz_url );
        CloseDemux( p_this );
        return VLC_ENOMEM;
    }

    p_sys->ic->pb->seekable = b_can_seek ? AVIO_SEEKABLE_NORMAL : 0;
    error = avformat_open_input(&p_sys->ic, psz_url, p_sys->fmt, NULL);

    if( error < 0 )
    {
        msg_Err( p_demux, "Could not open %s: %s", psz_url,
                 vlc_strerror_c(AVUNERROR(error)) );
        av_free( p_io_buffer );
        av_free( pb );
        p_sys->ic = NULL;
        free( psz_url );
        CloseDemux( p_this );
        return VLC_EGENERIC;
    }
    free( psz_url );

    char *psz_opts = var_InheritString( p_demux, "avformat-options" );
    AVDictionary *options[p_sys->ic->nb_streams ? p_sys->ic->nb_streams : 1];
    options[0] = NULL;
    unsigned int nb_streams = p_sys->ic->nb_streams;
    for (unsigned i = 1; i < nb_streams; i++)
        options[i] = NULL;
    if (psz_opts) {
        vlc_av_get_options(psz_opts, &options[0]);
        for (unsigned i = 1; i < nb_streams; i++) {
            av_dict_copy(&options[i], options[0], 0);
        }
        free(psz_opts);
    }
    vlc_avcodec_lock(); /* avformat calls avcodec behind our back!!! */
    error = avformat_find_stream_info( p_sys->ic, options );
    /* FIXME: what if nb_streams change after that call? */
    vlc_avcodec_unlock();
    AVDictionaryEntry *t = NULL;
    while ((t = av_dict_get(options[0], "", t, AV_DICT_IGNORE_SUFFIX))) {
        msg_Err( p_demux, "Unknown option \"%s\"", t->key );
    }
    av_dict_free(&options[0]);
    for (unsigned i = 1; i < nb_streams; i++) {
        av_dict_free(&options[i]);
    }

    if( error < 0 )
    {
        msg_Warn( p_demux, "Could not find stream info: %s",
                  vlc_strerror_c(AVUNERROR(error)) );
    }

    for( unsigned i = 0; i < p_sys->ic->nb_streams; i++ )
    {
        AVStream *s = p_sys->ic->streams[i];
        const AVCodecParameters *cp = s->codecpar;
        es_out_id_t  *es = NULL;
        es_format_t es_fmt;
        const char *psz_type = "unknown";

        /* Do not use the cover art as a stream */
        if( s->disposition == AV_DISPOSITION_ATTACHED_PIC )
        {
            TAB_APPEND( p_sys->i_tk, p_sys->tk, NULL );
            continue;
        }

        vlc_fourcc_t fcc = GetVlcFourcc( cp->codec_id );
        switch( cp->codec_type )
        {
        case AVMEDIA_TYPE_AUDIO:
            es_format_Init( &es_fmt, AUDIO_ES, fcc );
            es_fmt.i_original_fourcc = CodecTagToFourcc( cp->codec_tag );
            es_fmt.i_bitrate = cp->bit_rate;
            es_fmt.audio.i_channels = cp->channels;
            es_fmt.audio.i_rate = cp->sample_rate;
            es_fmt.audio.i_bitspersample = cp->bits_per_coded_sample;
            es_fmt.audio.i_blockalign = cp->block_align;
            psz_type = "audio";

            if(cp->codec_id == AV_CODEC_ID_AAC_LATM)
            {
                es_fmt.i_original_fourcc = VLC_FOURCC('L','A','T','M');
                es_fmt.b_packetized = false;
            }
            else if(cp->codec_id == AV_CODEC_ID_AAC &&
                    strstr(p_sys->fmt->long_name, "raw ADTS AAC"))
            {
                es_fmt.i_original_fourcc = VLC_FOURCC('A','D','T','S');
                es_fmt.b_packetized = false;
            }
            break;

        case AVMEDIA_TYPE_VIDEO:
            es_format_Init( &es_fmt, VIDEO_ES, fcc );
            es_fmt.i_original_fourcc = CodecTagToFourcc( cp->codec_tag );

            es_fmt.video.i_bits_per_pixel = cp->bits_per_coded_sample;
            /* Special case for raw video data */
            if( cp->codec_id == AV_CODEC_ID_RAWVIDEO )
            {
                msg_Dbg( p_demux, "raw video, pixel format: %i", cp->format );
                if( GetVlcChroma( &es_fmt.video, cp->format ) != VLC_SUCCESS)
                {
                    msg_Err( p_demux, "was unable to find a FourCC match for raw video" );
                }
                else
                    es_fmt.i_codec = es_fmt.video.i_chroma;
            }
            /* We need this for the h264 packetizer */
            else if( cp->codec_id == AV_CODEC_ID_H264 && ( p_sys->fmt == av_find_input_format("flv") ||
                p_sys->fmt == av_find_input_format("matroska") || p_sys->fmt == av_find_input_format("mp4") ) )
                es_fmt.i_original_fourcc = VLC_FOURCC( 'a', 'v', 'c', '1' );

            es_fmt.video.i_width = cp->width;
            es_fmt.video.i_height = cp->height;
            es_fmt.video.i_visible_width = es_fmt.video.i_width;
            es_fmt.video.i_visible_height = es_fmt.video.i_height;

            get_rotation(&es_fmt, s);

# warning FIXME: implement palette transmission
            psz_type = "video";
            es_fmt.video.i_frame_rate = s->codec->time_base.num;
            es_fmt.video.i_frame_rate_base = s->codec->time_base.den * __MAX( s->codec->ticks_per_frame, 1 );
            es_fmt.video.i_sar_num = s->sample_aspect_ratio.num;
            if (s->sample_aspect_ratio.num > 0)
                es_fmt.video.i_sar_den = s->sample_aspect_ratio.den;
            else
                es_fmt.video.i_sar_den = 0;
            break;

        case AVMEDIA_TYPE_SUBTITLE:
            es_format_Init( &es_fmt, SPU_ES, fcc );
            es_fmt.i_original_fourcc = CodecTagToFourcc( cp->codec_tag );
            if( strncmp( p_sys->ic->iformat->name, "matroska", 8 ) == 0 &&
                cp->codec_id == AV_CODEC_ID_DVD_SUBTITLE &&
                cp->extradata != NULL &&
                cp->extradata_size > 0 )
            {
                char *psz_start;
                char *psz_buf = malloc( cp->extradata_size + 1);
                if( psz_buf != NULL )
                {
                    memcpy( psz_buf, cp->extradata , cp->extradata_size );
                    psz_buf[cp->extradata_size] = '\0';

                    psz_start = strstr( psz_buf, "size:" );
                    if( psz_start &&
                        vobsub_size_parse( psz_start,
                                           &es_fmt.subs.spu.i_original_frame_width,
                                           &es_fmt.subs.spu.i_original_frame_height ) == VLC_SUCCESS )
                    {
                        msg_Dbg( p_demux, "original frame size: %dx%d",
                                 es_fmt.subs.spu.i_original_frame_width,
                                 es_fmt.subs.spu.i_original_frame_height );
                    }
                    else
                    {
                        msg_Warn( p_demux, "reading original frame size failed" );
                    }

                    psz_start = strstr( psz_buf, "palette:" );
                    if( psz_start &&
                        vobsub_palette_parse( psz_start, &es_fmt.subs.spu.palette[1] ) == VLC_SUCCESS )
                    {
                        es_fmt.subs.spu.palette[0] = SPU_PALETTE_DEFINED;
                        msg_Dbg( p_demux, "vobsub palette read" );
                    }
                    else
                    {
                        msg_Warn( p_demux, "reading original palette failed" );
                    }
                    free( psz_buf );
                }
            }

            psz_type = "subtitle";
            break;

        default:
            es_format_Init( &es_fmt, UNKNOWN_ES, 0 );
            es_fmt.i_original_fourcc = CodecTagToFourcc( cp->codec_tag );
#ifdef HAVE_AVUTIL_CODEC_ATTACHMENT
            if( cp->codec_type == AVMEDIA_TYPE_ATTACHMENT )
            {
                input_attachment_t *p_attachment;

                psz_type = "attachment";
                if( cp->codec_id == AV_CODEC_ID_TTF )
                {
                    AVDictionaryEntry *filename = av_dict_get( s->metadata, "filename", NULL, 0 );
                    if( filename && filename->value )
                    {
                        p_attachment = vlc_input_attachment_New(
                                filename->value, "application/x-truetype-font",
                                NULL, cp->extradata, (int)cp->extradata_size );
                        if( p_attachment )
                            TAB_APPEND( p_sys->i_attachments, p_sys->attachments,
                                        p_attachment );
                    }
                }
                else msg_Warn( p_demux, "unsupported attachment type (%u) in avformat demux", cp->codec_id );
            }
            else
#endif
            {
                if( cp->codec_type == AVMEDIA_TYPE_DATA )
                    psz_type = "data";

                msg_Warn( p_demux, "unsupported track type (%u:%u) in avformat demux", cp->codec_type, cp->codec_id );
            }
            break;
        }

        AVDictionaryEntry *language = av_dict_get( s->metadata, "language", NULL, 0 );
        if ( language && language->value )
            es_fmt.psz_language = strdup( language->value );

        if( s->disposition & AV_DISPOSITION_DEFAULT )
            es_fmt.i_priority = ES_PRIORITY_SELECTABLE_MIN + 1000;

#ifdef HAVE_AVUTIL_CODEC_ATTACHMENT
        if( cp->codec_type != AVMEDIA_TYPE_ATTACHMENT )
#endif
        if( cp->codec_type != AVMEDIA_TYPE_DATA )
        {
            const bool    b_ogg = !strcmp( p_sys->fmt->name, "ogg" );
            const uint8_t *p_extra = cp->extradata;
            unsigned      i_extra  = cp->extradata_size;

            if( cp->codec_id == AV_CODEC_ID_THEORA && b_ogg )
            {
                unsigned pi_size[3];
                const void *pp_data[3];
                unsigned i_count;
                for( i_count = 0; i_count < 3; i_count++ )
                {
                    if( i_extra < 2 )
                        break;
                    pi_size[i_count] = GetWBE( p_extra );
                    pp_data[i_count] = &p_extra[2];
                    if( i_extra < pi_size[i_count] + 2 )
                        break;

                    p_extra += 2 + pi_size[i_count];
                    i_extra -= 2 + pi_size[i_count];
                }
                if( i_count > 0 && xiph_PackHeaders( &es_fmt.i_extra, &es_fmt.p_extra,
                                                     pi_size, pp_data, i_count ) )
                {
                    es_fmt.i_extra = 0;
                    es_fmt.p_extra = NULL;
                }
            }
            else if( cp->codec_id == AV_CODEC_ID_SPEEX && b_ogg )
            {
                const uint8_t p_dummy_comment[] = {
                    0, 0, 0, 0,
                    0, 0, 0, 0,
                };
                unsigned pi_size[2];
                const void *pp_data[2];

                pi_size[0] = i_extra;
                pp_data[0] = p_extra;

                pi_size[1] = sizeof(p_dummy_comment);
                pp_data[1] = p_dummy_comment;

                if( pi_size[0] > 0 && xiph_PackHeaders( &es_fmt.i_extra, &es_fmt.p_extra,
                                                        pi_size, pp_data, 2 ) )
                {
                    es_fmt.i_extra = 0;
                    es_fmt.p_extra = NULL;
                }
            }
            else if( cp->codec_id == AV_CODEC_ID_OPUS )
            {
                const uint8_t p_dummy_comment[] = {
                    'O', 'p', 'u', 's',
                    'T', 'a', 'g', 's',
                    0, 0, 0, 0, /* Vendor String length */
                                /* Vendor String */
                    0, 0, 0, 0, /* User Comment List Length */

                };
                unsigned pi_size[2];
                const void *pp_data[2];

                pi_size[0] = i_extra;
                pp_data[0] = p_extra;

                pi_size[1] = sizeof(p_dummy_comment);
                pp_data[1] = p_dummy_comment;

                if( pi_size[0] > 0 && xiph_PackHeaders( &es_fmt.i_extra, &es_fmt.p_extra,
                                                        pi_size, pp_data, 2 ) )
                {
                    es_fmt.i_extra = 0;
                    es_fmt.p_extra = NULL;
                }
            }
            else if( cp->extradata_size > 0 )
            {
                es_fmt.p_extra = malloc( i_extra );
                if( es_fmt.p_extra )
                {
                    es_fmt.i_extra = i_extra;
                    memcpy( es_fmt.p_extra, p_extra, i_extra );
                }
            }
            es = es_out_Add( p_demux->out, &es_fmt );
            if( s->disposition & AV_DISPOSITION_DEFAULT )
                es_out_Control( p_demux->out, ES_OUT_SET_ES_DEFAULT, es );
            es_format_Clean( &es_fmt );

            msg_Dbg( p_demux, "adding es: %s codec = %4.4s (%d)",
                     psz_type, (char*)&fcc, cp->codec_id  );
        }
        TAB_APPEND( p_sys->i_tk, p_sys->tk, es );
    }
    p_sys->tk_pcr = xcalloc( p_sys->i_tk, sizeof(*p_sys->tk_pcr) );

    if( p_sys->ic->start_time != (int64_t)AV_NOPTS_VALUE )
        i_start_time = p_sys->ic->start_time * 1000000 / AV_TIME_BASE;

    msg_Dbg( p_demux, "AVFormat(%s %s) supported stream", AVPROVIDER(LIBAVFORMAT), LIBAVFORMAT_IDENT );
    msg_Dbg( p_demux, "    - format = %s (%s)",
             p_sys->fmt->name, p_sys->fmt->long_name );
    msg_Dbg( p_demux, "    - start time = %"PRId64, i_start_time );
    msg_Dbg( p_demux, "    - duration = %"PRId64,
             ( p_sys->ic->duration != (int64_t)AV_NOPTS_VALUE ) ?
             p_sys->ic->duration * 1000000 / AV_TIME_BASE : -1 );

    if( p_sys->ic->nb_chapters > 0 )
    {
        p_sys->p_title = vlc_input_title_New();
        p_sys->p_title->i_length = p_sys->ic->duration * 1000000 / AV_TIME_BASE;
    }

    for( unsigned i = 0; i < p_sys->ic->nb_chapters; i++ )
    {
        seekpoint_t *s = vlc_seekpoint_New();

        AVDictionaryEntry *title = av_dict_get( p_sys->ic->metadata, "title", NULL, 0);
        if( title && title->value )
        {
            s->psz_name = strdup( title->value );
            EnsureUTF8( s->psz_name );
            msg_Dbg( p_demux, "    - chapter %d: %s", i, s->psz_name );
        }
        s->i_time_offset = p_sys->ic->chapters[i]->start * 1000000 *
            p_sys->ic->chapters[i]->time_base.num /
            p_sys->ic->chapters[i]->time_base.den -
            (i_start_time != -1 ? i_start_time : 0 );
        TAB_APPEND( p_sys->p_title->i_seekpoint, p_sys->p_title->seekpoint, s );
    }

    ResetTime( p_demux, 0 );
    return VLC_SUCCESS;
}
/**
* @brief 
*
* @return 
*/
int LocalVideoInput::run()
{
    AVInputFormat *inputFormat = av_find_input_format( "video4linux2" );
    if ( inputFormat == NULL)
        Fatal( "Can't load input format" );

#if 0
    AVProbeData probeData;
    probeData.filename = mSource.c_str();
    probeData.buf = new unsigned char[1024];
    probeData.buf_size = 1024;
    inputFormat = av_probe_input_format( &probeData, 0 );
    if ( inputFormat == NULL)
        Fatal( "Can't probe input format" );

    AVFormatParameters formatParameters ;
    memset( &formatParameters, 0, sizeof(formatParameters) );
    formatParameters.channels = 1;
    formatParameters.channel = 0;
    formatParameters.standard = "PAL";
    formatParameters.pix_fmt = PIX_FMT_RGB24;
    //formatParameters.time_base.num = 1;
    //formatParameters.time_base.den = 10;
    formatParameters.width = 352;
    formatParameters.height = 288;
    //formatParameters.prealloced_context = 1;
#endif

    /* New API */
    AVDictionary *opts = NULL;
    av_dict_set( &opts, "standard", "PAL", 0 );
    av_dict_set( &opts, "video_size", "320x240", 0 );
    av_dict_set( &opts, "channel", "0", 0 );
    av_dict_set( &opts, "pixel_format", "rgb24", 0 );
    //av_dict_set( &opts, "framerate", "10", 0 );
    avDumpDict( opts );

    int avError = 0;
    AVFormatContext *formatContext = NULL;
    //if ( av_open_input_file( &formatContext, mSource.c_str(), inputFormat, 0, &formatParameters ) !=0 )
    if ( (avError = avformat_open_input( &formatContext, mSource.c_str(), inputFormat, &opts )) < 0 )
        Fatal( "Unable to open input %s due to: %s", mSource.c_str(), avStrError(avError) );

    avDumpDict( opts );
#if 0
    if ( av_open_input_stream( &formatContext, 0, mSource.c_str(), inputFormat, &formatParameters ) !=0 )
        Fatal( "Unable to open input %s due to: %s", mSource.c_str(), strerror(errno) );
#endif

    // Locate stream info from input
    if ( (avError = avformat_find_stream_info( formatContext, &opts )) < 0 )
        Fatal( "Unable to find stream info from %s due to: %s", mSource.c_str(), avStrError(avError) );
    
    if ( dbgLevel > DBG_INF )
        av_dump_format( formatContext, 0, mSource.c_str(), 0 );

    // Find first video stream present
    int videoStreamId = -1;
    for ( int i=0; i < formatContext->nb_streams; i++ )
    {
        if ( formatContext->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO )
        {
            videoStreamId = i;
            //set_context_opts( formatContext->streams[i]->codec, avcodec_opts[CODEC_TYPE_VIDEO], AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM );
            break;
        }
    }
    if ( videoStreamId == -1 )
        Fatal( "Unable to locate video stream in %s", mSource.c_str() );
    mStream = formatContext->streams[videoStreamId];
    mCodecContext = mStream->codec;

    // Try and get the codec from the codec context
    AVCodec *codec = NULL;
    if ( (codec = avcodec_find_decoder( mCodecContext->codec_id )) == NULL )
        Fatal( "Can't find codec for video stream from %s", mSource.c_str() );

    // Open the codec
    if ( avcodec_open2( mCodecContext, codec, &opts ) < 0 )
        Fatal( "Unable to open codec for video stream from %s", mSource.c_str() );

    //AVFrame *savedFrame = avcodec_alloc_frame();

    // Allocate space for the native video frame
    AVFrame *frame = avcodec_alloc_frame();

    // Determine required buffer size and allocate buffer
    int pictureSize = avpicture_get_size( mCodecContext->pix_fmt, mCodecContext->width, mCodecContext->height );
    
    ByteBuffer frameBuffer( pictureSize );
    
    //avpicture_fill( (AVPicture *)savedFrame, mLastFrame.mBuffer.data(), mCodecContext->pix_fmt, mCodecContext->width, mCodecContext->height);

    AVPacket packet;
    while( !mStop )
    {
        int frameComplete = false;
        while ( !frameComplete && (av_read_frame( formatContext, &packet ) >= 0) )
        {
            Debug( 5, "Got packet from stream %d", packet.stream_index );
            if ( packet.stream_index == videoStreamId )
            {
                frameComplete = false;
                if ( avcodec_decode_video2( mCodecContext, frame, &frameComplete, &packet ) < 0 )
                    Fatal( "Unable to decode frame at frame %ju", mFrameCount );

                Debug( 3, "Decoded video packet at frame %ju, pts %jd", mFrameCount, packet.pts );

                if ( frameComplete )
                {
                    Debug( 3, "Got frame %d, pts %jd (%.3f)", mCodecContext->frame_number, frame->pkt_pts, (((double)(packet.pts-mStream->start_time)*mStream->time_base.num)/mStream->time_base.den) );

                    avpicture_layout( (AVPicture *)frame, mCodecContext->pix_fmt, mCodecContext->width, mCodecContext->height, frameBuffer.data(), frameBuffer.capacity() );

                    uint64_t timestamp = packet.pts;
                    //Debug( 3, "%d: TS: %lld, TS1: %lld, TS2: %lld, TS3: %.3f", time( 0 ), timestamp, packet.pts, ((1000000LL*packet.pts*mStream->time_base.num)/mStream->time_base.den), (((double)packet.pts*mStream->time_base.num)/mStream->time_base.den) );
                    //Info( "%ld:TS: %lld, TS1: %lld, TS2: %lld, TS3: %.3f", time( 0 ), timestamp, packet.pts, ((1000000LL*packet.pts*mStream->time_base.num)/mStream->time_base.den), (((double)packet.pts*mStream->time_base.num)/mStream->time_base.den) );

                    VideoFrame *videoFrame = new VideoFrame( this, mCodecContext->frame_number, timestamp, frameBuffer );
                    distributeFrame( FramePtr( videoFrame ) );
                }
            }
            av_free_packet( &packet );
        }
        usleep( INTERFRAME_TIMEOUT );
    }
    cleanup();

    av_freep( &frame );
    if ( mCodecContext )
    {
       avcodec_close( mCodecContext );
       mCodecContext = NULL; // Freed by avformat_close_input
    }
    if ( formatContext )
    {
        avformat_close_input( &formatContext );
        formatContext = NULL;
        //av_free( formatContext );
    }
    return( !ended() );
}
Example #12
0
int setupDemuxerFormat(DemuxerSettings *ds, char *file, struct hqv_data *hqv) {
	AVProbeData probe_data, *pd = &probe_data;

	ds->pFormatCtx = avformat_alloc_context();
	ds->pFormatCtx->flags |= AVFMT_FLAG_NONBLOCK;
	ds->pFormatCtx->flags |= AVFMT_FLAG_GENPTS;
#ifdef AVFMT_FLAG_IGNDTS
	ds->pFormatCtx->flags |= AVFMT_FLAG_IGNDTS;
#endif
	if (ds->streaming)
		ds->pFormatCtx->flags |= AVFMT_NOFILE|AVFMT_FLAG_IGNIDX;

        // Setup input format for raw A/V
        if (ds->input_format != NULL) {
                ds->fmt = av_iformat_next(NULL);
                if (ds->fmt != NULL && ds->fmt->name != NULL && strcmp(ds->fmt->name, ds->input_format) != 0) {
                        do {
                                ds->fmt = av_iformat_next(ds->fmt);
                                if (ds->fmt == NULL || ds->fmt->name == NULL)
                                        break;
                        } while (strcmp(ds->fmt->name, ds->input_format) != 0);
                }
                if (ds->fmt)
                        av_log(NULL, AV_LOG_INFO, "Input format: %s\n", ds->fmt->long_name);
                else
                        av_log(NULL, AV_LOG_WARNING, "Failed finding input format: %s\n", ds->input_format);
        }

	if (ds->streaming)
		ds->stream_buffer = (uint8_t*)av_malloc(STREAM_BUFFER_SIZE); 

        // Try to figure out input format
        if (ds->streaming && ds->fmt == NULL) {

                pd->filename = "";
                if (file)
                        pd->filename = file;
                pd->buf = ds->stream_buffer;
                pd->buf_size = STREAM_BUFFER_SIZE;

                // Wait till have enough input data
                while(av_fifo_size(hqv->fifo) < STREAM_BUFFER_SIZE && continueDecoding)
                        usleep(33000);
                if (!continueDecoding)
                        exit(0);
                // Copy some fifo data 
                memcpy(ds->stream_buffer, hqv->fifo->buffer, STREAM_BUFFER_SIZE);

                // Probe input format
                ds->fmt = av_probe_input_format(pd, 1);

                if (!ds->fmt) {
                        av_log(NULL, AV_LOG_FATAL, "Failed probing input file: %s\n", file);
                        exit(1);
                } else
                        av_log(NULL, AV_LOG_INFO, "Input format: %s\n", ds->fmt->long_name);
        }

        // Open Input File
        if (ds->streaming) {
                // Streaming input
                ds->pb = av_alloc_put_byte(ds->stream_buffer, STREAM_BUFFER_SIZE, 0,
                        hqv, fifo_read, NULL, NULL);
                ds->pb->is_streamed = 1;

                // Open video device stream
                if (av_open_input_stream(&ds->pFormatCtx, ds->pb, file, ds->fmt, ds->ap) != 0) {
                        av_log(NULL, AV_LOG_FATAL, "%s: could not open device stream\n", file);
                        return -1;        // Couldn't open file
                }
        } else {
                // Open file
                if (av_open_input_file(&ds->pFormatCtx, file, ds->fmt, 0, ds->ap) != 0) {
                        av_log(NULL, AV_LOG_FATAL, "%s: could not openfile\n", file);
                        return -1;        // Couldn't open file
                }
        }

        // Retrieve stream information
        if (av_find_stream_info(ds->pFormatCtx) < 0) {
                av_log(NULL, AV_LOG_FATAL, "%s: could not find codec parameters\n", file);
                return -1;
        }
	return 0;
}