erfasst wurden Ich versuche, die Bilder mit dem Tutorial bei dranger.com zu entschlüsseln. Unten ist der Code, mit dem ich arbeite. Der Code ist ziemlich unberührt von pgm_save() Funktion und ersetzt die veralteten Funktionen.Zerrissene Bilder, die beim Entschlüsseln von Videobildern mit FFmpeg
Das Programm erfolgreich kompiliert, aber als ich versuchte, ein Video zu verarbeiten, bekomme ich Tearing-Effekt wie folgt: image1 und dies image2.
(Side Frage: Ich habe versucht, avpicture_fill() zu ersetzen, die mit av_image_copy_to_buffer veraltet ist() aber ich bin eine Zugriffsverletzung Fehler bekommen, so dass ich ließ es wie ich frage mich, ob es gibt. ein geeigneter Weg für mich, die Rahmendaten einem Puffer zuzuweisen.)
Die Bibliothek, die ich verwende, ist ffmpeg-20160219-git-98a0053-win32-dev. Würde es wirklich schätzen, wenn mir jemand dabei helfen könnte.
// 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;
}