diff --git a/gst/mpegtsdemux/tsdemux.c b/gst/mpegtsdemux/tsdemux.c
index fe0c3a6..6097a3f 100644
--- a/gst/mpegtsdemux/tsdemux.c
+++ b/gst/mpegtsdemux/tsdemux.c
@@ -113,6 +113,8 @@ typedef struct _TSDemuxStream TSDemuxStream;
 
 typedef struct _TSDemuxH264ParsingInfos TSDemuxH264ParsingInfos;
 
+typedef struct _TSDemuxJP2KParsingInfos TSDemuxJP2KParsingInfos;
+
 /* Returns TRUE if a keyframe was found */
 typedef gboolean (*GstTsDemuxKeyFrameScanFunction) (TSDemuxStream * stream,
     guint8 * data, const gsize data_size, const gsize max_frame_offset);
@@ -133,6 +135,12 @@ struct _TSDemuxH264ParsingInfos
   SimpleBuffer framedata;
 };
 
+struct _TSDemuxJP2KParsingInfos
+{
+  /* J2K parsing data */
+  gboolean interlace;
+};
+
 struct _TSDemuxStream
 {
   MpegTSBaseStream stream;
@@ -200,6 +208,7 @@ struct _TSDemuxStream
 
   GstTsDemuxKeyFrameScanFunction scan_function;
   TSDemuxH264ParsingInfos h264infos;
+  TSDemuxJP2KParsingInfos jp2kInfos;
 };
 
 #define VIDEO_CAPS \
@@ -215,8 +224,8 @@ struct _TSDemuxStream
     "video/x-cavs;" \
     "video/x-wmv," \
       "wmvversion = (int) 3, " \
-      "format = (string) WVC1" \
-  )
+      "format = (string) WVC1;" \
+      "image/x-jpc;" )
 
 #define AUDIO_CAPS \
   GST_STATIC_CAPS ( \
@@ -1452,6 +1461,75 @@ create_pad_for_stream (MpegTSBase * base, MpegTSBaseStream * bstream,
           "stream-format", G_TYPE_STRING, "byte-stream",
           "alignment", G_TYPE_STRING, "nal", NULL);
       break;
+    case GST_MPEGTS_STREAM_TYPE_VIDEO_JP2K:
+      is_video = TRUE;
+      desc = mpegts_get_descriptor_from_stream (bstream, GST_MTS_DESC_J2K_VIDEO);
+      if(desc == NULL){
+         caps = gst_caps_new_empty_simple ("image/x-jpc");
+         break;
+      } else {
+        GstByteReader br;
+        /* Skip the descpriptor tag and length */
+        gst_byte_reader_init (&br, desc->data + 2, desc->length);
+
+        guint16 profile_and_level = gst_byte_reader_get_uint16_be_unchecked(&br);
+        guint32 horizontal_size = gst_byte_reader_get_uint32_be_unchecked (&br);
+        guint32 vertical_size = gst_byte_reader_get_uint32_be_unchecked (&br);
+        guint32 max_bit_rate = gst_byte_reader_get_uint32_be_unchecked (&br);
+        guint32 max_buffer_size = gst_byte_reader_get_uint32_be_unchecked (&br);
+        guint16 DEN_frame_rate = gst_byte_reader_get_uint16_be_unchecked(&br);
+        guint16 NUM_frame_rate = gst_byte_reader_get_uint16_be_unchecked(&br);
+        guint8 color_specification = gst_byte_reader_get_uint8_unchecked (&br);
+        guint8 remaining_8b = gst_byte_reader_get_uint8_unchecked (&br);
+        gboolean still_mode = remaining_8b & 0x80;
+        gboolean interlaced_video = remaining_8b & 0x40;
+        guint8 reserved = remaining_8b;
+
+        const gchar * interlace_mode;
+        const gchar * colorspace;
+        const gchar * colorimetry_mode;
+        
+        if(interlaced_video){
+          interlace_mode = "interleaved";
+          stream->jp2kInfos.interlace = TRUE;
+        } else {
+          interlace_mode = "progressive";
+          stream->jp2kInfos.interlace = FALSE;
+        }
+
+        switch(color_specification)
+        {
+          case 1:
+            colorspace = "sRGB";
+            colorimetry_mode = "UNKNOWN";
+            break;
+
+          case 2:
+            colorspace = "sYUV";
+            colorimetry_mode = "bt601";
+            break;
+
+          case 3:
+            colorspace = "sYUV";
+            colorimetry_mode = "bt709";
+            break;
+
+          case 4:
+            colorspace = "sYUV";
+            colorimetry_mode = "bt709";
+          break;
+          default:
+          colorspace = "";
+          colorimetry_mode = "";
+        }
+
+        caps = gst_caps_new_simple ("image/x-jpc",
+                                    "framerate", GST_TYPE_FRACTION, NUM_frame_rate, DEN_frame_rate,
+                                    "interlace-mode", G_TYPE_STRING, interlace_mode,
+                                    "colorimetry", G_TYPE_STRING, colorimetry_mode,
+                                    "colorspace", G_TYPE_STRING, colorspace, NULL);
+      }
+      break; 
     case ST_VIDEO_DIRAC:
       if (bstream->registration_id == 0x64726163) {
         GST_LOG ("dirac");
@@ -2547,6 +2625,186 @@ error:
   }
 }
 
+static GstBufferList *
+parse_jp2k_access_unit (TSDemuxStream * stream)
+{
+  GstByteReader reader;
+  GstBufferList *buffer_list = NULL;
+
+  buffer_list = gst_buffer_list_new ();
+  gst_byte_reader_init (&reader, stream->data, stream->current_size);
+
+  // header tag
+  guint32 header_tag;
+
+  GstBuffer *buffer;
+  // Framerate box
+  guint16 den  = 0;
+  guint16 num  = 0;
+  // Maximum bitrate box
+  guint32 MaxBr = 0;
+  guint32 AUF[2] = { 0 };
+  // Field Coding Box
+  guint8 Fic = 1;
+  guint8 Fio = 0;
+  // Time Code box
+  guint32 HHMMSSFF = 0;
+  // Broadcast color box
+  guint8 CollC = 0;
+  guint8 b;
+
+  guint8 *packet_data;
+  guint packet_size;
+
+  // Elementary stream header box 'elsm' == 0x656c736d
+  if (!gst_byte_reader_get_uint32_be(&reader, &header_tag))
+    goto error;
+
+  if(header_tag == 0x656c736d)
+  {
+    // Framerate box 'frat' == 0x66726174
+    if (!gst_byte_reader_get_uint32_be(&reader, &header_tag))
+      goto error;
+
+    if(header_tag == 0x66726174)
+    {
+    if (!gst_byte_reader_get_uint16_be (&reader, &den))
+      goto error;
+
+    if (!gst_byte_reader_get_uint16_be (&reader, &num))
+      goto error;
+
+    } else {
+      GST_ERROR_OBJECT (stream->pad, "Unable to read frat tag");
+      goto error;
+    }
+
+    // Maximum bitrate box 'brat' == 0x62726174
+    if (!gst_byte_reader_get_uint32_be(&reader, &header_tag))
+      goto error;
+
+    if(header_tag == 0x62726174)
+    {
+    if (!gst_byte_reader_get_uint32_be (&reader, &MaxBr))
+      goto error;
+    if (!gst_byte_reader_get_uint32_be (&reader, &AUF[0]))
+      goto error;
+    
+    if(stream->jp2kInfos.interlace){
+      if (!gst_byte_reader_get_uint32_be (&reader, &AUF[1]))
+        goto error;
+      }
+    } else {
+      GST_ERROR_OBJECT (stream->pad, "Unable to read brat tag");
+      goto error;
+    }
+
+    if(stream->jp2kInfos.interlace){
+       // Field Coding Box
+      if (!gst_byte_reader_get_uint32_be(&reader, &header_tag))
+        goto error;
+    
+      // Field Coding Box 'fiel' == 0x6669656c
+      if(header_tag == 0x6669656c)
+      {
+        if( !gst_byte_reader_get_uint8(&reader, &Fic))
+          goto error;
+
+        if( !gst_byte_reader_get_uint8(&reader, &Fio))
+          goto error;
+      } else {
+        GST_ERROR_OBJECT (stream->pad, "Unable to read fiel tag");
+        goto error;
+      }
+    }
+
+    // Time Code Box 'tcod' == 0x74636f64
+    if (!gst_byte_reader_get_uint32_be(&reader, &header_tag))
+        goto error;
+
+    if(header_tag == 0x74636f64)
+    {
+      if (!gst_byte_reader_get_uint32_be (&reader, &HHMMSSFF))
+        goto error;
+    } else {
+      GST_ERROR_OBJECT (stream->pad, "Unable to read tcod tag");
+      goto error;
+    }
+    
+    // Broadcast Color Box 'bcol' == 0x6263686c
+    if (!gst_byte_reader_get_uint32_be(&reader, &header_tag))
+      goto error;
+
+    if(header_tag == 0x62636f6c)
+    {
+      if (!gst_byte_reader_get_uint8 (&reader, &CollC))
+        goto error;
+    } else {
+      GST_ERROR_OBJECT (stream->pad, "Unable to read bcol tag");
+      goto error;
+    }
+
+    // Get raserved 8-bits
+    if (!gst_byte_reader_get_uint8 (&reader, &b))
+        goto error;
+
+  } else {
+    GST_ERROR_OBJECT (stream->pad, "Unable to read elsm tag");
+    goto error;
+  }
+  
+  int remaining = gst_byte_reader_get_remaining(&reader);
+
+  packet_size = remaining;
+
+  GST_DEBUG_OBJECT(stream->pad, "Size of first codestream in TS stream: %d remaining: %d",AUF[0], remaining);
+  
+  if(!gst_byte_reader_dup_data (&reader, remaining, &packet_data))
+  {
+    GST_ERROR("Required size %d > %d than remaining size in buffer", AUF[0], remaining);
+    goto error;
+  }
+  
+  buffer = gst_buffer_new_wrapped (packet_data, packet_size);
+  gst_buffer_list_add (buffer_list, buffer);
+
+  GstMapInfo map_info;
+
+  gst_buffer_map(buffer, &map_info, GST_MAP_READ);
+
+  //TODO: add support for interlace
+  if(stream->jp2kInfos.interlace)
+  {
+    // remaining = gst_byte_reader_get_remaining(&reader);
+
+    // if(!gst_byte_reader_dup_data (&reader, AUF[1], &packet_data))
+    // {
+    //   GST_ERROR("Required size %d > %d than remaining size in buffer", AUF[1], remaining);
+    //   goto error;
+    // }
+
+    // buffer = gst_buffer_new_wrapped (packet_data, packet_size);
+    // gst_buffer_list_add (buffer_list, buffer);
+  }
+
+  g_free (stream->data);
+  stream->data = NULL;
+  stream->current_size = 0;
+
+need_data:
+  return buffer_list;
+
+error:
+  {
+    GST_ERROR ("Failed to parse JP2K access unit");
+    g_free (stream->data);
+    stream->data = NULL;
+    stream->current_size = 0;
+    gst_buffer_list_unref (buffer_list);
+    return NULL;
+  }
+}
+
 static GstFlowReturn
 gst_ts_demux_push_pending_data (GstTSDemux * demux, TSDemuxStream * stream,
     MpegTSBaseProgram * target_program)
