我想从内存中解码jpeg数据。但是在我做了很多努力之后,仍然存在错误。
我的完整沙箱代码如下:
#include <math.h>
#include <memory.h>
#include "gst/gst.h"
#include <gio/gio.h>
#define KB (1024)
#define MB (1024*KB)
#define MAX_STR_LEN 256
#define FOUR (4)
#define ALIGN_TO_FOUR(VAL) (((VAL) + FOUR - 1) & ~(FOUR - 1) )
int BMPwriter(unsigned char *pRGB, int bitNum, int width, int height, char *pFileName)
{
FILE *fp;
int fileSize;
unsigned char *pMovRGB;
int i;
int widthStep;
unsigned char header[54] = {
0x42, // identity : B
0x4d, // identity : M
0, 0, 0, 0, // file size
0, 0, // reserved1
0, 0, // reserved2
54, 0, 0, 0, // RGB data offset
40, 0, 0, 0, // struct BITMAPINFOHEADER size
0, 0, 0, 0, // bmp width
0, 0, 0, 0, // bmp height
1, 0, // planes
24, 0, // bit per pixel
0, 0, 0, 0, // compression
0, 0, 0, 0, // data size
0, 0, 0, 0, // h resolution
0, 0, 0, 0, // v resolution
0, 0, 0, 0, // used colors
0, 0, 0, 0 // important colors
};
widthStep = ALIGN_TO_FOUR(width*bitNum/8);
fileSize = ALIGN_TO_FOUR(widthStep*height) + sizeof(header);
memcpy(&header[2], &fileSize, sizeof(int));
memcpy(&header[18], &width, sizeof(int));
memcpy(&header[22], &height, sizeof(int));
memcpy(&header[28], &bitNum, sizeof(short));
printf("written on file %s ...", pFileName);
fp = fopen(pFileName, "wb");
fwrite(&header[0], 1, sizeof(header), fp);
pMovRGB = pRGB + (height - 1)*widthStep;
for(i = 0; i < height; i++){
fwrite(pMovRGB, 1, widthStep, fp);
pMovRGB -= widthStep;
}/*for i*/
fclose(fp);
printf("done\n");
return 0;
}/*BMPwriter*/
int main(int argc, char* argv[])
{
GstElement *pPipeline;
gst_init (&argc, &argv);
pPipeline = gst_pipeline_new(NULL);
g_assert (pPipeline);
GstElement *pSrcElement;
#if(1) /*read data from memory*/
unsigned char *pJpeg;
unsigned long jpegSize;
FILE *fp;
fp = fopen("SomeJpegFile640x480.jpg", "rb"); /*the jpeg file be 640x480*/
pJpeg = (unsigned char*)malloc(3*MB);
jpegSize = (unsigned long)fread(pJpeg, 1, 3*MB, fp);
fclose(fp); fp = NULL;
printf("jpegSize = %3.1fKB\n", jpegSize/(float)KB);
GMemoryInputStream *pStreamIn;
pStreamIn = G_MEMORY_INPUT_STREAM (g_memory_input_stream_new_from_data (pJpeg, jpegSize,
(GDestroyNotify) g_free));
pSrcElement = gst_element_factory_make ("giostreamsrc", "src");
g_object_set (G_OBJECT (pSrcElement), "stream", pStreamIn, NULL);
#else
pSrcElement = gst_element_factory_make ("filesrc", "source");
g_object_set (G_OBJECT (pSrcElement), "location", pJpeg, NULL);
g_object_set (G_OBJECT (pSrcElement), "location","SomeJpegFile640x480.jpg", NULL);
#endif
if(NULL == pSrcElement)
{
g_printerr ("File could not be created. Exiting.\n");
return -1;
}
printf("__LINE__ = %d\n", __LINE__);
GstElement *pJpegDecoder;
pJpegDecoder = gst_element_factory_make ("jpegdec", "jpegdec");
if(NULL == pJpegDecoder)
{
g_printerr ("Jpg Decoder could not be created. Exiting.\n");
return -1;
}
GstElement *pFreeze;
pFreeze = gst_element_factory_make("imagefreeze", "freeze");
if(NULL == pFreeze)
{
g_printerr ("ImageFreeze could not be created. Exiting.\n");
return -1;
}/*pFreeze*/
GstElement *pColorspace;
pColorspace = gst_element_factory_make("ffmpegcolorspace", "ffmdec");
if(NULL == pColorspace)
{
g_printerr ("Colorspace could not be created. Exiting.\n");
return -1;
}
GstElement *pSink;
#if _DIRECT_RENDER
pSink = gst_element_factory_make ("ximagesink", "sink");
#else
unsigned char *pRGB;
pRGB = (unsigned char*)malloc(10*MB);
GMemoryOutputStream *pStreamOut;
pStreamOut = G_MEMORY_OUTPUT_STREAM (g_memory_output_stream_new (pRGB, 10*MB, NULL, (GDestroyNotify)free));
pSink = gst_element_factory_make ("giostreamsink", "sink");
g_object_set(G_OBJECT (pSink), "stream", pStreamOut, NULL);
#endif
if(NULL == pSink)
{
g_printerr ("Image sink could not be created. Exiting.\n");
return -1;
}
printf("__LINE__ = %d\n", __LINE__);
/* source | jpg-decoder | image-freeze | colorspace | sink */
gst_bin_add_many (GST_BIN (pPipeline), pSrcElement, pJpegDecoder, pFreeze, pColorspace, pSink, NULL);
//gst_bin_add_many (GST_BIN (pPipeline), pSrcElement, pJpegDecoder, pColorspace, pSink, NULL, NULL);
printf("__LINE__ = %d\n", __LINE__);
gst_element_link_many (pSrcElement, pJpegDecoder, pColorspace, pSink, NULL, NULL);
gst_element_set_state (pPipeline, GST_STATE_PLAYING);
#if _DIRECT_RENDER
getchar();
#else
pRGB = (unsigned char*)g_memory_output_stream_get_data(G_MEMORY_OUTPUT_STREAM(pStreamOut));
printf("data size = %u\n", g_memory_output_stream_get_size (G_MEMORY_OUTPUT_STREAM(pStreamOut)));
BMPwriter(pRGB, 24, 640, 480, "out.bmp");
#endif
gst_element_set_state (pPipeline, GST_STATE_READY);
gst_object_unref (pPipeline);
gst_object_unref(pFreeze); gst_object_unref(pSink); gst_object_unref(pColorspace); gst_object_unref(pJpegDecoder);
gst_object_unref(pSrcElement);
gst_object_unref(pStreamIn);
free(pJpeg);
printf("__LINE__ = %d\n", __LINE__);
return 0;
}/*main*/
(沙箱代码可能是内存泄漏并且有多余的变量,但我认为它并不重要。)
当jpeg数据来自内存时,代码可以定期运行。 当输出显示在窗口上时,代码可以正常工作。(如果已经定义了预处理器变量_DIRECT_RENDER。) 但是,如果我试图获取存储原始数据的内存并将其保存为bmp文件......这是错误的:数据只是空白。(_DIRECT_RENDER尚未定义模式。)
是否有人可以给我一个提示/指示来解决这个错误?
非常感谢。