ffmpeg - simple player code

1. The overall process of playing media files

Media file --> demultiplexing --> decoding --> call playback interface --> play

2. Demultiplexing

2.1 What is demultiplexing?

Demultiplexing: Splitting media files into video and audio streams

avformat_open_input() /*打开对应的文件,查找对应的解复用器,flv解复用规则最简单*/

The demultiplexed video stream and audio stream are placed in the AVPacket structure.

2.2 Demultiplexing related functions

2.3 Demultiplexing process

3. Decoding

Decoding: Convert video streams and audio streams into video frames and audio frames.

4. Call the playback interface

5. Practical operation

  1. Configure the development environment
    Copy the dynamic library files (.so (dll) and lib) in the compiled ffmpeg dynamic library to the created project folder, and modify the configuration file.
  2. main function code
#include <stdio.h>
#include "libavformat/avformat.h"  /*解复用器的库*/
#include "libavcodec/avcodec.h"
#include "SDL.h"L                  /*可能不用*/

/*
播放视频的代码流程
1 打开文件
2 查找视频流成分
3 读取视频包
4 解码视频包
5 播放解码后的视频
*/
int g_quit = 0;
int main(int argc, char *argv[])
{
	printf("open file:%s!\n", argv[1]);
	int ret = 0;
	AVFormatContext *pFormatCtx = NULL;
	
	/*分配解复用器的上下文*/
	pFormatCtx = avformat_alloc_context();

	/*打开媒体文件*/
	ret = avformat_open_input(&pFormatCtx, argv[1], NULL, NULL);
	if(ret < 0) {
		printf("avformat_open_input %s failed\n", argv[1]);
		return -1;
	}
	
	/*获取码流信息*/
	ret = avformat_find_stream_info(pFormatCtx, NULL);
	if(ret < 0) {
		printf("avformat_find_stream_info %s failed\n", argv[1]);
		return -1;
	}
	
	/*获取音频流和视频流索引,一般视频流索引是0,音频流索引是1*/
	int video_index = av_find_best_stream(pFormatCtx, AVMEDIA_TYPE_VIDEO, -1, -1, NULL, 0);
	if(video_index < 0) {
		printf("av_find_best_stream %s failed\n", argv[1]);
		return -1;
	}
	int audio_index = av_find_best_stream(pFormatCtx, AVMEDIA_TYPE_AUDIO, -1, -1, NULL, 0);
	if(audio_index < 0) {
		printf("av_find_best_stream %s failed\n", argv[1]);
		return -1;
	}
	
	/*查找解码器上下文*/
	AVCodecContext *pCodecCtx = avcodec_alloc_context3(NULL);
	if(!pCodecCtx) {
		printf("avcodec_alloc_context3 %s failed\n", argv[1]);
		return -1;
	}

	/*拷贝解码器参数*/
	ret = avcodec_parameters_to_context(pCodecCtx, pFormatCtx->streams[video_index]->codecpar);
	if(ret < 0) {
		printf("avcodec_parameters_to_context %s failed\n", argv[1]);
		return -1;
	}

	/*查找解码器*/
	AVCodec *pCodec = avcodec_find_decoder(pCodecCtx->codec_id);
	if(!pCodec) {
		printf("avcodec_find_decoder %d failed\n", pCodecCtx->codec_id);
		return -1;
	}

	/*打开解码器,将解码器和解码器上下文关联*/
	ret = avcodec_open2(pCodecCtx, pCodec, NULL);
	if(ret < 0) {
		printf("avcodec_open2 %s failed\n", argv[1]);
		return -1;
	}

	/*查看文件信息*/
	/*av_dump_format(pFormatCtx, 0, argv[1], NULL);*/

	/*分配一个AVPacket*/
	AVPacket *pkt = av_packet_alloc();

	/*pkt初始化*/
	av_init_packet(pkt);

	/*分配一个AVFrame*/
	AVFrame *frame = av_frame_alloc();
	
	while(g_quit != 1) {
		/*读取音视频包*/
		ret = av_read_frame(pFormatCtx, pkt);
		if(ret < 0) {
			printf("read end of\n");
			break;
		}
		
		/*通过索引判断音频流和视频流*/
		if(pkt->stream_index == video_index) {
			/*解码*/
			/*发送原始视频流包去解码*/
			ret = avcodec_send_packet(pCodecCtx, pkt);
			if(ret != 0) {
				printf("avcodec_send_packet ret:%d\n", ret);
			}
			
			/*获取解码后的视频帧*/
			ret = avcodec_receive_frame(pCodecCtx, frame);
			if(ret != 0) {
				printf("avcodec_send_packet ret:%d\n", ret);
			}
			
			/*将视频帧播放,这个部分是根据sdl写的*/
			if(ret == 0) {
				
			}
		}
		else if(pkt->stream_index == audio_index) {
			
		}
		else {
			printf("read unkown packet\n");
		}
		/*释放包内存*/
		av_packet_unref(pkt);
	}

Original  ffmpeg--simple player code_Using ffmpeg sdk to write a simple player_erer shepherd's blog-CSDN blog

★The business card at the end of the article can receive audio and video development learning materials for free, including (FFmpeg, webRTC, rtmp, hls, rtsp, ffplay, srs) and audio and video learning roadmaps, etc.

see below!

 

Guess you like

Origin blog.csdn.net/yinshipin007/article/details/131818085