|
@@ -1,10 +1,11 @@
|
|
|
-
|
|
|
-/**
|
|
|
+/**
|
|
|
* 叶海辉
|
|
|
* QQ群121376426
|
|
|
* http://blog.yundiantech.com/
|
|
|
*/
|
|
|
|
|
|
+#include "videoplayer.h"
|
|
|
+
|
|
|
extern "C"
|
|
|
{
|
|
|
#include "libavcodec/avcodec.h"
|
|
@@ -15,40 +16,26 @@ extern "C"
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
|
-///现在我们需要做的是让SaveFrame函数能把RGB信息定稿到一个PPM格式的文件中。
|
|
|
-///我们将生成一个简单的PPM格式文件,请相信,它是可以工作的。
|
|
|
-void SaveFrame(AVFrame *pFrame, int width, int height,int index)
|
|
|
+VideoPlayer::VideoPlayer()
|
|
|
{
|
|
|
|
|
|
- FILE *pFile;
|
|
|
- char szFilename[32];
|
|
|
- int y;
|
|
|
-
|
|
|
- // Open file
|
|
|
- sprintf(szFilename, "frame%d.ppm", index);
|
|
|
- pFile=fopen(szFilename, "wb");
|
|
|
-
|
|
|
- if(pFile==NULL)
|
|
|
- return;
|
|
|
+}
|
|
|
|
|
|
- // Write header
|
|
|
- fprintf(pFile, "P6\n%d %d\n255\n", width, height);
|
|
|
+VideoPlayer::~VideoPlayer()
|
|
|
+{
|
|
|
|
|
|
- // Write pixel data
|
|
|
- for(y=0; y<height; y++)
|
|
|
- {
|
|
|
- fwrite(pFrame->data[0]+y*pFrame->linesize[0], 1, width*3, pFile);
|
|
|
- }
|
|
|
+}
|
|
|
|
|
|
- // Close file
|
|
|
- fclose(pFile);
|
|
|
+void VideoPlayer::startPlay()
|
|
|
+{
|
|
|
+ ///调用 QThread 的start函数 将会自动执行下面的run函数 run函数是一个新的线程
|
|
|
+ this->start();
|
|
|
|
|
|
}
|
|
|
|
|
|
-
|
|
|
-int main(int argc, char *argv[])
|
|
|
+void VideoPlayer::run()
|
|
|
{
|
|
|
- char *file_path = "E:\\in.mp4";
|
|
|
+ char *file_path = mFileName.toUtf8().data();
|
|
|
|
|
|
AVFormatContext *pFormatCtx;
|
|
|
AVCodecContext *pCodecCtx;
|
|
@@ -69,12 +56,12 @@ int main(int argc, char *argv[])
|
|
|
|
|
|
if (avformat_open_input(&pFormatCtx, file_path, NULL, NULL) != 0) {
|
|
|
printf("can't open the file. \n");
|
|
|
- return -1;
|
|
|
+ return;
|
|
|
}
|
|
|
|
|
|
if (avformat_find_stream_info(pFormatCtx, NULL) < 0) {
|
|
|
printf("Could't find stream infomation.\n");
|
|
|
- return -1;
|
|
|
+ return;
|
|
|
}
|
|
|
|
|
|
videoStream = -1;
|
|
@@ -91,7 +78,7 @@ int main(int argc, char *argv[])
|
|
|
///如果videoStream为-1 说明没有找到视频流
|
|
|
if (videoStream == -1) {
|
|
|
printf("Didn't find a video stream.\n");
|
|
|
- return -1;
|
|
|
+ return;
|
|
|
}
|
|
|
|
|
|
///查找解码器
|
|
@@ -100,26 +87,27 @@ int main(int argc, char *argv[])
|
|
|
|
|
|
if (pCodec == NULL) {
|
|
|
printf("Codec not found.\n");
|
|
|
- return -1;
|
|
|
+ return;
|
|
|
}
|
|
|
|
|
|
///打开解码器
|
|
|
if (avcodec_open2(pCodecCtx, pCodec, NULL) < 0) {
|
|
|
printf("Could not open codec.\n");
|
|
|
- return -1;
|
|
|
+ return;
|
|
|
}
|
|
|
|
|
|
pFrame = av_frame_alloc();
|
|
|
pFrameRGB = av_frame_alloc();
|
|
|
|
|
|
+ ///这里我们改成了 将解码后的YUV数据转换成RGB32
|
|
|
img_convert_ctx = sws_getContext(pCodecCtx->width, pCodecCtx->height,
|
|
|
pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height,
|
|
|
- PIX_FMT_RGB24, SWS_BICUBIC, NULL, NULL, NULL);
|
|
|
+ PIX_FMT_RGB32, SWS_BICUBIC, NULL, NULL, NULL);
|
|
|
|
|
|
- numBytes = avpicture_get_size(PIX_FMT_RGB24, pCodecCtx->width,pCodecCtx->height);
|
|
|
+ numBytes = avpicture_get_size(PIX_FMT_RGB32, pCodecCtx->width,pCodecCtx->height);
|
|
|
|
|
|
out_buffer = (uint8_t *) av_malloc(numBytes * sizeof(uint8_t));
|
|
|
- avpicture_fill((AVPicture *) pFrameRGB, out_buffer, PIX_FMT_RGB24,
|
|
|
+ avpicture_fill((AVPicture *) pFrameRGB, out_buffer, PIX_FMT_RGB32,
|
|
|
pCodecCtx->width, pCodecCtx->height);
|
|
|
|
|
|
int y_size = pCodecCtx->width * pCodecCtx->height;
|
|
@@ -129,8 +117,6 @@ int main(int argc, char *argv[])
|
|
|
|
|
|
av_dump_format(pFormatCtx, 0, file_path, 0); //输出视频信息
|
|
|
|
|
|
- int index = 0;
|
|
|
-
|
|
|
while (1)
|
|
|
{
|
|
|
if (av_read_frame(pFormatCtx, packet) < 0)
|
|
@@ -143,7 +129,7 @@ int main(int argc, char *argv[])
|
|
|
|
|
|
if (ret < 0) {
|
|
|
printf("decode error.\n");
|
|
|
- return -1;
|
|
|
+ return;
|
|
|
}
|
|
|
|
|
|
if (got_picture) {
|
|
@@ -152,17 +138,18 @@ int main(int argc, char *argv[])
|
|
|
pFrame->linesize, 0, pCodecCtx->height, pFrameRGB->data,
|
|
|
pFrameRGB->linesize);
|
|
|
|
|
|
- SaveFrame(pFrameRGB, pCodecCtx->width,pCodecCtx->height,index++); //保存图片
|
|
|
- if (index > 50) return 0; //这里我们就保存50张图片
|
|
|
+ //把这个RGB数据 用QImage加载
|
|
|
+ QImage tmpImg((uchar *)out_buffer,pCodecCtx->width,pCodecCtx->height,QImage::Format_RGB32);
|
|
|
+ QImage image = tmpImg.copy(); //把图像复制一份 传递给界面显示
|
|
|
+ emit sig_GetOneFrame(image); //发送信号
|
|
|
}
|
|
|
}
|
|
|
av_free_packet(packet);
|
|
|
+
|
|
|
+ msleep(5); //停一停 不然放的太快了
|
|
|
}
|
|
|
av_free(out_buffer);
|
|
|
av_free(pFrameRGB);
|
|
|
avcodec_close(pCodecCtx);
|
|
|
avformat_close_input(&pFormatCtx);
|
|
|
-
|
|
|
- return 0;
|
|
|
}
|
|
|
-
|