gpt4 book ai didi

ffmpeg - 使用 libavcodec 读取 .mkv 视频文件

转载 作者:行者123 更新时间:2023-12-04 22:58:37 28 4
gpt4 key购买 nike

尝试读取 .mkv 文件并将其写入 .bmp,但生成的 .bmp 是黑白的,并且包含多个应该写入的迷你图像:

int main()
{
av_register_all();
avformat_network_init();
avfilter_register_all();

//crashes on -Ofast without =NULL initialization:
AVFormatContext * format = NULL;
if ( avformat_open_input( & format, VIDEO_FILE, NULL, NULL ) != 0 ) {
cerr << "Could not open file " << VIDEO_FILE << endl;
return -1;
}

// Retrieve stream information
if ( avformat_find_stream_info( format, NULL ) < 0) {
cerr << "avformat_find_stream_info() failed." << endl;
return -1;
}
av_dump_format( format, 0, VIDEO_FILE, false );

AVCodec * video_dec = (AVCodec*)1;
AVCodec * audio_dec = (AVCodec*)1;
const auto video_stream_index = av_find_best_stream( format, AVMEDIA_TYPE_VIDEO, -1, -1, & video_dec, 0 );
const auto audio_stream_index = av_find_best_stream( format, AVMEDIA_TYPE_AUDIO, -1, -1, & audio_dec, 0 );
if ( video_stream_index < 0 ) {
cerr << "Failed to find video stream." << endl;
return -1;
}
if ( audio_stream_index < 0 ) {
cerr << "Failed to find audio stream." << endl;
return -1;
}

AVCodecParameters * videoParams = format->streams[ video_stream_index ]->codecpar;
cout << "Having " << videoParams->width << " | " << videoParams->height << " video." << endl;

av_read_play( format );

// create decoding context
AVCodecContext * video_ctx = avcodec_alloc_context3( video_dec );
AVCodecContext * audio_ctx = avcodec_alloc_context3( audio_dec );
if ( ! video_ctx || ! audio_ctx ) {
cerr << "Failed to avcodec_alloc_context3()" << endl;
return -1;
}
if ( video_dec->capabilities & AV_CODEC_CAP_TRUNCATED ) video_ctx->flags |= AV_CODEC_FLAG_TRUNCATED; // we do not send complete frames

/* For some codecs, such as msmpeg4 and mpeg4, width and height
MUST be initialized there because this information is not
available in the bitstream. */

avcodec_parameters_to_context( video_ctx, format->streams[ video_stream_index ]->codecpar );
avcodec_parameters_to_context( audio_ctx, format->streams[ audio_stream_index ]->codecpar );
if ( avcodec_open2( video_ctx, video_dec, NULL ) < 0 ) {
cout << "Failed to open video decoder." << endl;
return -1;
}
if ( avcodec_open2( audio_ctx, audio_dec, NULL ) < 0 ) {
cout << "Failed to open audio decoder." << endl;
return -1;
}

uint8_t* picture_buffer = (uint8_t*) (av_malloc( avpicture_get_size( AV_PIX_FMT_RGB24 , videoParams->width, videoParams->height ) ));
AVFrame* picture = av_frame_alloc();
avpicture_fill( (AVPicture *) picture, picture_buffer, AV_PIX_FMT_RGB24, video_ctx->width, video_ctx->height );

AVPacket packet;
av_init_packet( & packet );

int cnt = 0;
while ( av_read_frame( format, & packet ) >= 0 && cnt < 10 ) {
if ( packet.stream_index == video_stream_index ) {
int check;
const auto result = avcodec_decode_video2( video_ctx, picture, & check, & packet );
cout << "Bytes decoded " << result << " check " << check << endl;

std::string name = "debug/av/";
name += std::to_string( cnt ) + ".bmp";
cout << "Writing frame " << name << " with linesize " << picture->linesize[0] << " ..." << endl;
write_bmp( (uint8_t*) picture->data, videoParams->width, videoParams->height, name.c_str() );

av_frame_unref( picture );

++ cnt;
}
else if ( packet.stream_index == audio_stream_index ) {
cout << "Sound packet" << endl;
}
av_free_packet( & packet );
av_init_packet( & packet );
}
}

我该如何解决?

最佳答案

您必须使用 swscale 将图片转换为 RGB。

关于ffmpeg - 使用 libavcodec 读取 .mkv 视频文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60612430/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com