gpt4 book ai didi

c - 使用ffmpeg以相反的顺序解码然后重新编码帧

转载 作者:太空宇宙 更新时间:2023-11-04 04:42:05 24 4
gpt4 key购买 nike

我是 ffmpeg 的新手,现在我想解码帧并以相反的顺序将其编码回来。我用过this tutorial用于解码视频和this example将其编码回来。我可以正确解码帧,但是当我重新编码时,我得到的是虚拟图像而不是清晰的视频。我怎样才能得到真正的反转视频?

static void video_encode_example(const char *filename, int codec_id)
{
AVCodec *codec;
AVCodecContext *c= NULL;
int i, ret, x, y, got_output;
FILE *f;
struct SwsContext *sws_ctx = NULL;
AVFrame *frame;
AVFrame *frameRGB = NULL;
AVPacket pkt;
uint8_t endcode[] = { 0, 0, 1, 0xb7 };

printf("Encode video file %s\n", filename);

/* find the mpeg1 video encoder */
codec = avcodec_find_encoder(codec_id);
if (!codec) {
fprintf(stderr, "Codec not found\n");
exit(1);
}

c = avcodec_alloc_context3(codec);
if (!c) {
fprintf(stderr, "Could not allocate video codec context\n");
exit(1);
}

/* put sample parameters */
c->bit_rate = 400000;
/* resolution must be a multiple of two */
c->width = 352;
c->height = 288;
/* frames per second */
c->time_base = (AVRational){1,25};
/* emit one intra frame every ten frames
* check frame pict_type before passing frame
* to encoder, if frame->pict_type is AV_PICTURE_TYPE_I
* then gop_size is ignored and the output of encoder
* will always be I frame irrespective to gop_size
*/
c->gop_size = 10;
c->max_b_frames = 1;
c->pix_fmt = AV_PIX_FMT_YUV420P;

if (codec_id == AV_CODEC_ID_H264)
av_opt_set(c->priv_data, "preset", "slow", 0);

/* open it */
if (avcodec_open2(c, codec, NULL) < 0) {
fprintf(stderr, "Could not open codec\n");
exit(1);
}

f = fopen(filename, "wb");
if (!f) {
fprintf(stderr, "Could not open %s\n", filename);
exit(1);
}

frame = av_frame_alloc();
if (!frame) {
fprintf(stderr, "Could not allocate video frame\n");
exit(1);
}
frame->format = c->pix_fmt;
frame->width = c->width;
frame->height = c->height;

/* the image can be allocated by any means and av_image_alloc() is
* just the most convenient way if av_malloc() is to be used */
ret = av_image_alloc(frame->data, frame->linesize, c->width, c->height,
c->pix_fmt, 32);
if (ret < 0) {
fprintf(stderr, "Could not allocate raw picture buffer\n");
exit(1);
}

/* encode 1 second of video */
for (i = 0; i < 25; i++) {
av_init_packet(&pkt);
pkt.data = NULL; // packet data will be allocated by the encoder
pkt.size = 0;

fflush(stdout);
/* prepare a dummy image */
/* Y */
for (y = 0; y < c->height; y++) {
for (x = 0; x < c->width; x++) {
frame->data[0][y * frame->linesize[0] + x] = x + y + i * 3;
}
}

/* Cb and Cr */
for (y = 0; y < c->height/2; y++) {
for (x = 0; x < c->width/2; x++) {
frame->data[1][y * frame->linesize[1] + x] = 128 + y + i * 2;
frame->data[2][y * frame->linesize[2] + x] = 64 + x + i * 5;
}
}

frame->pts = i;

/* encode the image */
ret = avcodec_encode_video2(c, &pkt, frame, &got_output);
if (ret < 0) {
fprintf(stderr, "Error encoding frame\n");
exit(1);
}

if (got_output) {
// Convert the image from its native format to RGB
sws_scale
(
sws_ctx,
(uint8_t const * const *)frame->data,
frame->linesize,
0,
c->height,
frameRGB->data,
frameRGB->linesize
);
printf("Write frame %3d (size=%5d)\n", i, pkt.size);
fwrite(pkt.data, 1, pkt.size, f);
av_free_packet(&pkt);
}
}

/* get the delayed frames */
for (got_output = 1; got_output; i++) {
fflush(stdout);

ret = avcodec_encode_video2(c, &pkt, NULL, &got_output);
if (ret < 0) {
fprintf(stderr, "Error encoding frame\n");
exit(1);
}

if (got_output) {
printf("Write frame %3d (size=%5d)\n", i, pkt.size);
fwrite(pkt.data, 1, pkt.size, f);
av_free_packet(&pkt);
}
}

/* add sequence end code to have a real mpeg file */
fwrite(endcode, 1, sizeof(endcode), f);
fclose(f);

avcodec_close(c);
av_free(c);
av_freep(&frame->data[0]);
av_frame_free(&frame);
printf("\n");
}

最佳答案

假设您的代码示例与视频输入或反向编码无关,而只是一个“编码示例”。

一个视频文件由多个部分组成。首先,您有一种容器格式(例如 mkv 或 avi)。它包含有关此文件中哪些流的各种信息(字幕?有多少视频?多个音频流?类似的东西)。然后你有数据流。此文件中的视频流是数据包列表,由来自帧的特定编解码器(例如 h264 或 mpeg4)编码。

在您的代码示例中,您有一个帧列表,并且您正在使用编解码器对它们进行编码,从而为您提供一个数据包列表(我想它可以工作,因为它是一个教程代码)。但是这些数据包被转储到一个文件中,没有容器。因此,如果视频播放器想要阅读它们,我将很难猜测是什么格式。它在您的 link 中被列为第一行

您不想直接将数据包转储到文件中,而是想使用 FFmpeg 将数据包嵌入到容器中,并保存容器。你有一个所有这个过程的例子here

最后一件事:如果你想让你的视频倒序,你必须以倒序编码帧,而不仅仅是倒序多路复用数据包。

关于c - 使用ffmpeg以相反的顺序解码然后重新编码帧,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25428023/

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