设为首页收藏本站|繁體中文

Project1

 找回密码
 注册会员
搜索
查看: 2673|回复: 4
打印 上一主题 下一主题

[讨论] 试制FFMPEG视屏播放0.5alpha[召唤八云紫]无声版

[复制链接]

Lv2.观梦者

傻♂逼

梦石
0
星屑
374
在线时间
1606 小时
注册时间
2007-3-13
帖子
6562

烫烫烫开拓者

跳转到指定楼层
1
发表于 2011-9-10 23:24:43 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式

加入我们,或者,欢迎回来。

您需要 登录 才可以下载或查看,没有帐号?注册会员

x
本帖最后由 yangff 于 2011-9-11 17:57 编辑

不具备实用价值,仅供参考,使用前请阅读LGPL的协议!
播放成功,原来那些奇怪的灰度或者是绿色黄色都正常了!!!
测试结果640*480以下都是满帧
800*600开始掉了
1024*768只能勉强用了
1200*720蛋都碎了
10000*10000你开的了这么大 的bitmap??
可以完美嵌入Bitmap
暂时不支持音轨。帧率自行协调

  1. def marshal_dump;end
  2. def marshal_load(obj);end
  3. end
  4. class Bitmap
  5. # 传送到内存的API函数
  6. RtlMoveMemory_pi = Win32API.new('kernel32', 'RtlMoveMemory', 'pii', 'i')
  7. RtlMoveMemory_ip = Win32API.new('kernel32', 'RtlMoveMemory', 'ipi', 'i')
  8. def _dump(limit)
  9. data = "rgba" * width * height
  10. RtlMoveMemory_pi.call(data, address, data.length)
  11. [width, height, Zlib::Deflate.deflate(data)].pack("LLa*") # 压缩
  12. end
  13. def self._load(str)
  14. w, h, zdata = str.unpack("LLa*"); b = new(w, h)
  15. RtlMoveMemory_ip.call(b.address, Zlib::Inflate.inflate(zdata), w * h * 4); b
  16. end
  17. # [[[bitmap.object_id * 2 + 16] + 8] + 16] == 数据的开头
  18. #
  19. def address
  20. buffer, ad = "xxxx", object_id * 2 + 16
  21. RtlMoveMemory_pi.call(buffer, ad, 4); ad = buffer.unpack("L")[0] + 8
  22. RtlMoveMemory_pi.call(buffer, ad, 4); ad = buffer.unpack("L")[0] + 16
  23. RtlMoveMemory_pi.call(buffer, ad, 4);
  24. return buffer.unpack("L")[0]
  25. end
  26. end
  27. module RMPlayer
  28.   REG=Win32API.new("rmplayer","RegMovie","ip","i")
  29.   GNF=Win32API.new("rmplayer","NextFrame","ii","i")
  30.   CLM=Win32API.new("rmplayer","CloseMovie","ii","i")
  31.   def self.reg(a,s)
  32.     @a=a
  33.     @s=s
  34.     @h=REG.call(@a,s)
  35.   end
  36.   def self.next
  37.     GNF.call(@a,@h)
  38.   end
  39. end
  40. class RMP < Bitmap
  41.   def initialize(w,h,s)
  42.     super(w,h)
  43.     RMPlayer.reg(address,s)
  44.   end
  45.   def next
  46.     RMPlayer.next
  47.   end
  48. end
  49. @rmp=RMP.new(352,270,"haha.flv")
  50. @v=Viewport.new(0,0,640,480)
  51. @v.z=99
  52. @s=Sprite.new(@v)
  53. @s.z=99
  54. @s.bitmap=@rmp
  55. while true
  56.   @rmp.next
  57.   Graphics.update
  58. end
复制代码
  1. #ifndef INT64_C
  2. #define INT64_C(c) (c ## LL)
  3. #define UINT64_C(c) (c ## ULL)
  4. #endif

  5.         #include <Windows.h>
  6.         #include "libavutil/avstring.h"
  7.         #include "libavformat/avformat.h"
  8.         //#include "libavformat/rtsp.h"
  9.         #include "libavdevice/avdevice.h"
  10.         #include "libswscale/swscale.h"
  11.         #include "libavcodec/opt.h"
  12.         #include <libavcodec/avcodec.h>

  13. AVFormatContext *pFormatCtx;
  14. int          i, videoStream;
  15. AVCodecContext   *pCodecCtx;
  16. AVCodec       *pCodec;
  17. AVFrame       *pFrame;
  18. AVFrame       *pFrameRGB;
  19. int          numBytes;
  20. uint8_t       *buffer;


  21. int __declspec(dllexport) RegMovie(int pBitmap,char * src)
  22. {
  23.         avcodec_init() ;
  24.         av_register_all();
  25.         pFormatCtx = avformat_alloc_context();
  26.         if(av_open_input_file(&pFormatCtx,src, NULL, 0, NULL)!=0)return -1;// Couldn't open file
  27.         if(av_find_stream_info(pFormatCtx)<0) return -2;// Couldn't find stream information
  28.         //dump_format(pFormatCtx, 0, src, false);
  29.         videoStream=-1;
  30.         for(i=0; i<pFormatCtx->nb_streams; i++)
  31.        //if(&pFormatCtx->streams->codec.codec_type==CODEC_TYPE_VIDEO)
  32.            if ((pFormatCtx->streams[i]->codec->codec_type)==AVMEDIA_TYPE_VIDEO)
  33.        {
  34.          videoStream=i;
  35.          break;
  36.        }
  37.         if(videoStream==-1)
  38.                    return -3; // Didn't find a video stream
  39.         pCodecCtx=pFormatCtx->streams[videoStream]->codec;
  40.         pCodec=avcodec_find_decoder(pCodecCtx->codec_id);
  41.         if(pCodec==NULL)
  42.        return -4; // Codec not found
  43.         if(pCodec->capabilities & CODEC_CAP_TRUNCATED)
  44.        pCodecCtx->flags|=CODEC_FLAG_TRUNCATED;
  45.         if(avcodec_open(pCodecCtx, pCodec)<0)
  46.        return -5; // Could not open codec
  47.         pFrame=avcodec_alloc_frame();
  48.         pFrameRGB=avcodec_alloc_frame();
  49.         if(pFrameRGB==NULL)
  50.        return -6;
  51.                 // Determine required buffer size and allocate buffer
  52.         numBytes=avpicture_get_size(PIX_FMT_RGB24, pCodecCtx->width,
  53.                    pCodecCtx->height);
  54.         buffer=malloc(numBytes);//new uint8_t[numBytes];

  55.         // Assign appropriate parts of buffer to image planes in pFrameRGB
  56.         avpicture_fill((AVPicture *)pFrameRGB, buffer, PIX_FMT_RGB24,
  57.                    pCodecCtx->width, pCodecCtx->height);
  58.         return 0;
  59. }
  60. int GetNextFrame(AVFormatContext *pFormatCtx, AVCodecContext *pCodecCtx,
  61.    int videoStream, AVFrame *pFrame)
  62. {
  63.    static AVPacket packet;
  64.    static int      bytesRemaining=0;
  65.    //static uint8_t  *rawData;
  66.    static int fFirstTime=1;
  67.    int bytesDecoded;
  68.    int frameFinished;

  69. //  我 们第一次调用时,将 packet.data 设置为NULL指明它不用释放了
  70.    if(fFirstTime)
  71.    {
  72.        fFirstTime=0;
  73.        packet.data=NULL;
  74.    }

  75. // 解码直到成功解码完整的一帧
  76.    while(1)
  77.    {
  78.         //  除非解码完毕,否则一直在当前包中工作
  79.        while(bytesRemaining > 0)
  80.        {
  81.        //  解码下一块数 据
  82.            bytesDecoded=avcodec_decode_video2(pCodecCtx, pFrame,
  83.                &frameFinished, &packet);

  84.                // 出错了?
  85.            if(bytesDecoded < 0)
  86.            {
  87.                fprintf(stderr, "Error while decoding frame\n");
  88.                return 0;
  89.            }

  90.            bytesRemaining-=bytesDecoded;

  91.                // 我们完成当前帧了吗?接着我们返回
  92.            if(frameFinished)
  93.                return 1;
  94.        }

  95.        // 读取下一包,跳过所有不属于这个流的包
  96.        do
  97.        {
  98.            // 释放旧的包
  99.            if(packet.data!=NULL)
  100.                av_free_packet(&packet);

  101.            // 读取新的包
  102.            if(av_read_packet(pFormatCtx, &packet)<0)
  103.                goto loop_exit;
  104.        } while(packet.stream_index!=videoStream);

  105.        bytesRemaining=packet.size;
  106.    }

  107. loop_exit:

  108.        // 解码最后一帧的余下部分
  109.    bytesDecoded=avcodec_decode_video2(pCodecCtx, pFrame,
  110.                &frameFinished, &packet);

  111.        // 释放最后一个包
  112.    if(packet.data!=NULL)
  113.        av_free_packet(&packet);

  114.    return frameFinished!=0;
  115. }
  116. void frame(int iHeight,int iWidth,uint8_t *iYuvBuf,AVFrame *pFrame)
  117. {
  118.   int i,j,k;
  119.   for(i=0;i<iHeight;i++)
  120.       memcpy(iYuvBuf+iWidth*i, pFrame->data[0]+pFrame->linesize[0]*i,iWidth);
  121.   for(j=0;j<iHeight/2;j++)
  122.       memcpy(iYuvBuf+iWidth*i+iWidth/2*j,pFrame->data[1]+pFrame->linesize[1]*j,iWidth/2);
  123.   for(k=0;k<iHeight/2;k++)
  124.       memcpy(iYuvBuf+iWidth*i*2+iWidth/2*k, pFrame->data[2]+pFrame->linesize[2]*k, iWidth/2);
  125. }
  126. int __declspec(dllexport) NextFrame(int Bitmap,int playerHandle)
  127. {
  128.         int * pBitmap=(int *)Bitmap;
  129.         if (GetNextFrame(pFormatCtx, pCodecCtx, videoStream, pFrame))
  130.         {
  131.                 //struct SwsContext * img_convert_ctx;
  132.                 //img_convert_ctx=sws_getContext( pCodecCtx->width/12, pCodecCtx->height/12,PIX_FMT_RGB32,pCodecCtx->width,pCodecCtx->height,PIX_FMT_YUV420P,2,NULL,NULL,NULL);
  133.                 uint8_t *data = malloc (3*pCodecCtx->width*pCodecCtx->height);
  134.                 uint8_t *src[3]= {data, data+pCodecCtx->width*pCodecCtx->height, data+pCodecCtx->width*pCodecCtx->height+pCodecCtx->width*pCodecCtx->height};
  135.                 //int stride[3]={pCodecCtx->width, pCodecCtx->width, pCodecCtx->width};
  136.                 //sws_scale(img_convert_ctx,(const uint8_t*  const*)pFrame->data,pFrame->linesize,0,pCodecCtx->height,src,stride);
  137.                 int p=0;
  138.                 int r,g,b=0;
  139.                 double y,u,v;
  140.                 int off=pCodecCtx->width*pCodecCtx->height;
  141.                 int off1=pCodecCtx->width*pCodecCtx->height*1;
  142.                 frame(pCodecCtx->height,pCodecCtx->width,data,pFrame);
  143.                 //pBitmap[pCodecCtx->width*pCodecCtx->height-1]=0xffffaaff;
  144.             for (int i=pCodecCtx->height-1;i>=0;i--){
  145.                 for (int j=0;j<pCodecCtx->width;j++)
  146.                 {        //if (i*pCodecCtx->width+j<pCodecCtx->height*pCodecCtx->width)
  147.                         pBitmap[p]=0xff000000 ;
  148.                         y=(double)src[0][i*pCodecCtx->width+j];//pFrame->pp;//data[0][p+off];
  149.                     u=(double)src[1][(i/2*pCodecCtx->width+j)/2];//pFrame->pp;//data[0][p+off1];
  150.                         v=(double)src[2][(i/2*pCodecCtx->width+j)/2];//pFrame->pp//data[0][p+off1+off];
  151.                         r=(int)(1.164f*(y-16)+1.596f*(v-128));
  152.                         g=(int)(1.164f*(y-16)-0.813f*(v - 128) - 0.391f*(u - 128));
  153.                         b=(int)(1.164f*(y-16)+2.018f*(u - 128));
  154.                         if (r>255) r=255; if (r<0) r=0;
  155.                         if (g>255) g=255; if (g<0) g=0;
  156.                         if (b>255) b=255; if (b<0) b=0;
  157.                         pBitmap[p]|= b; //b
  158.                         pBitmap[p]|= g << 8; // g
  159.                         pBitmap[p]|= r << 16; // r
  160.                         // | data[((j+i*pCodecCtx->width+pCodecCtx->width*pCodecCtx->height) << 8)];// | data[((j+i*pCodecCtx->width+pCodecCtx->width*pCodecCtx->height*2) << 16)] | (0xff << 24);
  161.                         p++;
  162.                 }}
  163.                 free(data);
  164.                 return 1;        }
  165.                
  166.         return -1;
  167. }
  168. int __declspec(dllexport) CloseMovie(int pBitmap,int playerHandle)
  169. {

  170. }
复制代码

点评

忘记释放内存了囧  发表于 2011-9-10 23:37
LGPL的柱子  发表于 2011-9-10 23:29
PS这东西就丢在这里好了……有一些API我不确定版本反正先这样吧。我用的是最新的版本但是问题一坨……一些代码是搬旧资料的,还有用这些代码小心  发表于 2011-9-10 23:29
哎呀,蛋疼什么的最有爱了

Lv1.梦旅人

反伸手党斗士

梦石
0
星屑
91
在线时间
1128 小时
注册时间
2009-9-10
帖子
2513

贵宾

2
发表于 2011-9-11 18:21:04 | 只看该作者
- -我来增加点热度就好了
为什么窗口里视频……恩……好像有不和谐的玩意0 0?

点评

这是很优秀的让智商增加的办法,你去百度一下,“哈哈哈大笑歌”看完之后你无论是智商还是身体就都和里面同步了,同步率1000%+  发表于 2011-9-11 18:25
回复 支持 反对

使用道具 举报

Lv4.逐梦者

梦石
0
星屑
6855
在线时间
1666 小时
注册时间
2008-10-29
帖子
6710

贵宾

3
发表于 2011-9-12 00:55:53 | 只看该作者
这类代码看者头痛...
空了弄来试试...











你知道得太多了

回复 支持 反对

使用道具 举报

Lv2.观梦者

傻♂逼

梦石
0
星屑
374
在线时间
1606 小时
注册时间
2007-3-13
帖子
6562

烫烫烫开拓者

4
 楼主| 发表于 2011-9-12 01:22:37 | 只看该作者
后知后觉 发表于 2011-9-12 00:55
这类代码看者头痛...
空了弄来试试...

DLL编译+演示下载(GUN C)
http://ftp.66rpg.com/yangff/RMPlayer.part1.rar
http://ftp.66rpg.com/yangff/RMPlayer.part2.rar

半成品,无音轨,无封装……
哎呀,蛋疼什么的最有爱了
回复 支持 反对

使用道具 举报

Lv1.梦旅人

梦石
0
星屑
50
在线时间
135 小时
注册时间
2011-8-1
帖子
188
5
发表于 2011-9-12 08:41:43 | 只看该作者
那个···小女孩说的啥???好不河蟹···

세상은 너무 미쳐있다
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册会员

本版积分规则

拿上你的纸笔,建造一个属于你的梦想世界,加入吧。
 注册会员
找回密码

站长信箱:[email protected]|手机版|小黑屋|无图版|Project1游戏制作

GMT+8, 2024-11-25 10:00

Powered by Discuz! X3.1

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表