如何在libavcodec中设置解码像素格式
How to set decode pixel format in libavcodec?
我通过libavcodec解码视频,使用以下代码:
//Open input file
if(avformat_open_input(&ctx, filename, NULL, NULL)!=0)
return FALSE; // Couldn't open file
if(avformat_find_stream_info(ctx, NULL)<0)
return FALSE; // Couldn't find stream information
videoStream = -1;
//find video stream
for(i=0; i<ctx->nb_streams; i++)
{
if((ctx->streams[i])->codec->codec_type==AVMEDIA_TYPE_VIDEO)
{
videoStream=i;
break;
}
}
if (videoStream == -1)
return FALSE; // Didn't find a video stream
video_codec_ctx=ctx->streams[videoStream]->codec;
//find decoder
video_codec=avcodec_find_decoder(video_codec_ctx->codec_id);
if(video_codec==NULL)
return FALSE; // Codec not found
if(avcodec_open(video_codec_ctx, video_codec)<0)
return -1; // Could not open codec
video_frame=avcodec_alloc_frame();
scaled_frame=avcodec_alloc_frame();
static struct SwsContext *img_convert_ctx;
if(img_convert_ctx == NULL)
{
int w = video_codec_ctx->width;
int h = video_codec_ctx->height;
img_convert_ctx = sws_getContext(w, h,
video_codec_ctx->pix_fmt,
w, h, dst_pix_fmt, SWS_BICUBIC,
NULL, NULL, NULL);
if(img_convert_ctx == NULL) {
fprintf(stderr, "Cannot initialize the conversion context!n");
return FALSE;
}
}
while(b_play)
{
if (av_read_frame(ctx, &packet) < 0)
{
break;
}
if(packet.stream_index==videoStream) {
// Decode video frame
avcodec_decode_video2(video_codec_ctx, video_frame, &frameFinished,
&packet);
// Did we get a video frame?
if(frameFinished)
{
if (video_codec_ctx->pix_fmt != dst_pix_fmt)
{
if (video_codec_ctx->pix_fmt != dst_pix_fmt)
sws_scale(img_convert_ctx, video_frame->data,
video_frame->linesize, 0,
video_codec_ctx->height,
scaled_frame->data, scaled_frame->linesize);
}
}
}
av_free_packet(&packet);
}
代码工作正常,但有必要将每个帧转换为所需的格式。是否可以在没有sws_scale的情况下设置解码的像素格式以获得正确的格式?
非常感谢你的回答。
ffmpeg
的AVCodec
实例(静态解码器"工厂"对象)每个都定义了它们支持的像素格式数组,以值-1结束。
AVCodecContext
(解码器实例)对象有一个名为get_format
的回调函数指针:它是该结构中的函数指针。
在编解码器初始化的某个时刻,使用AVCodec
工厂对象的支持格式数组调用此回调函数,回调应该从该数组中选择一种格式(有点像"pick a card,any card")并返回该值。此get_format
回调的默认实现是一个名为avcodec_default_get_format
的函数。(已安装avcodec_get_context_defaults2
)。这个默认函数非常简单地实现了"pick a format"逻辑:它选择数组的第一个元素,而不是仅硬件加速的像素格式。
如果您希望编解码器使用不同的像素格式,您可以在上下文对象中安装自己的get_format
回调。但是,回调必须返回数组中的一个值(就像从菜单中进行选择一样)。它不能返回任意值。编解码器将只支持它在数组中指定的格式。
浏览一系列可用的格式并选择最好的格式。如果你幸运的话,它正是你真正想要的,sws_scale
函数不必进行像素格式转换。(此外,如果您没有要求缩放或裁剪图片,sws_scale应该识别出转换是noop。)
相关文章:
- 如何在不产生任何垃圾的情况下获得C中的像素
- 在C++中使用GDAL可以将图像的像素坐标转换为lat,long吗
- 如何在24位SDL_Surface上设置像素的颜色
- 如何从SDL_Surface获取特定像素的颜色
- 如何将CMSampleBufferRef/CIImage/UIImage转换为像素,例如uint8_t[]
- 在C++中查找像素 RGB 数据的最快方法是什么?
- 是否可以从 OpenGL 缓冲区获取原始大小的像素?
- 选择基于另一个垫子的非零像素的cv::Mat的一部分?
- 如何使用 sdl2 快速绘制像素网格?
- 如何在C++中进行像素操作? - Linux
- 他们如何将红外锁定像素转换为镜头前方 1m 的正常平面上的位置
- 访问随机图像像素的快速方法,最多一次
- OpenCV 像素访问点与 at() - 不同的值
- 如何使用 freetype2 访问单色位图中的像素状态
- 尝试渲染像素坐标时,简单线条渲染失败
- 计算另一个图像像素满足条件的像素值的平均值
- 如何返回定义良好的内存部分?例如来自图像数据的像素的颜色值
- 在Qt-cpp中通过像素获取QString的子字符串
- 使用C++解码为ffmpeg中的特定像素格式
- 如何在libavcodec中设置解码像素格式