czanyou

如何在 iPhone 下面用 ffmpeg 解码 H.264 流 (2)


  下面是如果解码以及将  YV12 数据转换成 
32 位 ARGB 数据的代码
  1
 
  2 #include "avcodec.h"
  3 #include "h264decoder.h";
  4 
  5 typedef unsigned char byte_t;
  6 typedef unsigned int uint_t;
  7 
  8 struct AVCodec *fCodec = NULL;              // Codec
  9 struct AVCodecContext *fCodecContext = NULL;          // Codec Context
 10 struct AVFrame *fVideoFrame = NULL;          // Frame    
 11 
 12 int fDisplayWidth    = 0;
 13 int fDisplayHeight    = 0;
 14 int *fColorTable = NULL;
 15 
 16 int avcodec_decode_video(AVCodecContext *avctx, AVFrame *picture,
 17                          int *got_picture_ptr,
 18                          const uint8_t *buf, int buf_size)
 19 {
 20     AVPacket avpkt;
 21     av_init_packet(&avpkt);
 22     avpkt.data = buf;
 23     avpkt.size = buf_size;
 24     // HACK for CorePNG to decode as normal PNG by default
 25     avpkt.flags = AV_PKT_FLAG_KEY;
 26     return avcodec_decode_video2(avctx, picture, got_picture_ptr, &avpkt);
 27 }
 28 
 29 #define RGB_V(v) ((v < 0) ? 0 : ((v > 255) ? 255 : v))
 30         
 31 void DeleteYUVTable()
 32 {
 33     av_free(fColorTable);
 34 }
 35 
 36 void CreateYUVTable()
 37 {
 38     int i;
 39     int u, v;
 40     int *u_b_tab = NULL;
 41     int *u_g_tab = NULL;
 42     int *v_g_tab = NULL;
 43     int *v_r_tab = NULL;
 44 
 45     fColorTable = (int *)av_malloc(4 * 256 * sizeof(int));
 46     u_b_tab = &fColorTable[0 * 256];
 47     u_g_tab = &fColorTable[1 * 256];
 48     v_g_tab = &fColorTable[2 * 256];
 49     v_r_tab = &fColorTable[3 * 256];
 50 
 51     for (i = 0; i < 256; i++) {
 52         u = v = (i - 128);
 53         u_b_tab[i] = (int) ( 1.772   * u);
 54         u_g_tab[i] = (int) ( 0.34414 * u);
 55         v_g_tab[i] = (int) ( 0.71414 * v); 
 56         v_r_tab[i] = (int) ( 1.402   * v);
 57     }
 58 }
 59 
 60 /** YV12 To RGB888 */
 61 void DisplayYUV_32(uint_t *displayBuffer, int videoWidth, int videoHeight, int outPitch)
 62 {
 63     int *u_b_tab = &fColorTable[0 * 256];
 64     int *u_g_tab = &fColorTable[1 * 256];
 65     int *v_g_tab = &fColorTable[2 * 256];
 66     int *v_r_tab = &fColorTable[3 * 256];
 67     
 68     // YV12: [Y:MxN] [U:M/2xN/2] [V:M/2xN/2]
 69     byte_t* y = fVideoFrame->data[0];
 70     byte_t* u = fVideoFrame->data[1];
 71     byte_t* v = fVideoFrame->data[2];
 72     
 73     int src_ystride  = fVideoFrame->linesize[0];
 74     int src_uvstride = fVideoFrame->linesize[1];
 75     
 76     int i, line;
 77     int r, g, b;
 78     
 79     int ub, ug, vg, vr;
 80 
 81     int width  = videoWidth;
 82     int height = videoHeight;
 83     
 84     // 剪切边框
 85     if (width > fDisplayWidth) {
 86         width = fDisplayWidth;        
 87         y += (videoWidth - fDisplayWidth) / 2;
 88         u += (videoWidth - fDisplayWidth) / 4;
 89         v += (videoWidth - fDisplayWidth) / 4;
 90     }
 91     
 92     if (height > fDisplayHeight) {
 93         height = fDisplayHeight;
 94     }
 95     
 96     for (line = 0; line < height; line++) {
 97         byte_t* yoff = y + line * src_ystride;
 98         byte_t* uoff = u + (line / 2* src_uvstride;
 99         byte_t* voff = v + (line / 2* src_uvstride;
100         //uint_t* buffer = displayBuffer + (height - line - 1) * outPitch;
101         uint_t* buffer = displayBuffer + line * outPitch;
102         
103         for (i = 0; i < width; i++) {
104             ub = u_b_tab[*uoff];
105             ug = u_g_tab[*uoff];
106             vg = v_g_tab[*voff];
107             vr = v_r_tab[*voff];
108             
109             b = RGB_V(*yoff + ub);
110             g = RGB_V(*yoff - ug - vg);
111             r = RGB_V(*yoff + vr);
112             
113             *buffer = 0xff000000 | b << 16 | g << 8 | r;
114             
115             buffer++;
116             yoff ++;
117             
118             if ((i % 2== 1) {
119                 uoff++;
120                 voff++;
121             }
122         }
123     }
124 }
125 
126 int avc_decode_init(int width, int height)
127 {
128     if (fCodecContext != NULL) {
129         return 0;
130     }
131     avcodec_init();      
132     avcodec_register_all();
133     fCodec = avcodec_find_decoder(CODEC_ID_H264);
134     
135     fDisplayWidth  = width;
136     fDisplayHeight = height;
137 
138     CreateYUVTable();    
139     
140     fCodecContext = avcodec_alloc_context(); 
141     avcodec_open(fCodecContext, fCodec); 
142     fVideoFrame  = avcodec_alloc_frame();
143         
144     return 1;
145 }
146 
147 int avc_decode_release()
148 {
149     if (fCodecContext) {
150         avcodec_close(fCodecContext);
151         free(fCodecContext->priv_data);
152         free(fCodecContext);
153         fCodecContext = NULL;
154     }
155 
156     if (fVideoFrame) {
157         free(fVideoFrame);
158         fVideoFrame = NULL;
159     }
160 
161     DeleteYUVTable();
162     return 1;
163 }
164 
165 int avc_decode(char* buf, int nalLen, char* out)
166 {
167     byte_t* data = (byte_t*)buf;
168     int frameSize = 0;
169     
170     int ret = avcodec_decode_video(fCodecContext, fVideoFrame, &frameSize, data, nalLen); 
171     if (ret <= 0) {
172         return ret;
173     }
174     
175     int width  = fCodecContext->width;
176     int height = fCodecContext->height;
177     DisplayYUV_32((uint32_t*)out, width, height, fDisplayWidth);
178     return ret;    
179 }
180 

posted on 2011-09-09 10:31 暗黑长老 阅读(3073) 评论(2)  编辑 收藏 引用

Feedback

# re: 如何在 iPhone 下面用 ffmpeg 解码 H.264 流 (2) 2011-09-13 22:00 wanghx74285@163.com

楼主你好,看到你的文章很高兴,想问一下你 #include "h264decoder.h"是个什么文件呢,自己写的吗?
我的邮箱:wanghx74285@163.com 希望能得到您的回答,谢谢
  回复  更多评论   

# re: 如何在 iPhone 下面用 ffmpeg 解码 H.264 流 (2) 2011-09-20 10:54 马全红

请问博主,1024 * 768能解到多少帧?  回复  更多评论   



只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理