dranger.comのチュートリアルを使用して画像をデコードしようとしています。以下は、私が作業しているコードです。このコードは、のpgm_save()関数と、廃止された関数を置き換えるだけでなく、ほとんど変更されていません。FFmpegでビデオフレームをデコードするときに裂けた画像
プログラムが正常にコンパイルが、私はビデオを処理しようとしたとき、私はこのような効果引き裂く取得しています:image1とこのimage2を。
(サイド質問:私は(avpicture_fillを交換しようとしました)av_image_copy_to_buffer()で推奨されていませんが、存在する場合、私は疑問に思う私がアクセス違反エラーを取得していますので、あるとして、私はそれを残しました。フレームデータをバッファに割り当てる適切な方法です)。
私が使用しているライブラリは、ffmpeg-20160219-git-98a0053-win32-devです。誰かが私にこれを手伝ってもらえると本当に感謝します。
// Decode video and save frames
char filename[] = "test%0.3d.ppm";
static void ppm_save(unsigned char *buf, int wrap, int xsize, int ysize,
int framenum)
{
char filenamestr[sizeof(filename)];
FILE *f;
int i;
sprintf_s(filenamestr, sizeof(filenamestr), filename, framenum);
fopen_s(&f,filenamestr,"w");
fprintf(f,"P6\n%d %d\n%d\n",xsize,ysize,255);
for(i=0;i<ysize;i++)
fwrite(buf + i * wrap,1,xsize*3,f);
fclose(f);
}
int main(int argc, char** argv)
{
AVFormatContext *pFormatCtx = NULL;
AVCodecContext *codecCtx= NULL;
AVCodec *codec;
int videoStream;
int frameFinished;
AVFrame *inframe;
AVFrame *outframe;
struct SwsContext *sws_ctx = NULL;
AVPacket avpkt;
unsigned int i;
printf("Video decoding application\n");
// Register all formats and codecs
av_register_all();
// Open video file
if (avformat_open_input(&pFormatCtx, argv[1], NULL, NULL) != 0)
return -1; // Couldn't open file
// Retrieve stream information
if (avformat_find_stream_info(pFormatCtx, NULL) < 0)
return -1; // Couldn't find stream information
// Dump information about file onto standard error (Not necessary)
av_dump_format(pFormatCtx, 0, argv[1], 0);
// Find the first video stream
videoStream = -1;
for (i = 0; i < pFormatCtx->nb_streams; i++)
if (pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
videoStream = i;
break;
}
if (videoStream == -1)
return -1; // Didn't find a video stream
/* find the video decoder */
codec = avcodec_find_decoder(pFormatCtx->streams[videoStream]->codec->codec_id);
if (!codec) {
fprintf(stderr, "codec not found\n");
exit(1);
}
codecCtx= avcodec_alloc_context3(codec);
if(avcodec_copy_context(codecCtx, pFormatCtx->streams[i]->codec) != 0) {
fprintf(stderr, "Couldn't copy codec context");
return -1; // Error copying codec context
}
/* open it */
if (avcodec_open2(codecCtx, codec, NULL) < 0) {
fprintf(stderr, "could not open codec\n");
exit(1);
}
// Allocate video frame
inframe= av_frame_alloc();
if(inframe==NULL)
return -1;
// Allocate output frame
outframe=av_frame_alloc();
if(outframe==NULL)
return -1;
// Determine required buffer size and allocate buffer
int numBytes=av_image_get_buffer_size(AV_PIX_FMT_RGB24, codecCtx->width,
codecCtx->height,1);
uint8_t* buffer=(uint8_t *)av_malloc(numBytes*sizeof(uint8_t));
// Assign appropriate parts of buffer to image planes in outframe
// Note that outframe is an AVFrame, but AVFrame is a superset
// of AVPicture
avpicture_fill((AVPicture *)outframe, buffer, AV_PIX_FMT_RGB24,
codecCtx->width, codecCtx->height);
//av_image_copy_to_buffer(buffer, numBytes,
// outframe->data, outframe->linesize,
// AV_PIX_FMT_RGB24, codecCtx->width, codecCtx->height,1);
// initialize SWS context for software scaling
sws_ctx = sws_getContext(codecCtx->width,
codecCtx->height,
codecCtx->pix_fmt,
codecCtx->width,
codecCtx->height,
AV_PIX_FMT_RGB24,
SWS_BILINEAR,
NULL,
NULL,
NULL
);
// av_init_packet(&avpkt);
i = 0;
while(av_read_frame(pFormatCtx, &avpkt)>=0) {
// Is this a packet from the video stream?
if(avpkt.stream_index==videoStream) {
// Decode video frame
avcodec_decode_video2(codecCtx, inframe, &frameFinished, &avpkt);
// Did we get a video frame?
if(frameFinished) {
// Convert the image from its native format to RGB
sws_scale(sws_ctx, (uint8_t const * const *)inframe->data,
inframe->linesize, 0, codecCtx->height,
outframe->data, outframe->linesize);
// Save the frame to disk
if(++i%15 == 0)
ppm_save(outframe->data[0], outframe->linesize[0],
codecCtx->width, codecCtx->height, i);
}
}
// Free the packet that was allocated by av_read_frame
av_packet_unref(&avpkt);
}
// Free the RGB image
av_free(buffer);
av_frame_free(&outframe);
// Free the original frame
av_frame_free(&inframe);
// Close the codecs
avcodec_close(codecCtx);
av_free(codecCtx);
// Close the video file
avformat_close_input(&pFormatCtx);
printf("\n");
return 0;
}