FFmpeg开发实战(六):jpeg转换为yuv格式图像
文章目录
- 参考文献
- jpeg转yuv
- 源码下载
JPG和PNG等图片的解码方式和视频解码是一样的,因为视频是由一幅一幅的图片组成的,只不过视频的帧是会前后参考的,而JPG等图片是单独的一帧而已。
0. 参考文献
ffmpeg解码JPG和PNG等图片
1. jpeg转yuv
int main(int argc, char* argv[])
{
int i;
char szFileName[128] = {
0 };
int decLen = 0;
int frame = 0;
AVCodecContext *pCodecCtx = NULL;
AVFrame *pFrame = NULL;
AVCodec *pCodec = NULL;
AVFormatContext *pFormatCtx = NULL;
/*if (argc != 3)
{
fprintf(stderr, "ERROR:need 3 argument!n");
exit(-1);
}*/
sprintf(szFileName, "%s", "H:/bmp2jpg/1.jpeg");
#ifdef ENABLE_DEMUX_SAVE
FILE* frvdemux = fopen("rvdemuxout.rm", "wb+");
if (NULL == frvdemux)
{
fprintf(stderr, "create rvdemuxout file failedn");
exit(1);
}
#endif
/* output yuv file name */
sprintf(ffrvout, "%s", "H:/bmp2jpg/1.yuv");
pfout = fopen(ffrvout, "wb+");
if (NULL == pfout)
{
printf("create output file failedn");
exit(1);
}
printf("==========> Begin test ffmpeg call ffmpeg rv decodern");
av_register_all();
/* Open input video file */
//printf("before avformat_open_input [%s]n", szFileName);
if (avformat_open_input(&pFormatCtx, szFileName, NULL, NULL) != 0)
{
fprintf(stderr, "Couldn't open input filen");
return -1;
}
//printf("after avformat_open_inputn");
/* Retrieve stream information */
if (avformat_find_stream_info(pFormatCtx, 0) < 0)
{
printf("av_find_stream_info ERRORn");
return -1;
}
//printf("after av_find_stream_info, n");
/* Find the first video stream */
int videoStream = -1;
printf("==========> pFormatCtx->nb_streams = %dn", pFormatCtx->nb_streams);
for (i = 0; i < pFormatCtx->nb_streams; i++) {
if (pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
videoStream = i;
printf("the first video stream index: videoStream = %dn", videoStream);
break;
}
}
if (videoStream == -1)
return -1; // Didn't find a video stream
/* Get a pointer to the codec context for the video stream */
pCodecCtx = pFormatCtx->streams[videoStream]->codec;
printf("pCodecCtx->codec_id = %dn", pCodecCtx->codec_id);
pCodec = avcodec_find_decoder(pCodecCtx->codec_id);
if (pCodec == NULL) {
fprintf(stderr, "can not find decoder!n");
return -1;
}
/* Open codec */
if (avcodec_open2(pCodecCtx, pCodec, NULL) < 0)
{
printf("cannot open software codecn");
return -1; // Could not open codec
}
printf("==========> Open software codec successn");
pFrame = av_frame_alloc();
if (pFrame == NULL)
{
fprintf(stderr, "avcodec_alloc_frame() ERRORn");
return -1;
}
/* flag whether we get a decoded yuv frame */
int frameFinished;
int packetno = 0;
AVPacket packet;
av_init_packet(&packet);
while (av_read_frame(pFormatCtx, &packet) >= 0) {
//printf("[main]avpkt->slice_count=%dn", packet.sliceNum);
/* Is this a packet from the video stream? */
if (packet.stream_index == videoStream) {
packetno++;
#ifdef ENABLE_PRINT_FRAME_BYTES
if (1) {
int i;
int size = packet.size < PRINT_BYTES ? packet.size : PRINT_BYTES;
unsigned char *data = packet.data;
printf("===>[%5d] [", packet.size);
for (i = 0; i < size; i++)
printf("%02x ", data[i]);
printf("]n");
}
#endif
#ifdef ENABLE_DEMUX_SAVE
fwrite(packet.data, 1, packet.size, frvdemux);
#endif
//printf("[the %d packet]packet.size = %dn", packetno++, packet.size);
while (packet.size > 0) {
decLen = avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, &packet);
//printf("[video_decode_example]after avcodec_decode_video2,decoded=%dn",decLen);
if (decLen < 0) {
fprintf(stderr, "[video_decode_example]Error while decoding frame %dn", frame);
//exit(1);
/* FIXME if decode one frame err, ignore this frame */
decLen = packet.size;
}
if (frameFinished) {
printf("got a yuv framen");
//printf(stderr, "[video_decode_example]saving frame %3dn", frame);
/* the picture is allocated by the decoder. no need to free it */
if (frame == 0) {
printf("[video_decode_example]picture->linesize[0]=%d, c->width=%d,c->height=%dn",
pFrame->linesize[0], pCodecCtx->width, pCodecCtx->height);
printf("===>YUV format = %dn", pFrame->format);
}
#ifdef ENABLE_YUV_SAVE
/* save yuv pic */
if (frame < FRAME_NUM) {
switch (pFrame->format) {
case 0: /* YUV420P */
case 12:
yuv420p_save(pFrame, pCodecCtx);
break;
case 2: /* RGB24 */
rgb24_save(pFrame, pCodecCtx);
break;
case 13: /* YUVJ422P */
yuv422p_save(pFrame, pCodecCtx);
break;
case 14: /* YUVJ444P */
yuv444p_save(pFrame, pCodecCtx);
break;
default:
fprintf(stderr, "unsupport YUV format for savingn");
break;
}
fprintf(stderr, "===>save pic successn");
}
#endif
/* frame index grow */
frame++;
}
//printf("===========> %dn", decLen);
/* left data in pkt , go on decoding */
packet.data += decLen;
packet.size -= decLen;
}
if (frame == FRAME_NUM) {
printf("==========> decoded [%d pkt frames] ---> save [%d YUV frames], enough to stop!n", packetno, FRAME_NUM);
break;
}
}
/* FIXME no need free in this file */
//printf("free packet that was allocated by av_read_framen");
// Free the packet that was allocated by av_read_frame
//av_free_packet(&packet);
}
printf("decoding job down! begin to freen");
/* Free the YUV frame */
av_free(pFrame);
/* Close the codec */
avcodec_close(pCodecCtx);
/* Close the video file */
avformat_free_context(pFormatCtx);
fclose(pfout);
printf("==========> END-OKn");
return 0;
}
2. 源码下载
jpeg转换为yuv格式图像源码
还没有评论,来说两句吧...