赞 | 12 |
VIP | 107 |
好人卡 | 6 |
积分 | 4 |
经验 | 31122 |
最后登录 | 2024-6-29 |
在线时间 | 1606 小时 |
Lv2.观梦者 傻♂逼
- 梦石
- 0
- 星屑
- 374
- 在线时间
- 1606 小时
- 注册时间
- 2007-3-13
- 帖子
- 6562
|
加入我们,或者,欢迎回来。
您需要 登录 才可以下载或查看,没有帐号?注册会员
x
本帖最后由 yangff 于 2011-9-11 17:57 编辑
不具备实用价值,仅供参考,使用前请阅读LGPL的协议!
播放成功,原来那些奇怪的灰度或者是绿色黄色都正常了!!!
测试结果640*480以下都是满帧
800*600开始掉了
1024*768只能勉强用了
1200*720蛋都碎了
10000*10000你开的了这么大 的bitmap??
可以完美嵌入Bitmap
暂时不支持音轨。帧率自行协调
- def marshal_dump;end
- def marshal_load(obj);end
- end
- class Bitmap
- # 传送到内存的API函数
- RtlMoveMemory_pi = Win32API.new('kernel32', 'RtlMoveMemory', 'pii', 'i')
- RtlMoveMemory_ip = Win32API.new('kernel32', 'RtlMoveMemory', 'ipi', 'i')
- def _dump(limit)
- data = "rgba" * width * height
- RtlMoveMemory_pi.call(data, address, data.length)
- [width, height, Zlib::Deflate.deflate(data)].pack("LLa*") # 压缩
- end
- def self._load(str)
- w, h, zdata = str.unpack("LLa*"); b = new(w, h)
- RtlMoveMemory_ip.call(b.address, Zlib::Inflate.inflate(zdata), w * h * 4); b
- end
- # [[[bitmap.object_id * 2 + 16] + 8] + 16] == 数据的开头
- #
- def address
- buffer, ad = "xxxx", object_id * 2 + 16
- RtlMoveMemory_pi.call(buffer, ad, 4); ad = buffer.unpack("L")[0] + 8
- RtlMoveMemory_pi.call(buffer, ad, 4); ad = buffer.unpack("L")[0] + 16
- RtlMoveMemory_pi.call(buffer, ad, 4);
- return buffer.unpack("L")[0]
- end
- end
- module RMPlayer
- REG=Win32API.new("rmplayer","RegMovie","ip","i")
- GNF=Win32API.new("rmplayer","NextFrame","ii","i")
- CLM=Win32API.new("rmplayer","CloseMovie","ii","i")
- def self.reg(a,s)
- @a=a
- @s=s
- @h=REG.call(@a,s)
- end
- def self.next
- GNF.call(@a,@h)
- end
- end
- class RMP < Bitmap
- def initialize(w,h,s)
- super(w,h)
- RMPlayer.reg(address,s)
- end
- def next
- RMPlayer.next
- end
- end
- @rmp=RMP.new(352,270,"haha.flv")
- @v=Viewport.new(0,0,640,480)
- @v.z=99
- @s=Sprite.new(@v)
- @s.z=99
- @s.bitmap=@rmp
- while true
- @rmp.next
- Graphics.update
- end
复制代码- #ifndef INT64_C
- #define INT64_C(c) (c ## LL)
- #define UINT64_C(c) (c ## ULL)
- #endif
- #include <Windows.h>
- #include "libavutil/avstring.h"
- #include "libavformat/avformat.h"
- //#include "libavformat/rtsp.h"
- #include "libavdevice/avdevice.h"
- #include "libswscale/swscale.h"
- #include "libavcodec/opt.h"
- #include <libavcodec/avcodec.h>
- AVFormatContext *pFormatCtx;
- int i, videoStream;
- AVCodecContext *pCodecCtx;
- AVCodec *pCodec;
- AVFrame *pFrame;
- AVFrame *pFrameRGB;
- int numBytes;
- uint8_t *buffer;
- int __declspec(dllexport) RegMovie(int pBitmap,char * src)
- {
- avcodec_init() ;
- av_register_all();
- pFormatCtx = avformat_alloc_context();
- if(av_open_input_file(&pFormatCtx,src, NULL, 0, NULL)!=0)return -1;// Couldn't open file
- if(av_find_stream_info(pFormatCtx)<0) return -2;// Couldn't find stream information
- //dump_format(pFormatCtx, 0, src, false);
- videoStream=-1;
- for(i=0; i<pFormatCtx->nb_streams; i++)
- //if(&pFormatCtx->streams->codec.codec_type==CODEC_TYPE_VIDEO)
- if ((pFormatCtx->streams[i]->codec->codec_type)==AVMEDIA_TYPE_VIDEO)
- {
- videoStream=i;
- break;
- }
- if(videoStream==-1)
- return -3; // Didn't find a video stream
- pCodecCtx=pFormatCtx->streams[videoStream]->codec;
- pCodec=avcodec_find_decoder(pCodecCtx->codec_id);
- if(pCodec==NULL)
- return -4; // Codec not found
- if(pCodec->capabilities & CODEC_CAP_TRUNCATED)
- pCodecCtx->flags|=CODEC_FLAG_TRUNCATED;
- if(avcodec_open(pCodecCtx, pCodec)<0)
- return -5; // Could not open codec
- pFrame=avcodec_alloc_frame();
- pFrameRGB=avcodec_alloc_frame();
- if(pFrameRGB==NULL)
- return -6;
- // Determine required buffer size and allocate buffer
- numBytes=avpicture_get_size(PIX_FMT_RGB24, pCodecCtx->width,
- pCodecCtx->height);
- buffer=malloc(numBytes);//new uint8_t[numBytes];
- // Assign appropriate parts of buffer to image planes in pFrameRGB
- avpicture_fill((AVPicture *)pFrameRGB, buffer, PIX_FMT_RGB24,
- pCodecCtx->width, pCodecCtx->height);
- return 0;
- }
- int GetNextFrame(AVFormatContext *pFormatCtx, AVCodecContext *pCodecCtx,
- int videoStream, AVFrame *pFrame)
- {
- static AVPacket packet;
- static int bytesRemaining=0;
- //static uint8_t *rawData;
- static int fFirstTime=1;
- int bytesDecoded;
- int frameFinished;
- // 我 们第一次调用时,将 packet.data 设置为NULL指明它不用释放了
- if(fFirstTime)
- {
- fFirstTime=0;
- packet.data=NULL;
- }
- // 解码直到成功解码完整的一帧
- while(1)
- {
- // 除非解码完毕,否则一直在当前包中工作
- while(bytesRemaining > 0)
- {
- // 解码下一块数 据
- bytesDecoded=avcodec_decode_video2(pCodecCtx, pFrame,
- &frameFinished, &packet);
- // 出错了?
- if(bytesDecoded < 0)
- {
- fprintf(stderr, "Error while decoding frame\n");
- return 0;
- }
- bytesRemaining-=bytesDecoded;
- // 我们完成当前帧了吗?接着我们返回
- if(frameFinished)
- return 1;
- }
- // 读取下一包,跳过所有不属于这个流的包
- do
- {
- // 释放旧的包
- if(packet.data!=NULL)
- av_free_packet(&packet);
- // 读取新的包
- if(av_read_packet(pFormatCtx, &packet)<0)
- goto loop_exit;
- } while(packet.stream_index!=videoStream);
- bytesRemaining=packet.size;
- }
- loop_exit:
- // 解码最后一帧的余下部分
- bytesDecoded=avcodec_decode_video2(pCodecCtx, pFrame,
- &frameFinished, &packet);
- // 释放最后一个包
- if(packet.data!=NULL)
- av_free_packet(&packet);
- return frameFinished!=0;
- }
- void frame(int iHeight,int iWidth,uint8_t *iYuvBuf,AVFrame *pFrame)
- {
- int i,j,k;
- for(i=0;i<iHeight;i++)
- memcpy(iYuvBuf+iWidth*i, pFrame->data[0]+pFrame->linesize[0]*i,iWidth);
- for(j=0;j<iHeight/2;j++)
- memcpy(iYuvBuf+iWidth*i+iWidth/2*j,pFrame->data[1]+pFrame->linesize[1]*j,iWidth/2);
- for(k=0;k<iHeight/2;k++)
- memcpy(iYuvBuf+iWidth*i*2+iWidth/2*k, pFrame->data[2]+pFrame->linesize[2]*k, iWidth/2);
- }
- int __declspec(dllexport) NextFrame(int Bitmap,int playerHandle)
- {
- int * pBitmap=(int *)Bitmap;
- if (GetNextFrame(pFormatCtx, pCodecCtx, videoStream, pFrame))
- {
- //struct SwsContext * img_convert_ctx;
- //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);
- uint8_t *data = malloc (3*pCodecCtx->width*pCodecCtx->height);
- uint8_t *src[3]= {data, data+pCodecCtx->width*pCodecCtx->height, data+pCodecCtx->width*pCodecCtx->height+pCodecCtx->width*pCodecCtx->height};
- //int stride[3]={pCodecCtx->width, pCodecCtx->width, pCodecCtx->width};
- //sws_scale(img_convert_ctx,(const uint8_t* const*)pFrame->data,pFrame->linesize,0,pCodecCtx->height,src,stride);
- int p=0;
- int r,g,b=0;
- double y,u,v;
- int off=pCodecCtx->width*pCodecCtx->height;
- int off1=pCodecCtx->width*pCodecCtx->height*1;
- frame(pCodecCtx->height,pCodecCtx->width,data,pFrame);
- //pBitmap[pCodecCtx->width*pCodecCtx->height-1]=0xffffaaff;
- for (int i=pCodecCtx->height-1;i>=0;i--){
- for (int j=0;j<pCodecCtx->width;j++)
- { //if (i*pCodecCtx->width+j<pCodecCtx->height*pCodecCtx->width)
- pBitmap[p]=0xff000000 ;
- y=(double)src[0][i*pCodecCtx->width+j];//pFrame->pp;//data[0][p+off];
- u=(double)src[1][(i/2*pCodecCtx->width+j)/2];//pFrame->pp;//data[0][p+off1];
- v=(double)src[2][(i/2*pCodecCtx->width+j)/2];//pFrame->pp//data[0][p+off1+off];
- r=(int)(1.164f*(y-16)+1.596f*(v-128));
- g=(int)(1.164f*(y-16)-0.813f*(v - 128) - 0.391f*(u - 128));
- b=(int)(1.164f*(y-16)+2.018f*(u - 128));
- if (r>255) r=255; if (r<0) r=0;
- if (g>255) g=255; if (g<0) g=0;
- if (b>255) b=255; if (b<0) b=0;
- pBitmap[p]|= b; //b
- pBitmap[p]|= g << 8; // g
- pBitmap[p]|= r << 16; // r
- // | data[((j+i*pCodecCtx->width+pCodecCtx->width*pCodecCtx->height) << 8)];// | data[((j+i*pCodecCtx->width+pCodecCtx->width*pCodecCtx->height*2) << 16)] | (0xff << 24);
- p++;
- }}
- free(data);
- return 1; }
-
- return -1;
- }
- int __declspec(dllexport) CloseMovie(int pBitmap,int playerHandle)
- {
- }
复制代码 |
|