当前位置:网站首页>Ffplay realizes user-defined input stream playback

Ffplay realizes user-defined input stream playback

2022-06-23 07:28:00 CodeOfCC


Preface

Use ffplay Play the video , Sometimes we can only get byte data , such as Windows The embedded resource of can only get the video file data in memory , Or it is a video transmitted over a custom protocol network , At this time, we need to implement a stream data input interface to play ,ffmpeg Of AVIOContext This function is supported , We just need to be right ffplay Simply expand .


One 、 How to use AVIOContext?

avio yes ffmpeg Custom input stream objects , It is AVformatContext A field of , I just need to create avio Object and implement its callback method , And then to AVformatContext.pb Assignment can .

1、 Define callback methods

Take file stream as an example ( Omit the operation of opening file and getting file length )

FILE* file;
static int avio_read(ACPlay play, uint8_t* buf, int bufsize)
{
    
	return fread(buf, 1, bufsize, file);
}
static int64_t avio_seek(ACPlay play, int64_t offset, int whence)
{
    
	switch (whence)
	{
    
	case AVSEEK_SIZE:
		return fileSize;
		break;
	case SEEK_CUR:
		fseek(file, offset, whence);
		break;
	case SEEK_SET:
		fseek(file, offset, whence);
		break;
	case SEEK_END:
		fseek(file, offset, whence);
		break;
	default:
		break;
	}
	return  ftell(test3file);
}

2、 relation AVFormatContext

AVFormatContext* ic = NULL;
AVIOContext* avio = avio_alloc_context((unsigned char*)av_malloc(1024 * 1024), 1024 * 1024, 0, s, avio_read, NULL, avio_seek);
if (avio)
{
    
	ic->pb = avio;
	ic->flags = AVFMT_FLAG_CUSTOM_IO;
}
avformat_open_input(&ic, "", NULL, NULL);

3、 Destroy resources

if (ic->avio)
{
    
	if (ic->avio->buffer)
	{
    
		av_free(is->avio->buffer);
	}
	avio_context_free(&is->avio);
	ic->avio = NULL;
}

Two 、ffplay Use in AVIOContext

1、 Add fields

stay VideoState Add the following fields

AVIOContext* avio;

2、 Defining interfaces

/// <summary>
///  Start playing 
/// </summary>
/// <param name="play"> Player object </param>
/// <param name="read"> Custom input stream , Callback when reading data </param>
/// <param name="seek"> Custom input stream , Callback during positioning </param>
void ac_play_startViaCustomStream(ACPlay play, ACPlayCustomPacketReadCallback read, ACPlayCustomPacketStreamSeekCallback seek);
{
    
    VideoState* s = (VideoState*)play;
	if(read)
	s->avio = avio_alloc_context((unsigned char*)av_malloc(1024 * 1024), 1024 * 1024, 0, s, read, NULL, seek);
	stream_open(s, "", NULL);
}

3、 relation AVFormatContext

stay read_thread in avformat_open_input Add the following code to the previous line of the :

if (is->avio)
{
    
	ic->pb = is->avio;
	ic->flags = AVFMT_FLAG_CUSTOM_IO;
}

4、 Destroy resources

stay stream_close Add the following code to

if (ic->avio)
{
    
	if (ic->avio->buffer)
	{
    
		av_free(is->avio->buffer);
	}
	avio_context_free(&is->avio);
	ic->avio = NULL;
}

summary

That's what we're going to talk about today , The reason to realize this function is that the author used to work , I have encountered relevant usage scenarios , Play when the program starts mp4 Embed resources , It is obviously not a good solution to read it out and save the file for playback , and ffmpeg It supports custom input streams , So it's easy to add this feature to ffplay Yes . in general , This function has certain usage scenarios and its implementation is not complicated .

原网站

版权声明
本文为[CodeOfCC]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/174/202206230504321434.html