如何使用gstreamer解码内存中的jpeg?

时间:2014-01-16 18:37:45

标签: jpeg gstreamer

我想从内存中解码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尚未定义模式。)

是否有人可以给我一个提示/指示来解决这个错误?

非常感谢。

0 个答案:

没有答案