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;
}