을 설정하는 방법을 디코딩 픽셀 형식을 위해 libavcodec?
-
11-12-2019 - |
문제
나는 비디오를 디코딩을 통해 위해 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
ko AVCodec
인스턴스(static 디코더"공장은"개체)각각의 정의는 배열의 픽셀 형식을 지원하는 종료에 의 값은-1 입니다.
이 AVCodecContext
(디코더 인스턴스)객체가 있을 콜백 함수 포인터이라고 get_format
:그것은 함수 포인터에서는 구조입니다.
이 콜백 함수 호출에 어떤 시점에서 코덱을 초기화과 AVCodec
공장체의 배열을 지원하는 형식,그리고 콜백되어 중 하나를 선택하는 이 포맷에서는 array(의 종류는 다음과 같"카드를 선택하고,모든 카드에")을 반환하는 값입니다.의 기본 구현은이 get_format
콜백 함수 호출 avcodec_default_get_format
.(이 설치 avcodec_get_context_defaults2
).이러한 기본 기능을 구현하는"선택한 형식"논리히:그것은 선택의 첫 번째 요소에 배열되지 않는 하드웨어 가속만 픽셀 형식입니다.
당신이 원하는 코덱과 함께 작동 다른 픽셀 형식으로,당신이 무엇을 할 수 있을 설치하고 자신의 get_format
콜백 컨텍스트에 개체입니다.그러나,콜백을 반환해야 하에 있는 값의 배열(선택하는 것과 같은 메뉴에서).그것은 반환할 수 없습니다 임의의 값입니다.코덱에만 지원하는 형식을 지정한다.
보의 배열을 사용할 수 있는 형식을 선택합니다.당신이 운이 좋다면,그것의 정확한 한 당신이 실제로 원하는 sws_scale
기능을 할 필요가 없 픽셀 형식 변환입니다.(는 경우,또한,당신은하지 않는 요청은 규모나 사진을 sws_scale 을 인식해야한다는 것을 변환하는 noop.)