1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
| static int write_video_frame(AVFormatContext *oc, OutputStream *ost) { int ret; AVCodecContext *c; AVFrame *frame; int got_packet = 0; AVPacket pkt = { 0 };
c = ost->enc; frame = get_video_frame(ost); av_init_packet(&pkt); ret = avcodec_encode_video2(c, &pkt, frame, &got_packet); if (ret < 0) { exit(1); } if (got_packet) { ret = write_frame(oc, &c->time_base, ost->st, &pkt); } else { ret = 0; } if (ret < 0) { exit(1); } return (frame || got_packet) ? 0 : 1; }
static AVFrame *get_video_frame(OutputStream *ost) { AVCodecContext *c = ost->enc;
if (av_compare_ts(ost->next_pts, c->time_base,STREAM_DURATION, (AVRational) { 1, 1 }) >= 0) return NULL; if (av_frame_make_writable(ost->frame) < 0) exit(1); if (c->pix_fmt != AV_PIX_FMT_YUV420P) { if (!ost->sws_ctx) { ost->sws_ctx = sws_getContext(c->width, c->height, AV_PIX_FMT_YUV420P, c->width, c->height, c->pix_fmt, SCALE_FLAGS, NULL, NULL, NULL); if (!ost->sws_ctx) { exit(1); } } fill_yuv_image(ost->tmp_frame, ost->next_pts, c->width, c->height); sws_scale(ost->sws_ctx, (const uint8_t * const *)ost->tmp_frame->data, ost->tmp_frame->linesize, 0, c->height, ost->frame->data, ost->frame->linesize); } else { fill_yuv_image(ost->frame, ost->next_pts, c->width, c->height); } ost->frame->pts = ost->next_pts++; return ost->frame; } static void fill_yuv_image(AVFrame *pict, int frame_index, int width, int height) { int x, y, i; i = frame_index; for (y = 0; y < height; y++) for (x = 0; x < width; x++) pict->data[0][y * pict->linesize[0] + x] = x + y + i * 3; for (y = 0; y < height / 2; y++) { for (x = 0; x < width / 2; x++) { pict->data[1][y * pict->linesize[1] + x] = 128 + y + i * 2; pict->data[2][y * pict->linesize[2] + x] = 64 + x + i * 5; } } }
|