使用libavcodec解码mJPEG [英] Decoding mJPEG with libavcodec

查看:953
本文介绍了使用libavcodec解码mJPEG的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在创建视频会议应用程序。我发现网络摄像头(至少有3个)为mJPEG输出格式提供更高的分辨率和帧率。到目前为止,我使用YUY2,转换为I420用X264进行压缩。要将mJPEG转码为I420,我需要先解码它。我试图解码图像从webcam与libavcodec。这是我的代码。

I am creating video conference application. I have discovered that webcams (at least 3 I have) provide higher resolutions and framerates for mJPEG output format. So far I was using YUY2, converted in I420 for compression with X264. To transcode mJPEG to I420, I need to decode it first. I am trying to decode images from webcam with libavcodec. This is my code.

初始化:

// mJPEG to I420 conversion
AVCodecContext * _transcoder = nullptr;
AVFrame * _outputFrame;
AVPacket _inputPacket;

avcodec_register_all();
_outputFrame = av_frame_alloc();
av_frame_unref(_outputFrame);
av_init_packet(&_inputPacket);

AVCodec * codecDecode = avcodec_find_decoder(AV_CODEC_ID_MJPEG);

_transcoder = avcodec_alloc_context3(codecDecode);
avcodec_get_context_defaults3(_transcoder, codecDecode);
_transcoder->flags2 |= CODEC_FLAG2_FAST;
_transcoder->pix_fmt = AVPixelFormat::AV_PIX_FMT_YUV420P;
_transcoder->width = width;
_transcoder->height = height;
avcodec_open2(_transcoder, codecDecode, nullptr);

解码:

_inputPacket.size = size;
_inputPacket.data = data;

int got_picture;
int decompressed_size = avcodec_decode_video2(_transcoder, _outputFrame, &got_picture, &_inputPacket);

但是到目前为止,我得到的是一个绿色屏幕。我在哪里错了?

But so far, what I am getting is a green screen. Where am I wrong?

UPD:
我已启用libavcodec记录,但没有警告或错误。
我还发现_outputframe有AV_PIX_FMT_YUVJ422P作为格式和颜色空间,这不适合libavcodec的枚举中的值(实际值是156448160)。

UPD: I have enabled libavcodec logging, but there are not warnings or errors. Also I have discovered that _outputframe has AV_PIX_FMT_YUVJ422P as format and colorspace, which does not fit any on values in libavcodec's enums (the actual value is 156448160).

推荐答案

根据评论提出建议后,我想出了工作解决方案。

After suggestions from comments, I came up with working solution.

初始化:

av_init_packet(&_inputPacket);

AVCodec * codecDecode = avcodec_find_decoder(AV_CODEC_ID_MJPEG);

_transcoder = avcodec_alloc_context3(codecDecode);
avcodec_get_context_defaults3(_transcoder, codecDecode);
avcodec_open2(_transcoder, codecDecode, nullptr);

// swscale contex init
mJPEGconvertCtx = sws_getContext(width, height, AV_PIX_FMT_YUVJ422P, 
        width, height, AV_PIX_FMT_YUV420P, SWS_FAST_BILINEAR, nullptr, nullptr, nullptr);

// x264 pic init
x264_picture_t _pic_in;
x264_picture_alloc(&_pic_in, X264_CSP_I420, width, height);
_pic_in.img.i_csp = X264_CSP_I420 ;
_pic_in.img.i_plane = 3;
_pic_in.img.i_stride[0] = width;
_pic_in.img.i_stride[1] = width / 2;
_pic_in.img.i_stride[2] = width / 2;

_pic_in.i_type = X264_TYPE_AUTO ;
_pic_in.i_qpplus1 = 0;

转码:

_inputPacket.size = size;
_inputPacket.data = data;

int got_picture;

// decode
avcodec_decode_video2(_transcoder, _outputFrame, &got_picture, &_inputPacket); 

// transform
sws_scale(_mJPEGconvertCtx, _outputFrame->data, _outputFrame->linesize, 0, height, 
        _pic_in.img.plane, _pic_in.img.i_stride);

然后,_pic_in直接由x264使用。图片很好,但转码时间对于更高的分辨率是可怕的。

Afterwards, _pic_in is used directly by x264. Image is fine, but the transcoding times are horrible for higher resolutions.

这篇关于使用libavcodec解码mJPEG的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆