2,275
社区成员
发帖
与我相关
我的任务
分享
int main(int argc, char *argv[])
{
int err;
int i, j;
int byte_cnt;
int got_frame = 0;
unsigned int video_stream = -1;
unsigned char *buffer;
char path[256];
unsigned int index = 0;
AVFormatContext *pFormatCtx = NULL;
AVCodecContext *pCodecCtx = NULL;
AVFrame *pFrame = NULL;
AVFrame *pFrameRgb = NULL;
AVCodec *pCodec = NULL;
AVPacket packet = {0}, out_pkt;
AVCodecParserContext *pCodecParserCtx = NULL;
struct SwsContext *pSwsCtx = NULL;
av_log_set_level(AV_LOG_DEBUG);
if (argc != 2) {
av_info_log("argument number err!\n");
return -1;
}
// register all format of video file, and codec
av_info_log("av register!\n");
av_register_all();
// open video file, get head info from file
av_info_log("open input media file!\n");
err = avformat_open_input(&pFormatCtx, argv[1], NULL, NULL);
if (err<0) {
av_err_log("avformat_open_input open %s fail, err=%d\n",argv[1], err);
return -1;
}
// get stream info(AVFormatContext)
av_info_log("get stream info!\n");
err = avformat_find_stream_info(pFormatCtx, NULL);
if (err<0) {
av_err_log("can not find codec parameter!\n");
goto err1;
}
// Dump information about file onto standard error
av_dump_format(pFormatCtx, 0, argv[1], 0);
av_info_log("nb_streams = %d\n", pFormatCtx->nb_streams);
// get video stream
for (i=0; i<pFormatCtx->nb_streams; i++) {
if (pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
video_stream = i;
break;
}
}
if (video_stream == -1) {
av_err_log("not find video stream!\n");
goto err1;
}
// get AVCodecContext(codec info)
pCodecCtx = pFormatCtx->streams[video_stream]->codec;
// get AVCodec(get codec)
pCodec = avcodec_find_decoder(pCodecCtx->codec_id);
if (!pCodec) {
av_err_log("%s codec not support!\n", avcodec_get_name(pCodecCtx->codec_id));
goto err1;
}
av_info_log("find video decoder sucess! name=\"%s\",id=%d\n", avcodec_get_name(pCodecCtx->codec_id), pCodecCtx->codec_id);
// open codec
err = avcodec_open2(pCodecCtx, pCodec, NULL);
if (err < 0) {
av_err_log("open %s(id=%d) codec fail!\n", avcodec_get_name(pCodecCtx->codec_id), pCodecCtx->codec_id);
goto err1;
}
av_info_log("open video codec sucess!\n");
//pFrame = avcodec_alloc_frame();
//if (!pFrame) {
// printf("alloc frame faild! at %d\n", __LINE__);
// goto err1;
//}
pFrame = av_frame_alloc();
if (!pFrame) {
av_err_log("alloc frame fail at %d\n", __LINE__);
goto err1;
}
pFrameRgb = av_frame_alloc();
if (!pFrameRgb) {
av_err_log("alloc frame fail at %d\n", __LINE__);
goto err2;
}
// caculate picture size
byte_cnt = avpicture_get_size(AV_PIX_FMT_RGB24, pCodecCtx->width, pCodecCtx->height);
av_info_log("a frame(RGB24) image size is %d\n", byte_cnt);
// alloc a size memrry of picture
buffer = (unsigned char *)av_malloc(byte_cnt * sizeof(unsigned char));
if (!buffer) {
av_err_log("alloc frame fail at %d\n", __LINE__);
goto err2;
}
avpicture_fill((AVPicture *)pFrameRgb, buffer, AV_PIX_FMT_RGB24, pCodecCtx->width, pCodecCtx->height);
//av_info_log("avpicture fill!\n");
// init AVCodecParsetContext struct
pCodecParserCtx = av_parser_init(pCodecCtx->codec_id);
do {
unsigned char *p_out_buf = NULL, *p_in_buf = NULL;
unsigned int in_size = 0, out_size = 0, length = 0;
//av_init_packet(&packet);
av_free_packet(&packet);
if (av_read_frame(pFormatCtx, &packet)<0) {
av_err_log("av_read_frame fail!\n");
break;
}
p_in_buf = packet.data;
in_size = packet.size;
p_out_buf = NULL;
out_size = 0;
do {
length = av_parser_parse2(pCodecParserCtx, pCodecCtx->codec,
&p_out_buf, &out_size,
p_in_buf, in_size,
AV_NOPTS_VALUE, AV_NOPTS_VALUE, AV_NOPTS_VALUE);
if (p_out_buf && (out_size!=0)) {
av_info_log("av_paraser_parse2 seperate a frame as a packet: size=%dK(%dByte)\n", out_size/1024, out_size);
}
av_info_log("p_out_buf=0x%x, out_size=%d, length=%d\n", p_out_buf, out_size, length);
if (length <= 0) {
av_info_log("av_parser_parse2 return <=0, continue!\n");
continue;
} else {
av_init_packet(&out_pkt);
out_pkt.data = p_out_buf;
out_pkt.size = out_size;
p_in_buf += length;
in_size -= length;
}
if (pFormatCtx->streams[packet.stream_index]->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
err = avcodec_decode_video2(pCodecCtx, pFrame, &got_frame, &out_pkt);
if (err < 0) {
av_err_log("video decode fail!\n");
goto err3;
}
if (got_frame) {
//create SW scale context
av_info_log("decode a frame finished!\n");
av_info_log("the one line data of the frame:\n");
printf("\n");
pSwsCtx = sws_getCachedContext(pSwsCtx, pCodecCtx->width, pCodecCtx->height, pCodecCtx->pix_fmt,
pCodecCtx->width, pCodecCtx->height, AVMEDIA_TYPE_VIDEO,
SWS_BICUBIC, NULL, NULL, NULL);
sws_scale(pSwsCtx, (const unsigned char* const *)pFrame->data[0], pFrame->linesize, 0, pCodecCtx->height, pFrameRgb->data, pFrameRgb->linesize);
av_info_log("cover img format finish!\n");
} else {
av_info_log("decode a frame fail!\n");
break;
}
}
} while (in_size!=0);
break;
} while (1);
av_free_packet(&packet);
av_free(buffer);
av_frame_free(&pFrame);
avformat_close_input(&pFormatCtx);
return 0;
err3:
av_frame_free(&pFrame);
av_free_packet(&packet);
av_free(buffer);
err2:
av_frame_free(&pFrame);
err1:
avformat_close_input(&pFormatCtx);
return -1;
}