VideoHelp Forum
+ Reply to Thread
Results 1 to 2 of 2
Thread
  1. Hello!
    I'm attempting to decode video that I have on an internal buffer(actually a circular mutex, as other things are also using this data). My internal buffer is a one to one copy of what I'm receiving over UDP from VLC streaming an mpeg2 file.

    I have created a function: ReadData which I pass to avio_alloc_context, and it gets called properly when I do that. Then, I continue along just like how I did on my test app(which actually opened "UDP://127.0.0.1:4567" and worked successfully). However, when I get to av_read_frame() it becomes apparent that my AVFormatContext is not getting fully populated by avformat_open_input(). I'm not sure which piece specifically I'm missing, but when I call av_read_frame() the program exits.

    My code(keep in mind that this is a work in progress and a lot of this will get cleaned up when I get it working):
    Code:
    	pCodecCtx = avcodec_alloc_context();
    	pAVFormatCtx = avformat_alloc_context();
        AVProbeData probeData;
        probeData.filename = "";
        int bufSize = 1024*8;
        unsigned char *buffer = (unsigned char*)av_malloc(bufSize*sizeof(unsigned char));
        bool probed = false;
        if(InternalReadMethod(buffer, bufSize) >= 0)
        {
        	probeData.buf = buffer;
            probeData.buf_size = bufSize;
            pAVInputFormat = av_probe_input_format(&probeData, 1);
            pAVInputFormat->flags |= AVFMT_NOFILE;
            pAVInputFormat->read_header = NULL;
            pAVFormatCtx->iformat = pAVInputFormat;
            probed = true;
        }
        pAVIOCtx = avio_alloc_context(buffer, bufSize, NULL, this, ReadData, NULL, NULL);
    
    	pAVIOCtx->is_streamed = 1;
        pAVFormatCtx->pb = pAVIOCtx;
        if(!probed)
        {
        	pAVInputFormat = NULL;
            pAVFormatCtx->iformat = NULL;
        }
        printf("Opening input buffer");
        
    	inputOpen = avformat_open_input(&pAVFormatCtx, "", pAVInputFormat, NULL);
            
        if(inputOpen == -1)
        {
        	printf("couldn't open input buffer");
            return -1;
    	}
            
        int videoStream = -1;
        for(int i = 0; i < pAVFormatCtx->nb_streams; i++)
        {
        	if(pAVFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) 
            {
            	videoStream = i;
                break;
    		}
    	}
        if(videoStream > -1)
        {
        	pCodecCtx = pAVFormatCtx->streams[videoStream]->codec;
            pCodec = avcodec_find_decoder(pCodecCtx->codec_id);
    	}
        else
        {
        	//Assume MPEG2 for now
        	pCodec = avcodec_find_decoder(CODEC_ID_MPEG2VIDEO);
    	}
            
        AVPacket        packet;
        int             frameFinished;
        int             numBytes;
        uint8_t         *frameBuffer;
    
        if(avcodec_open(pCodecCtx, pCodec)<0)
        {
        	return -1; // Could not open codec
    	}
    
        // Allocate video frame
        pFrame=avcodec_alloc_frame();
    
        // Allocate an AVFrame structure
        pFrameRGB=avcodec_alloc_frame();
        if(pFrameRGB==NULL)
        {
        	return -1;
    	}
    
        // Determine required buffer size and allocate buffer
        numBytes=avpicture_get_size(PIX_FMT_RGB24, pCodecCtx->width,
                pCodecCtx->height);
        frameBuffer=(uint8_t *)av_malloc(numBytes*sizeof(uint8_t));
    
        // Assign appropriate parts of buffer to image planes in pFrameRGB
        // Note that pFrameRGB is an AVFrame, but AVFrame is a superset
        // of AVPicture
        avpicture_fill((AVPicture *)pFrameRGB, frameBuffer, PIX_FMT_RGB24,
                pCodecCtx->width, pCodecCtx->height);
    
    	while(av_read_frame(pAVFormatCtx, &packet)>=0) 
    	{
    		...
    	}
    And, for safety's sake here's my read function:

    Code:
    int ImageInterface::ReadData(void *opaque, uint8_t *buf, int bufSize)
    {
        if(((ImageInterface*)opaque)->InternalReadMethod(buf, bufSize) >= 0)
        {
            return bufSize;
        }
        else
        {
            return -1;
        }
    }
    
    int ImageInterface::InternalReadMethod(uint8_t *buf, int bufSize)
    {
        return(myCircBuff->peekData(buf, bufSize));//returns 1 on success, -1 on fail
    }
    If anybody can tell me what I've done wrong, or even just point me to someplace that could explain in more detail how I should be setting up the interface between my internal buffer and ffmpeg I'd be deeply indebted to you!

    Thanks!
    Quote Quote  
  2. Did you ever get this working? If so can you post what you figured out. Your example seems to be the best one for using the newest ffmpeg API and using a network stream.
    Quote Quote  



Similar Threads

Visit our sponsor! Try DVDFab and backup Blu-rays!