FFmpeg开发实战(六):jpeg转换为yuv格式图像

Myth丶恋晨 2022-10-17 13:43 926阅读 0赞

文章目录

    1. 参考文献
    1. jpeg转yuv
    1. 源码下载

JPG和PNG等图片的解码方式和视频解码是一样的,因为视频是由一幅一幅的图片组成的,只不过视频的帧是会前后参考的,而JPG等图片是单独的一帧而已。

0. 参考文献

ffmpeg解码JPG和PNG等图片

1. jpeg转yuv

  1. int main(int argc, char* argv[])
  2. {
  3. int i;
  4. char szFileName[128] = {
  5. 0 };
  6. int decLen = 0;
  7. int frame = 0;
  8. AVCodecContext *pCodecCtx = NULL;
  9. AVFrame *pFrame = NULL;
  10. AVCodec *pCodec = NULL;
  11. AVFormatContext *pFormatCtx = NULL;
  12. /*if (argc != 3)
  13. {
  14. fprintf(stderr, "ERROR:need 3 argument!n");
  15. exit(-1);
  16. }*/
  17. sprintf(szFileName, "%s", "H:/bmp2jpg/1.jpeg");
  18. #ifdef ENABLE_DEMUX_SAVE
  19. FILE* frvdemux = fopen("rvdemuxout.rm", "wb+");
  20. if (NULL == frvdemux)
  21. {
  22. fprintf(stderr, "create rvdemuxout file failedn");
  23. exit(1);
  24. }
  25. #endif
  26. /* output yuv file name */
  27. sprintf(ffrvout, "%s", "H:/bmp2jpg/1.yuv");
  28. pfout = fopen(ffrvout, "wb+");
  29. if (NULL == pfout)
  30. {
  31. printf("create output file failedn");
  32. exit(1);
  33. }
  34. printf("==========> Begin test ffmpeg call ffmpeg rv decodern");
  35. av_register_all();
  36. /* Open input video file */
  37. //printf("before avformat_open_input [%s]n", szFileName);
  38. if (avformat_open_input(&pFormatCtx, szFileName, NULL, NULL) != 0)
  39. {
  40. fprintf(stderr, "Couldn't open input filen");
  41. return -1;
  42. }
  43. //printf("after avformat_open_inputn");
  44. /* Retrieve stream information */
  45. if (avformat_find_stream_info(pFormatCtx, 0) < 0)
  46. {
  47. printf("av_find_stream_info ERRORn");
  48. return -1;
  49. }
  50. //printf("after av_find_stream_info, n");
  51. /* Find the first video stream */
  52. int videoStream = -1;
  53. printf("==========> pFormatCtx->nb_streams = %dn", pFormatCtx->nb_streams);
  54. for (i = 0; i < pFormatCtx->nb_streams; i++) {
  55. if (pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
  56. videoStream = i;
  57. printf("the first video stream index: videoStream = %dn", videoStream);
  58. break;
  59. }
  60. }
  61. if (videoStream == -1)
  62. return -1; // Didn't find a video stream
  63. /* Get a pointer to the codec context for the video stream */
  64. pCodecCtx = pFormatCtx->streams[videoStream]->codec;
  65. printf("pCodecCtx->codec_id = %dn", pCodecCtx->codec_id);
  66. pCodec = avcodec_find_decoder(pCodecCtx->codec_id);
  67. if (pCodec == NULL) {
  68. fprintf(stderr, "can not find decoder!n");
  69. return -1;
  70. }
  71. /* Open codec */
  72. if (avcodec_open2(pCodecCtx, pCodec, NULL) < 0)
  73. {
  74. printf("cannot open software codecn");
  75. return -1; // Could not open codec
  76. }
  77. printf("==========> Open software codec successn");
  78. pFrame = av_frame_alloc();
  79. if (pFrame == NULL)
  80. {
  81. fprintf(stderr, "avcodec_alloc_frame() ERRORn");
  82. return -1;
  83. }
  84. /* flag whether we get a decoded yuv frame */
  85. int frameFinished;
  86. int packetno = 0;
  87. AVPacket packet;
  88. av_init_packet(&packet);
  89. while (av_read_frame(pFormatCtx, &packet) >= 0) {
  90. //printf("[main]avpkt->slice_count=%dn", packet.sliceNum);
  91. /* Is this a packet from the video stream? */
  92. if (packet.stream_index == videoStream) {
  93. packetno++;
  94. #ifdef ENABLE_PRINT_FRAME_BYTES
  95. if (1) {
  96. int i;
  97. int size = packet.size < PRINT_BYTES ? packet.size : PRINT_BYTES;
  98. unsigned char *data = packet.data;
  99. printf("===>[%5d] [", packet.size);
  100. for (i = 0; i < size; i++)
  101. printf("%02x ", data[i]);
  102. printf("]n");
  103. }
  104. #endif
  105. #ifdef ENABLE_DEMUX_SAVE
  106. fwrite(packet.data, 1, packet.size, frvdemux);
  107. #endif
  108. //printf("[the %d packet]packet.size = %dn", packetno++, packet.size);
  109. while (packet.size > 0) {
  110. decLen = avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, &packet);
  111. //printf("[video_decode_example]after avcodec_decode_video2,decoded=%dn",decLen);
  112. if (decLen < 0) {
  113. fprintf(stderr, "[video_decode_example]Error while decoding frame %dn", frame);
  114. //exit(1);
  115. /* FIXME if decode one frame err, ignore this frame */
  116. decLen = packet.size;
  117. }
  118. if (frameFinished) {
  119. printf("got a yuv framen");
  120. //printf(stderr, "[video_decode_example]saving frame %3dn", frame);
  121. /* the picture is allocated by the decoder. no need to free it */
  122. if (frame == 0) {
  123. printf("[video_decode_example]picture->linesize[0]=%d, c->width=%d,c->height=%dn",
  124. pFrame->linesize[0], pCodecCtx->width, pCodecCtx->height);
  125. printf("===>YUV format = %dn", pFrame->format);
  126. }
  127. #ifdef ENABLE_YUV_SAVE
  128. /* save yuv pic */
  129. if (frame < FRAME_NUM) {
  130. switch (pFrame->format) {
  131. case 0: /* YUV420P */
  132. case 12:
  133. yuv420p_save(pFrame, pCodecCtx);
  134. break;
  135. case 2: /* RGB24 */
  136. rgb24_save(pFrame, pCodecCtx);
  137. break;
  138. case 13: /* YUVJ422P */
  139. yuv422p_save(pFrame, pCodecCtx);
  140. break;
  141. case 14: /* YUVJ444P */
  142. yuv444p_save(pFrame, pCodecCtx);
  143. break;
  144. default:
  145. fprintf(stderr, "unsupport YUV format for savingn");
  146. break;
  147. }
  148. fprintf(stderr, "===>save pic successn");
  149. }
  150. #endif
  151. /* frame index grow */
  152. frame++;
  153. }
  154. //printf("===========> %dn", decLen);
  155. /* left data in pkt , go on decoding */
  156. packet.data += decLen;
  157. packet.size -= decLen;
  158. }
  159. if (frame == FRAME_NUM) {
  160. printf("==========> decoded [%d pkt frames] ---> save [%d YUV frames], enough to stop!n", packetno, FRAME_NUM);
  161. break;
  162. }
  163. }
  164. /* FIXME no need free in this file */
  165. //printf("free packet that was allocated by av_read_framen");
  166. // Free the packet that was allocated by av_read_frame
  167. //av_free_packet(&packet);
  168. }
  169. printf("decoding job down! begin to freen");
  170. /* Free the YUV frame */
  171. av_free(pFrame);
  172. /* Close the codec */
  173. avcodec_close(pCodecCtx);
  174. /* Close the video file */
  175. avformat_free_context(pFormatCtx);
  176. fclose(pfout);
  177. printf("==========> END-OKn");
  178. return 0;
  179. }

2. 源码下载

jpeg转换为yuv格式图像源码

发表评论

表情:
评论列表 (有 0 条评论,926人围观)

还没有评论,来说两句吧...

相关阅读