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 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97
| int avcodec_save_video_file(AVFormatContext *pFormatCtx, int streamIndex, char *fileName) { AVCodec *pCodec; AVCodecContext *pCodecCtx; AVCodecParameters *codecpar = pFormatCtx->streams[streamIndex]->codecpar;
pCodec = avcodec_find_decoder(codecpar->codec_id); if (!pCodec) { printf("can't decoder audio\n"); return -1; } pCodecCtx = avcodec_alloc_context3(pCodec); if (!pCodecCtx) { printf("can't allocate a audio decoding context\n"); return -1; }
avcodec_parameters_to_context(pCodecCtx, codecpar);
if (avcodec_open2(pCodecCtx, pCodec, NULL) < 0) { printf("can't open codec\n"); return -1; }
AVPacket *pPacket = (AVPacket*) av_malloc(sizeof(AVPacket)); AVFrame *pFrame = av_frame_alloc(); AVFrame *pFrameYUV = av_frame_alloc();
unsigned char *outBuffer = (unsigned char*) av_malloc( av_image_get_buffer_size(AV_PIX_FMT_YUV420P, pCodecCtx->width, pCodecCtx->height, 1)); av_image_fill_arrays(pFrameYUV->data, pFrameYUV->linesize, outBuffer, AV_PIX_FMT_YUV420P, pCodecCtx->width, pCodecCtx->height, 1);
SwsContext *pImgConvertCtx = sws_getContext(pCodecCtx->width, pCodecCtx->height, pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height, AV_PIX_FMT_YUV420P, SWS_BICUBIC, NULL, NULL, NULL);
printf("width = %d, height = %d, name = %s\n", pCodecCtx->width, pCodecCtx->height, pCodec->name);
FILE *fp = fopen(fileName, "wb+");
av_seek_frame(pFormatCtx, streamIndex, 0, AVSEEK_FLAG_BACKWARD);
while (av_read_frame(pFormatCtx, pPacket) >= 0) { if (pPacket->stream_index == streamIndex) { int ret = avcodec_send_packet(pCodecCtx, pPacket); if (ret < 0) { printf("Decode error\n"); break; }
if (avcodec_receive_frame(pCodecCtx, pFrame) >= 0) { sws_scale(pImgConvertCtx, pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameYUV->data, pFrameYUV->linesize);
int y_size = pCodecCtx->width * pCodecCtx->height; fwrite(pFrameYUV->data[0], 1, y_size, fp); fwrite(pFrameYUV->data[1], 1, y_size / 4, fp); fwrite(pFrameYUV->data[2], 1, y_size / 4, fp); } }
av_packet_unref(pPacket); }
fclose(fp); av_frame_free(&pFrame); av_frame_free(&pFrameYUV); av_free(outBuffer); avcodec_close(pCodecCtx);
return 0; }
|