C#写一段ffmpeg解码h264的代码
时间: 2023-11-04 08:53:50 浏览: 203
ffmpeg解码h264
以下是使用FFmpeg解码H.264视频的示例代码,需要安装FFmpeg库并将其添加到项目引用中:
```csharp
using System;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;
using FFmpeg.AutoGen;
namespace FFmpegDecodeH264
{
class Program
{
static void Main(string[] args)
{
// 设置FFmpeg的路径
string ffmpegPath = @"C:\ffmpeg\bin\ffmpeg.exe";
ffmpeg.av_register_all();
// 打开输入文件
AVFormatContext* pFormatContext = null;
int result = ffmpeg.avformat_open_input(&pFormatContext, "input.h264", null, null);
if (result < 0)
{
Console.WriteLine("无法打开输入文件");
return;
}
// 获取流信息
result = ffmpeg.avformat_find_stream_info(pFormatContext, null);
if (result < 0)
{
Console.WriteLine("无法获取流信息");
return;
}
// 查找视频流
int videoStreamIndex = -1;
for (int i = 0; i < pFormatContext->nb_streams; i++)
{
if (pFormatContext->streams[i]->codec->codec_type == AVMediaType.AVMEDIA_TYPE_VIDEO)
{
videoStreamIndex = i;
break;
}
}
if (videoStreamIndex == -1)
{
Console.WriteLine("找不到视频流");
return;
}
// 获取视频流解码器
AVCodecContext* pCodecContext = pFormatContext->streams[videoStreamIndex]->codec;
AVCodec* pCodec = ffmpeg.avcodec_find_decoder(pCodecContext->codec_id);
if (pCodec == null)
{
Console.WriteLine("无法获取解码器");
return;
}
// 打开解码器
result = ffmpeg.avcodec_open2(pCodecContext, pCodec, null);
if (result < 0)
{
Console.WriteLine("无法打开解码器");
return;
}
// 循环读取帧并解码
AVPacket packet = new AVPacket();
AVFrame* pFrame = ffmpeg.av_frame_alloc();
AVFrame* pFrameRGB = ffmpeg.av_frame_alloc();
SwsContext* pSwsContext = null;
while (ffmpeg.av_read_frame(pFormatContext, &packet) >= 0)
{
if (packet.stream_index == videoStreamIndex)
{
// 解码一帧
int frameFinished = 0;
result = ffmpeg.avcodec_decode_video2(pCodecContext, pFrame, &frameFinished, &packet);
if (result < 0)
{
Console.WriteLine("解码错误");
return;
}
// 如果解码成功,将帧转换为RGB格式
if (frameFinished != 0)
{
// 初始化转换器
if (pSwsContext == null)
{
pSwsContext = ffmpeg.sws_getContext(
pCodecContext->width, pCodecContext->height, pCodecContext->pix_fmt,
pCodecContext->width, pCodecContext->height, AVPixelFormat.AV_PIX_FMT_RGB24,
ffmpeg.SWS_BILINEAR, null, null, null);
}
// 分配RGB帧
int numBytes = ffmpeg.av_image_get_buffer_size(AVPixelFormat.AV_PIX_FMT_RGB24, pCodecContext->width, pCodecContext->height, 1);
byte* buffer = (byte*)ffmpeg.av_malloc((ulong)numBytes);
ffmpeg.av_image_fill_arrays(pFrameRGB->data, pFrameRGB->linesize, buffer, AVPixelFormat.AV_PIX_FMT_RGB24, pCodecContext->width, pCodecContext->height, 1);
// 转换帧
ffmpeg.sws_scale(pSwsContext, pFrame->data, pFrame->linesize, 0, pCodecContext->height, pFrameRGB->data, pFrameRGB->linesize);
// 显示帧
Bitmap bitmap = new Bitmap(pCodecContext->width, pCodecContext->height, pCodecContext->width * 3, PixelFormat.Format24bppRgb, new IntPtr(pFrameRGB->data[0]));
bitmap.Save("output.bmp", ImageFormat.Bmp);
// 释放RGB帧内存
ffmpeg.av_free(buffer);
}
}
// 释放数据包
ffmpeg.av_packet_unref(&packet);
}
// 释放资源
ffmpeg.av_frame_free(&pFrame);
ffmpeg.av_frame_free(&pFrameRGB);
ffmpeg.sws_freeContext(pSwsContext);
ffmpeg.avcodec_close(pCodecContext);
ffmpeg.avformat_close_input(&pFormatContext);
}
}
}
```
阅读全文