[datatype-dev] RESEND: CR: support PGS embedded subtitle feature for mpge2ts

[datatype-dev] RESEND: CR: support PGS embedded subtitle feature for mpge2ts

Joe Li Joeli at realnetworks.com
Fri Dec 30 02:41:04 UTC 2011


Skipped content of type multipart/alternative-------------- next part --------------
/* ***** BEGIN LICENSE BLOCK *****
 * Source last modified: $Id
 * 
 * Portions Copyright (c) 1995-2004 RealNetworks, Inc. All Rights Reserved.
 * 
 * The contents of this file, and the files included with this file,
 * are subject to the current version of the RealNetworks Public
 * Source License (the "RPSL") available at
 * http://www.helixcommunity.org/content/rpsl unless you have licensed
 * the file under the current version of the RealNetworks Community
 * Source License (the "RCSL") available at
 * http://www.helixcommunity.org/content/rcsl, in which case the RCSL
 * will apply. You may also obtain the license terms directly from
 * RealNetworks.  You may not use this file except in compliance with
 * the RPSL or, if you have a valid RCSL with RealNetworks applicable
 * to this file, the RCSL.  Please see the applicable RPSL or RCSL for
 * the rights, obligations and limitations governing use of the
 * contents of the file.
 * 
 * Alternatively, the contents of this file may be used under the
 * terms of the GNU General Public License Version 2 (the
 * "GPL") in which case the provisions of the GPL are applicable
 * instead of those above. If you wish to allow use of your version of
 * this file only under the terms of the GPL, and not to allow others
 * to use your version of this file under the terms of either the RPSL
 * or RCSL, indicate your decision by deleting the provisions above
 * and replace them with the notice and other provisions required by
 * the GPL. If you do not delete the provisions above, a recipient may
 * use your version of this file under the terms of any one of the
 * RPSL, the RCSL or the GPL.
 * 
 * This file is part of the Helix DNA Technology. RealNetworks is the
 * developer of the Original Code and owns the copyrights in the
 * portions it created.
 * 
 * This file, and the files included with this file, is distributed
 * and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY
 * KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS
 * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET
 * ENJOYMENT OR NON-INFRINGEMENT.
 * 
 * Technology Compatibility Kit Test Suite(s) Location:
 *    http://www.helixcommunity.org/content/tck
 * 
 * Contributor(s):
 * 
 * ***** END LICENSE BLOCK ***** */
#include "bmpmaker.h"
#define LOG_TAG "bmpmaker.cpp"
#include <utils/Log.h>


BYTE* BMPMaker::GetData() 
{
    return mData;
}

UINT32 BMPMaker::GetWidth() 
{
    return mWidth;
}

UINT32 BMPMaker::GetHeight() 
{
    return mHeight;
}

UINT32 BMPMaker::GetBitCount() 
{
    return mBitCount;
}

void BMPMaker::BMPInfoHeader(UINT32 width, UINT32 height, UINT32 bitCount) 
{
    UINT32 value = 0;
    mWidth = width;
    mHeight = height;
    mBitCount = bitCount;

    mInfo[0] = 40;

    value = width;
    mInfo[4] = (BYTE) value;
    value = value >> 8;
    mInfo[5] = (BYTE) value;
    value = value >> 8;
    mInfo[6] = (BYTE) value;
    value = value >> 8;
    mInfo[7] = (BYTE) value;

    value = height;
    mInfo[8] = (BYTE) value;
    value = value >> 8;
    mInfo[9] = (BYTE) value;
    value = value >> 8;
    mInfo[10] = (BYTE) value;
    value = value >> 8;
    mInfo[11] = (BYTE) value;

    mInfo[12] = 1;
    mInfo[14] = (BYTE) bitCount;

    value = width * height * 3;
    if (width % 4 != 0)
        value += (width % 4) * height;
    mInfo[20] = (BYTE) value;
    value = value >> 8;
    mInfo[21] = (BYTE) value;
    value = value >> 8;
    mInfo[22] = (BYTE) value;
    value = value >> 8;
    mInfo[23] = (BYTE) value;
}

void BMPMaker::BMPFileHeader(UINT32 size, UINT32 offset) 
{
    UINT32 value = 0;
    mHeader[0] = 'B';
    mHeader[1] = 'M';
    
    value = size;
    mHeader[2] = (BYTE) value;
    value = value >> 8;
    mHeader[3] = (BYTE) value;
    value = value >> 8;
    mHeader[4] = (BYTE) value;
    value = value >> 8;
    mHeader[5] = (BYTE) value;
    
    value = offset;
    mHeader[10] = (BYTE) value;
    value = value >> 8;
    mHeader[11] = (BYTE) value;
    value = value >> 8;
    mHeader[12] = (BYTE) value;
    value = value >> 8;
    mHeader[13] = (BYTE) value;
}
-------------- next part --------------
/* ***** BEGIN LICENSE BLOCK *****
 * Source last modified: $Id
 * 
 * Portions Copyright (c) 1995-2004 RealNetworks, Inc. All Rights Reserved.
 * 
 * The contents of this file, and the files included with this file,
 * are subject to the current version of the RealNetworks Public
 * Source License (the "RPSL") available at
 * http://www.helixcommunity.org/content/rpsl unless you have licensed
 * the file under the current version of the RealNetworks Community
 * Source License (the "RCSL") available at
 * http://www.helixcommunity.org/content/rcsl, in which case the RCSL
 * will apply. You may also obtain the license terms directly from
 * RealNetworks.  You may not use this file except in compliance with
 * the RPSL or, if you have a valid RCSL with RealNetworks applicable
 * to this file, the RCSL.  Please see the applicable RPSL or RCSL for
 * the rights, obligations and limitations governing use of the
 * contents of the file.
 * 
 * Alternatively, the contents of this file may be used under the
 * terms of the GNU General Public License Version 2 (the
 * "GPL") in which case the provisions of the GPL are applicable
 * instead of those above. If you wish to allow use of your version of
 * this file only under the terms of the GPL, and not to allow others
 * to use your version of this file under the terms of either the RPSL
 * or RCSL, indicate your decision by deleting the provisions above
 * and replace them with the notice and other provisions required by
 * the GPL. If you do not delete the provisions above, a recipient may
 * use your version of this file under the terms of any one of the
 * RPSL, the RCSL or the GPL.
 * 
 * This file is part of the Helix DNA Technology. RealNetworks is the
 * developer of the Original Code and owns the copyrights in the
 * portions it created.
 * 
 * This file, and the files included with this file, is distributed
 * and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY
 * KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS
 * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET
 * ENJOYMENT OR NON-INFRINGEMENT.
 * 
 * Technology Compatibility Kit Test Suite(s) Location:
 *    http://www.helixcommunity.org/content/tck
 * 
 * Contributor(s):
 * 
 * ***** END LICENSE BLOCK ***** */
#ifndef _BMPMAKER_H_
#define _BMPMAKER_H_
#include "hxtypes.h"
class BMPMaker{
private:
    UINT32 mWidth;
    UINT32 mHeight;
    UINT32 mBitCount;
public:
    BYTE mHeader[14];
    BYTE mInfo[40];
    BYTE*  mData;
    BMPMaker()
    {
       memset(mHeader,0,14);
       memset(mInfo,0,40);
       mData = NULL;
    }
    ~BMPMaker()
    {
       if(mData)
       {
           free(mData);
       }
    }
    BYTE *GetData();
    UINT32 GetWidth();
    UINT32 GetHeight();
    UINT32 GetBitCount();
    void BMPInfoHeader(UINT32 width, UINT32 height, UINT32 bitCount);
    void BMPFileHeader(UINT32 size, UINT32 offset);
};
#endif
-------------- next part --------------
A non-text attachment was scrubbed...
Name: interface.diff
Type: application/octet-stream
Size: 673 bytes
Desc: interface.diff
Url : http://lists.helixcommunity.org/pipermail/datatype-dev/attachments/20111229/1553b646/interface-0001.obj
-------------- next part --------------
A non-text attachment was scrubbed...
Name: mpegts.format.diff
Type: application/octet-stream
Size: 10775 bytes
Desc: mpegts.format.diff
Url : http://lists.helixcommunity.org/pipermail/datatype-dev/attachments/20111229/1553b646/mpegts.format-0001.obj
-------------- next part --------------
/* ***** BEGIN LICENSE BLOCK *****
 * Source last modified: $Id
 * 
 * Portions Copyright (c) 1995-2004 RealNetworks, Inc. All Rights Reserved.
 * 
 * The contents of this file, and the files included with this file,
 * are subject to the current version of the RealNetworks Public
 * Source License (the "RPSL") available at
 * http://www.helixcommunity.org/content/rpsl unless you have licensed
 * the file under the current version of the RealNetworks Community
 * Source License (the "RCSL") available at
 * http://www.helixcommunity.org/content/rcsl, in which case the RCSL
 * will apply. You may also obtain the license terms directly from
 * RealNetworks.  You may not use this file except in compliance with
 * the RPSL or, if you have a valid RCSL with RealNetworks applicable
 * to this file, the RCSL.  Please see the applicable RPSL or RCSL for
 * the rights, obligations and limitations governing use of the
 * contents of the file.
 * 
 * Alternatively, the contents of this file may be used under the
 * terms of the GNU General Public License Version 2 (the
 * "GPL") in which case the provisions of the GPL are applicable
 * instead of those above. If you wish to allow use of your version of
 * this file only under the terms of the GPL, and not to allow others
 * to use your version of this file under the terms of either the RPSL
 * or RCSL, indicate your decision by deleting the provisions above
 * and replace them with the notice and other provisions required by
 * the GPL. If you do not delete the provisions above, a recipient may
 * use your version of this file under the terms of any one of the
 * RPSL, the RCSL or the GPL.
 * 
 * This file is part of the Helix DNA Technology. RealNetworks is the
 * developer of the Original Code and owns the copyrights in the
 * portions it created.
 * 
 * This file, and the files included with this file, is distributed
 * and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY
 * KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS
 * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET
 * ENJOYMENT OR NON-INFRINGEMENT.
 * 
 * Technology Compatibility Kit Test Suite(s) Location:
 *    http://www.helixcommunity.org/content/tck
 * 
 * Contributor(s):
 * 
 * ***** END LICENSE BLOCK ***** */
#include "pgsdec.h"
#include "bmpmaker.h"
#define LOG_TAG "pgsdec.cpp"
#include <utils/Log.h>

//if you want debug this PGS decoder, just enable it
//#define DGB_PGS_INFO

#define AVPALETTE_SIZE 1024
#define MAX_NEG_CROP 0
#define SCALEBITS 8
#define ONE_HALF (1 << (SCALEBITS - 1))
#define FIX(x) ((int) ((x) * (1L<<SCALEBITS) + 0.5)) 

#define YUV_TO_RGB1(cb1, cr1)\
{\
    cb = (cb1) - 128;\
    cr = (cr1) - 128;\
    r_add = FIX(1.40200) * cr + ONE_HALF;\
    g_add = - FIX(0.34414) * cb - FIX(0.71414) * cr + ONE_HALF;\
    b_add = FIX(1.77200) * cb + ONE_HALF;\
}

#define YUV_TO_RGB2(r, g, b, y1)\
{\
    y = (y1) << SCALEBITS;\
    r = cm[(y + r_add) >> SCALEBITS];\
    g = cm[(y + g_add) >> SCALEBITS];\
    b = cm[(y + b_add) >> SCALEBITS];\
}

/**
 * Decode the Run Length Encoded data to PGM raw data.
 *
 * @OUT param subctx contains the current codec context
 * @IN  param sub pointer to the RLE data to process
 * @IN  param buf pointer to the packet to process
 * @IN  param buf_size size of packet to process
 */
HX_RESULT PGSSubtitleDec::decode_rle(PGSSubContext *subctx, AVSubtitle *sub, const UINT8 *buf, UINT32 buf_size)
{
    HX_RESULT retVal = HXR_FAIL;
    const UINT8 *rle_bitmap_end;
    int pixel_count, line_count;

    rle_bitmap_end = buf + buf_size;

    sub->rects.data = malloc(sub->rects.w * sub->rects.h);

    if (!sub->rects.data)
        return HXR_OUTOFMEMORY;

    pixel_count = 0;
    line_count  = 0;

    while (buf < rle_bitmap_end && line_count < sub->rects.h) {
        UINT8 flags, color;
        int run; 

        color = bytestream_get_byte(&buf);
        run   = 1;

        if (color == 0x00) {
            flags = bytestream_get_byte(&buf);
            run   = flags & 0x3f;
            if (flags & 0x40)
                run = (run << 8) + bytestream_get_byte(&buf);
            color = flags & 0x80 ? bytestream_get_byte(&buf) : 0;
        }

        if (run > 0 && pixel_count + run <= sub->rects.w * sub->rects.h) {
            memset(sub->rects.data + pixel_count, color, run);
            pixel_count += run;
        } else if (!run) {
            /*
             * New Line. Check if correct pixels decoded, if not display warning
             * and adjust bitmap pointer to correct new line position.
             */
            if (pixel_count % sub->rects.w > 0)
                LOGD("Decoded %d pixels, when line should be %d pixels\n", pixel_count % sub->rects.w, sub->rects.w);
            line_count++;
        }
    }

    if (pixel_count < sub->rects.w * sub->rects.h) {
        LOGD("Insufficient RLE data for subtitle\n");
        return retVal;
    }

#ifdef DGB_PGS_INFO
    //checking the bitmap info
    FILE *out = NULL;
    char name[32]= {0};
    sprintf(name,"/data/www.log%d.pgm",m_Counter++);
    out =fopen(name,"w");
    fprintf( out, "P2\n" );
    fprintf( out, "%d %d\n", 720, 56);
    fprintf( out, "%d\n", 3 );
    BYTE *by = sub->rects.data;
    LOGD("PGS DBG Info at %s,%d__line_count:%d__\n",__FUNCTION__,__LINE__,line_count);
    for(int k=0;(k<(sub->rects.w * sub->rects.h))&& (by);k++)
    {
       fprintf(out,"%d ",by[k]);
       //LOGD("by[%d]==%x \n",k,by[k]);
       if(k % (sub->rects.w) == 0)
           fprintf(out,"\n");
    }
    fclose(out);
#endif
    //end for checking
    LOGD("Pixel Count = %d, Area = %d\n", pixel_count, sub->rects.w * sub->rects.h);

    return HXR_OK;
}

/**
 * Parse the picture segment packet.
 *
 * The picture segment contains details on the sequence id,
 * width, height and Run Length Encoded (RLE) bitmap data.
 *
 * @OUT param subctx contains the current codec context
 * @IN  param buf pointer to the packet to process
 * @IN  param buf_size size of packet to process
 * @todo TODO: Support for RLE data over multiple packets
 */
 
HX_RESULT PGSSubtitleDec::parse_picture_segment(PGSSubContext *subctx,const UINT8 *buf, UINT32 buf_size)
{
    HX_RESULT retVal = HXR_FAIL;
    UINT8 sequence_desc;
    unsigned int rle_bitmap_len, width, height;

    if (buf_size <= 4)
        return retVal;
    buf_size -= 4;

    /* skip 3 unknown bytes: Object ID (2 bytes), Version Number */
    buf += 3;

    /* Read the Sequence Description to determine if start of RLE data or appended to previous RLE */
    sequence_desc = bytestream_get_byte(&buf);

#if 0
    //we will support for multi-section pgs subtitle data
    if (!(sequence_desc & 0x80)) {
        /* Additional RLE data */
        if (buf_size > subctx->picture.rle_remaining_len)
            return -1;

        memcpy(subctx->picture.rle + subctx->picture.rle_data_len, buf, buf_size);
        subctx->picture.rle_data_len += buf_size;
        subctx->picture.rle_remaining_len -= buf_size;

        return 0;
    }
#endif

    if (buf_size <= 7)
        return retVal;
    buf_size -= 7;

    /* Decode rle bitmap length, stored size includes width/height data */
    rle_bitmap_len = bytestream_get_be24(&buf) - 2*2;

    /* Get bitmap dimensions from data */
    width  = bytestream_get_be16(&buf);
    height = bytestream_get_be16(&buf);

    /* Make sure the bitmap is not too large */
    #if 0
    if (subctx->width < width || subctx->height < height) {
        LOGD("Bitmap dimensions larger then video.\n");
        return -1;
    }
    #endif

    subctx->picture.w = width;
    subctx->picture.h = height;

    subctx->picture.rle = (unsigned char *)malloc(rle_bitmap_len);
    if (!subctx->picture.rle)
        return HXR_OUTOFMEMORY;

    memcpy(subctx->picture.rle, buf, buf_size);

    subctx->picture.rle_data_len = buf_size;
    subctx->picture.rle_remaining_len = rle_bitmap_len - buf_size;

    return HXR_OK;
}

/**
 * Parse the palette segment packet.
 *
 * The palette segment contains details of the palette
 *
 * @OUT param subctx contains the current codec context
 * @IN param buf pointer to the packet to process
 * @IN param buf_size size of packet to process
 */
void PGSSubtitleDec::parse_palette_segment(PGSSubContext *subctx,const UINT8 *buf, UINT32 buf_size)
{
    const UINT8 *buf_end = buf + buf_size;
    uint8_t ff_cropTbl[256 + 2 * MAX_NEG_CROP] = {0, }; 
    const UINT8 *cm      = ff_cropTbl + MAX_NEG_CROP;
    int color_id,i;
    int y, cb, cr, alpha;
    int r, g, b, r_add, g_add, b_add;

    //initial ff_cropTbl here
    for(i=0;i<256;i++) 
        ff_cropTbl[i + MAX_NEG_CROP] = i;
    for(i=0;i<MAX_NEG_CROP;i++) 
    {
        ff_cropTbl[i] = 0;
        ff_cropTbl[i + MAX_NEG_CROP + 256] = 255;
    } 

    /* Skip two null bytes */
    buf += 2;

    while (buf < buf_end) {
        color_id  = bytestream_get_byte(&buf);
        y         = bytestream_get_byte(&buf);
        cb        = bytestream_get_byte(&buf);
        cr        = bytestream_get_byte(&buf);
        alpha     = bytestream_get_byte(&buf);

        YUV_TO_RGB1(cb, cr);
        YUV_TO_RGB2(r, g, b, y);

#ifdef DGB_PGS_INFO
        LOGD("PGS DBG Info at %s,%d_clr:%x,y:%x,cb:%x,cr:%x,alp:%x__\n",__FUNCTION__,__LINE__,color_id,y,cb,cr,alpha);
        LOGD("(y:%d,r_add:%d,g_add:%d,b_add:%d)\n", y,r_add,g_add,b_add);
        LOGD("Color %d := (%d,%d,%d,%d)\n", color_id, r, g, b, alpha);
#endif

        /* Store color in palette */
        subctx->clut[color_id] = RGBA(r,g,b,alpha);
    }
}

/**
 * Window Segment Structure (No new information provided):

 * @OUT param subctx contains the current codec context
 * @IN param buf pointer to the packet to process
 * @IN buf_size size of packet to process

 * 2 bytes: Unkown,
 * 2 bytes: X position of subtitle,
 * 2 bytes: Y position of subtitle,
 * 2 bytes: Width of subtitle,
 * 2 bytes: Height of subtitle.
**/
void PGSSubtitleDec::parse_window_segment(PGSSubContext *subctx, const UINT8 *buf, UINT32 buf_size)
{
    //skip 2 bytes unknown
    buf += 2;
    int x = bytestream_get_be16(&buf);
    int y = bytestream_get_be16(&buf);
    LOGD("Subtitle position: (%d,%d)\n", x,y);

    UINT32 w = bytestream_get_be16(&buf);
    UINT32 h = bytestream_get_be16(&buf);
    LOGD("Subtitle Dimensions: %dx%d\n", w,h);
}

/**
 * Parse the presentation segment packet.
 *
 * The presentation segment contains details on the video
 * width, video height, x & y subtitle position.
 *
 * @OUT param subctx contains the current codec context
 * @IN param buf pointer to the packet to process
 * @IN buf_size size of packet to process
 * @todo TODO: Implement cropping
 */
void PGSSubtitleDec::parse_presentation_segment(PGSSubContext *subctx, const UINT8 *buf, UINT32 buf_size)
{
    int    x = 0;
    int    y = 0;
    UINT32 w = bytestream_get_be16(&buf);
    UINT32 h = bytestream_get_be16(&buf);
    LOGD("Video Dimensions %dx%d\n",  w, h);

    /* Skip 1 bytes of unknown, frame rate? */
    buf++;

    subctx->presentation.id_number = bytestream_get_be16(&buf);

    /*
     * Skip 3 bytes of unknown:
     *     state
     *     palette_update_flag (0x80),
     *     palette_id_to_use,
     */
    buf += 3;

    subctx->presentation.object_number = bytestream_get_byte(&buf);
    if (!subctx->presentation.object_number)
        return;

    /*
     * Skip 4 bytes of unknown:
     *     object_id_ref (2 bytes),
     *     window_id_ref,
     *     composition_flag (0x80 - object cropped, 0x40 - object forced)
     */
    buf += 4;

    x = bytestream_get_be16(&buf);
    y = bytestream_get_be16(&buf);

    /* TODO If cropping, cropping_x, cropping_y, cropping_width, cropping_height (all 2 bytes).*/

    LOGD("Subtitle Placement x=%d, y=%d\n", x, y);

    #if 0
    //we will support crop later
    if (x > subctx->width || y > subctx->height) {
        LOGD("Subtitle out of video bounds. x = %d, y = %d, video width = %d, video height = %d.\n", x, y, subctx->width, subctx->height);
        x = 0; y = 0;
    }
    #endif

    /* Fill in dimensions */
    subctx->presentation.x = x;
    subctx->presentation.y = y;
}

/**
 * Parse the display segment packet.
 *
 * The display segment controls the updating of the display.
 *
 * @IN param subctx contains the current codec context
 * @OUT param sub pointer to the data pertaining the subtitle to display
 * @IN param buf pointer to the packet to process
 * @IN param buf_size size of packet to process
 * @todo TODO: start/end time, relies on correct PTS, currently it is a little late
 */
HX_RESULT PGSSubtitleDec::display_end_segment(PGSSubContext *subctx,AVSubtitle *sub, const UINT8 *buf, UINT32 buf_size)
{
    HX_RESULT retVal = HXR_FAIL;
    if(!sub || !subctx)
        return HXR_FAIL;
    if(sub->dispType == CLR_CMMD)
    {
        //its a clear command here, so reture directly
        return HXR_OK;
    }

    // Blank if last object_number was 0.
    // Note that this may be wrong for more complex subtitles.
    if (!subctx->presentation.object_number)
    {
        LOGD("PGS DBG Info at %s,%d__last object numer is 0__\n",__FUNCTION__,__LINE__);
        return retVal;
    }

    sub->rects.x    = subctx->presentation.x;
    sub->rects.y    = subctx->presentation.y;
    sub->rects.w    = subctx->picture.w;
    sub->rects.h    = subctx->picture.h;

    /* Process bitmap */
    sub->rects.linesize = subctx->picture.w;
#ifdef PGS_DBF_INFO
    LOGD("PGS DBG Info at %s,%d__x:%d,y:%d__\n",__FUNCTION__,__LINE__,subctx->presentation.x,subctx->presentation.y);
    LOGD("PGS DBG Info at %s,%d__w:%d,h:%d__\n",__FUNCTION__,__LINE__,subctx->picture.w,subctx->picture.h);
    LOGD("PGS DBG Info at %s,%d__pict:linesize:%d__\n",__FUNCTION__,__LINE__,subctx->picture.w);
#endif

    if (subctx->picture.rle) {
        if (subctx->picture.rle_remaining_len)
            LOGD("RLE data length %u is %u bytes shorter than expected\n", subctx->picture.rle_data_len, subctx->picture.rle_remaining_len);
        if(decode_rle(subctx,sub, subctx->picture.rle, subctx->picture.rle_data_len) != HXR_OK)
            return retVal;
    }
	
    return HXR_OK;
}

/**
 * Decode the whole packet.
 *
 * @IN param pBuffer contains the current pgs subtitle packet
 * @OUT param data pointer to the data of parsing subtile
 * @OUT param errValue keep the value of subtitle parsing tracks.
**/
HX_RESULT PGSSubtitleDec::decode(IHXBuffer *pBuffer, AVSubtitle *data, UINT32 *errValue)
{ 
    HX_RESULT retVal = HXR_FAIL;
    if(!pBuffer || !data)
        return retVal;
	
    const UINT8* buf = pBuffer->GetBuffer();
    UINT32 buf_size  = pBuffer->GetSize();
    const UINT8*  buf_end;
    UINT8         segment_type;
    UINT32        segment_length = 0;
    int           ipos= 0;	
    BYTE          nHeaderRemainderLength = 0;
    PGSSubContext tmpContext;
    tmpContext.picture.rle = NULL;
	
    *errValue = 0;
    /* Ensure that we have received at a least a segment code and segment length */
    if (buf_size < 3)
        return retVal;

    buf_end = buf + buf_size;

    /* Step through buffer to identify segments */
    while (buf < buf_end) {
        //Get the next start code here
        // check PES start code
        while((buf[ipos] != 0)   || 
                (buf[ipos+1] != 0) || 
                (buf[ipos+2] != 1) ||  
                (buf[ipos+3] != 0xBD))
        {
             buf++;      
        }
        nHeaderRemainderLength = buf[ipos+8];

#ifdef DGB_PGS_INFO	
        LOGD("PGS DBG Info at %s,%d___nHeaderRemainderLength:%u___\n",__FUNCTION__,__LINE__,nHeaderRemainderLength);
        for(int i=0;i<(8+nHeaderRemainderLength);i++)
        {
          LOGD("PGS DBG Info at %s,%d___byte:%x___\n",__FUNCTION__,__LINE__,buf[i]);
        }
#endif	
	buf +=8;
	buf += 	nHeaderRemainderLength + 1;
	 
        segment_type   = bytestream_get_byte(&buf);
        segment_length = bytestream_get_be16(&buf);

        LOGD("PGS DBG Info Segment Length %d, Segment Type %x\n", segment_length, segment_type);

        if (segment_type != DISPLAY_SEGMENT && segment_length > buf_end - buf)
            break;

        switch (segment_type) {
        case PALETTE_SEGMENT:
            parse_palette_segment(&tmpContext,buf, segment_length);
            break;
        case PICTURE_SEGMENT:
            data->dispType = RAW_DATA;
            *errValue = parse_picture_segment(&tmpContext,buf, segment_length);
            break;
        case PRESENTATION_SEGMENT:
            parse_presentation_segment(&tmpContext,buf, segment_length);
            break;
        case WINDOW_SEGMENT:
            parse_window_segment(&tmpContext,buf, segment_length);
            break;
        case DISPLAY_SEGMENT:
            *errValue = display_end_segment(&tmpContext,data, buf, segment_length);
            break;
        default:
            LOGD("Unknown subtitle segment type 0x%x, length %d\n", segment_type, segment_length);
            break;
        }
        buf += segment_length;
        if(*errValue != HXR_OK)
        {		
            break;		
        }				
    }
    if(tmpContext.picture.rle)
        free(tmpContext.picture.rle);
    return HXR_OK;
}
-------------- next part --------------
/* ***** BEGIN LICENSE BLOCK *****
 * Source last modified: $Id
 * 
 * Portions Copyright (c) 1995-2004 RealNetworks, Inc. All Rights Reserved.
 * 
 * The contents of this file, and the files included with this file,
 * are subject to the current version of the RealNetworks Public
 * Source License (the "RPSL") available at
 * http://www.helixcommunity.org/content/rpsl unless you have licensed
 * the file under the current version of the RealNetworks Community
 * Source License (the "RCSL") available at
 * http://www.helixcommunity.org/content/rcsl, in which case the RCSL
 * will apply. You may also obtain the license terms directly from
 * RealNetworks.  You may not use this file except in compliance with
 * the RPSL or, if you have a valid RCSL with RealNetworks applicable
 * to this file, the RCSL.  Please see the applicable RPSL or RCSL for
 * the rights, obligations and limitations governing use of the
 * contents of the file.
 * 
 * Alternatively, the contents of this file may be used under the
 * terms of the GNU General Public License Version 2 (the
 * "GPL") in which case the provisions of the GPL are applicable
 * instead of those above. If you wish to allow use of your version of
 * this file only under the terms of the GPL, and not to allow others
 * to use your version of this file under the terms of either the RPSL
 * or RCSL, indicate your decision by deleting the provisions above
 * and replace them with the notice and other provisions required by
 * the GPL. If you do not delete the provisions above, a recipient may
 * use your version of this file under the terms of any one of the
 * RPSL, the RCSL or the GPL.
 * 
 * This file is part of the Helix DNA Technology. RealNetworks is the
 * developer of the Original Code and owns the copyrights in the
 * portions it created.
 * 
 * This file, and the files included with this file, is distributed
 * and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY
 * KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS
 * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET
 * ENJOYMENT OR NON-INFRINGEMENT.
 * 
 * Technology Compatibility Kit Test Suite(s) Location:
 *    http://www.helixcommunity.org/content/tck
 * 
 * Contributor(s):
 * 
 * ***** END LICENSE BLOCK ***** */

#ifndef _PGSSUBTITLEDEC_H_
#define _PGSSUBTITLEDEC_H_
#include "hxtypes.h"
#include "hxcomm.h"
#include "ihxpckts.h"
#include "hxresult.h"

#define RGBA(r,g,b,a) (((a) << 24) | ((r) << 16) | ((g) << 8) | (b))

#define AV_RL16(x) ((((uint8_t*)(x))[0] << 8) | ((uint8_t*)(x))[1])

#define AV_RL24(x) ((((uint8_t*)(x))[0] << 16) | \
                   (((uint8_t*)(x))[1] << 8) | \
                   ((uint8_t*)(x))[2])

static inline unsigned int bytestream_get_be24(uint8_t **b)
{
    (*b) += 3;
    return AV_RL24(*b - 3);
}

static inline unsigned int bytestream_get_be16(uint8_t **b)
{
    (*b) += 2;
    return AV_RL16(*b - 2);
}

static inline unsigned int bytestream_get_byte(uint8_t **b)
{
    (*b)++;
    return (*b)[-1];
}

enum SegmentType {
    PALETTE_SEGMENT      = 0x14,
    PICTURE_SEGMENT      = 0x15,
    PRESENTATION_SEGMENT = 0x16,
    WINDOW_SEGMENT       = 0x17,
    DISPLAY_SEGMENT      = 0x80
};

enum DisplayType {
    RAW_DATA = 0,
    CLR_CMMD = 1
};

typedef struct PGSSubPresentation {
    int x;
    int y;
    int id_number;
    int object_number;
} PGSSubPresentation;

typedef struct PGSSubPicture {
    UINT32       w;
    UINT32       h;
    UINT8*       rle;
    unsigned int rle_buffer_size, rle_data_len;
    unsigned int rle_remaining_len;
} PGSSubPicture;

typedef struct PGSSubContext {
    PGSSubPresentation presentation;
    UINT32             clut[256];
    PGSSubPicture      picture;
} PGSSubContext;

typedef struct AVSubtitleRect {
    int    x;         ///< top left corner  of pict, undefined when pict is not set
    int    y;         ///< top left corner  of pict, undefined when pict is not set
    UINT32 w;         ///< width            of pict, undefined when pict is not set
    UINT32 h;         ///< height           of pict, undefined when pict is not set
    UINT32 nb_colors; ///< number of colors in pict, undefined when pict is not set
    UINT32 linesize;
    UINT8* data;
} AVSubtitleRect;

typedef struct AVSubtitle {
    int            dispType; //0: raw data stored; 1: clear command store
    AVSubtitleRect rects;
} AVSubtitle;

class PGSSubtitleDec 
{
public:
    IUnknown*         m_pContext;	
    PGSSubContext*    m_pPGSContext;	
    int               m_Counter;
    
    PGSSubtitleDec(IUnknown* pContext)
    {
        m_pPGSContext = NULL;
        m_pContext = pContext;
        HX_ADDREF(m_pContext);
        m_Counter = 0;	
    }
	
    ~PGSSubtitleDec()
    {
        HX_DELETE(m_pPGSContext);
        HX_RELEASE(m_pContext);
    }

    HX_RESULT decode(IHXBuffer *pBuffer, AVSubtitle *data, UINT32 *errValue);	
    HX_RESULT display_end_segment(PGSSubContext *subctx, AVSubtitle *sub, const UINT8 *buf, UINT32 buf_size);
    void parse_presentation_segment(PGSSubContext *subctx, const UINT8 *buf, UINT32 buf_size);
    void parse_window_segment(PGSSubContext *subctx, const UINT8 *buf, UINT32 buf_size);
    void parse_palette_segment(PGSSubContext *subctx, const UINT8 *buf, UINT32 buf_size);
    HX_RESULT parse_picture_segment(PGSSubContext *subctx, const UINT8 *buf, UINT32 buf_size);
    HX_RESULT decode_rle(PGSSubContext *subctx, AVSubtitle *sub, const UINT8 *buf, UINT32 buf_size);
};
#endif
-------------- next part --------------
/* ***** BEGIN LICENSE BLOCK *****
 * Source last modified: $Id: pgspayload.cpp,v 1.2.2.1.6.2 2011/05/25 08:18:38 joeli Exp $
 * 
 * Portions Copyright (c) 1995-2004 RealNetworks, Inc. All Rights Reserved.
 * 
 * The contents of this file, and the files included with this file,
 * are subject to the current version of the RealNetworks Public
 * Source License (the "RPSL") available at
 * http://www.helixcommunity.org/content/rpsl unless you have licensed
 * the file under the current version of the RealNetworks Community
 * Source License (the "RCSL") available at
 * http://www.helixcommunity.org/content/rcsl, in which case the RCSL
 * will apply. You may also obtain the license terms directly from
 * RealNetworks.  You may not use this file except in compliance with
 * the RPSL or, if you have a valid RCSL with RealNetworks applicable
 * to this file, the RCSL.  Please see the applicable RPSL or RCSL for
 * the rights, obligations and limitations governing use of the
 * contents of the file.
 * 
 * Alternatively, the contents of this file may be used under the
 * terms of the GNU General Public License Version 2 (the
 * "GPL") in which case the provisions of the GPL are applicable
 * instead of those above. If you wish to allow use of your version of
 * this file only under the terms of the GPL, and not to allow others
 * to use your version of this file under the terms of either the RPSL
 * or RCSL, indicate your decision by deleting the provisions above
 * and replace them with the notice and other provisions required by
 * the GPL. If you do not delete the provisions above, a recipient may
 * use your version of this file under the terms of any one of the
 * RPSL, the RCSL or the GPL.
 * 
 * This file is part of the Helix DNA Technology. RealNetworks is the
 * developer of the Original Code and owns the copyrights in the
 * portions it created.
 * 
 * This file, and the files included with this file, is distributed
 * and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY
 * KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS
 * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET
 * ENJOYMENT OR NON-INFRINGEMENT.
 * 
 * Technology Compatibility Kit Test Suite(s) Location:
 *    http://www.helixcommunity.org/content/tck
 * 
 * Contributor(s):
 * 
 * ***** END LICENSE BLOCK ***** */

#include "hxtypes.h"
#include "hxresult.h"
#include "hxassert.h"
#include "pckunpck.h"
#include "pgspayload.h"

CHXPGSPayload::CHXPGSPayload(IUnknown* pContext)
    : CHXBasePayload(pContext)
{
}

CHXPGSPayload::~CHXPGSPayload()
{
}

HXBOOL
CHXPGSPayload::IsStreamHeaderInfoReady(void)
{
    return TRUE;
}

HX_RESULT
CHXPGSPayload::PrepareHeader(IHXValues* pHeader)
{
    HX_ASSERT(pHeader);
    if (pHeader)
    {
        SetCStringPropertyCCF(pHeader, "MimeType", HX_TS_SUBTITLE_MIME_TYPE, m_pContext);
        pHeader->SetPropertyULONG32("Preroll", 0);
    }
    return HXR_OK;
}
-------------- next part --------------

/* ***** BEGIN LICENSE BLOCK *****
 * Source last modified: $Id: pgspayload.h,v 1.1.18.1 2011/05/25 07:53:02 joeli Exp $
 * 
 * Portions Copyright (c) 1995-2004 RealNetworks, Inc. All Rights Reserved.
 * 
 * The contents of this file, and the files included with this file,
 * are subject to the current version of the RealNetworks Public
 * Source License (the "RPSL") available at
 * http://www.helixcommunity.org/content/rpsl unless you have licensed
 * the file under the current version of the RealNetworks Community
 * Source License (the "RCSL") available at
 * http://www.helixcommunity.org/content/rcsl, in which case the RCSL
 * will apply. You may also obtain the license terms directly from
 * RealNetworks.  You may not use this file except in compliance with
 * the RPSL or, if you have a valid RCSL with RealNetworks applicable
 * to this file, the RCSL.  Please see the applicable RPSL or RCSL for
 * the rights, obligations and limitations governing use of the
 * contents of the file.
 * 
 * Alternatively, the contents of this file may be used under the
 * terms of the GNU General Public License Version 2 (the
 * "GPL") in which case the provisions of the GPL are applicable
 * instead of those above. If you wish to allow use of your version of
 * this file only under the terms of the GPL, and not to allow others
 * to use your version of this file under the terms of either the RPSL
 * or RCSL, indicate your decision by deleting the provisions above
 * and replace them with the notice and other provisions required by
 * the GPL. If you do not delete the provisions above, a recipient may
 * use your version of this file under the terms of any one of the
 * RPSL, the RCSL or the GPL.
 * 
 * This file is part of the Helix DNA Technology. RealNetworks is the
 * developer of the Original Code and owns the copyrights in the
 * portions it created.
 * 
 * This file, and the files included with this file, is distributed
 * and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY
 * KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS
 * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET
 * ENJOYMENT OR NON-INFRINGEMENT.
 * 
 * Technology Compatibility Kit Test Suite(s) Location:
 *    http://www.helixcommunity.org/content/tck
 * 
 * Contributor(s):
 * 
 * ***** END LICENSE BLOCK ***** */
#ifndef _PGSPAYLOAD_H_
#define _PGSPAYLOAD_H_

#include "basepayload.h"

#define HX_TS_SUBTITLE_MIME_TYPE    "subtitle/pgs"

enum SegmentType {
    PALETTE_SEGMENT      = 0x14,
    PICTURE_SEGMENT      = 0x15,
    PRESENTATION_SEGMENT = 0x16,
    WINDOW_SEGMENT       = 0x17,
    DISPLAY_SEGMENT      = 0x80,
};

class CHXPGSPayload : public CHXBasePayload
{
public:
    CHXPGSPayload(IUnknown* pContext);
    virtual ~CHXPGSPayload();
    virtual HXBOOL      NeedAU() { return FALSE; }

    virtual HX_RESULT   PrepareHeader(IHXValues* pHeader);
    virtual HXBOOL      IsStreamHeaderInfoReady(void);
};

#endif /*_PGSPAYLOAD_H_*/
-------------- next part --------------
A non-text attachment was scrubbed...
Name: text.renderer.diff
Type: application/octet-stream
Size: 14652 bytes
Desc: text.renderer.diff
Url : http://lists.helixcommunity.org/pipermail/datatype-dev/attachments/20111229/1553b646/text.renderer-0001.obj
-------------- next part --------------
A non-text attachment was scrubbed...
Name: video.display.diff
Type: application/octet-stream
Size: 2591 bytes
Desc: video.display.diff
Url : http://lists.helixcommunity.org/pipermail/datatype-dev/attachments/20111229/1553b646/video.display-0001.obj


More information about the Datatype-dev mailing list
 

Site Map   |   Terms of Use   |   Privacy Policy   |   Contact Us

Copyright © 1995-2007 RealNetworks, Inc. All rights reserved. RealNetworks and Helix are trademarks of RealNetworks.
All other trademarks or registered trademarks are the property of their respective holders.