FFmpeg开发实战(六):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格式图像源码

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

i胡说

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值