func: static int zero12v_decode_frame(AVCodecContext *avctx, void *data,
  
                                  int *got_frame, AVPacket *avpkt)
  
  {
  
      int line = 0, ret;
  
      const int width = avctx->width;
  
      AVFrame *pic = data;
  
      uint16_t *y, *u, *v;
  
      const uint8_t *line_end, *src = avpkt->data;
  
      int stride = avctx->width * 8 / 3;
  
  
  
      if (width == 1) {
  
          av_log(avctx, AV_LOG_ERROR, "Width 1 not supported.\n");
  
          return AVERROR_INVALIDDATA;
  
      }
  
  
  
      if (   avctx->codec_tag == MKTAG('0', '1', '2', 'v')
  
          && avpkt->size % avctx->height == 0
  
          && avpkt->size / avctx->height * 3 >= width * 8)
  
          stride = avpkt->size / avctx->height;
  
  
  
      if (avpkt->size < avctx->height * stride) {
  
          av_log(avctx, AV_LOG_ERROR, "Packet too small: %d instead of %d\n",
  
                 avpkt->size, avctx->height * stride);
  
          return AVERROR_INVALIDDATA;
  
      }
  
  
  
      if ((ret = ff_get_buffer(avctx, pic, 0)) < 0)
  
          return ret;
  
  
  
      pic->pict_type = AV_PICTURE_TYPE_I;
  
      pic->key_frame = 1;
  
  
  
      y = (uint16_t *)pic->data[0];
  
      u = (uint16_t *)pic->data[1];
  
      v = (uint16_t *)pic->data[2];
  
      line_end = avpkt->data + stride;
  
  
  
      while (line++ < avctx->height) {
  
          while (1) {
  
              uint32_t t = AV_RL32(src);
  
              src += 4;
  
              *u++ = t <<  6 & 0xFFC0;
  
              *y++ = t >>  4 & 0xFFC0;
  
              *v++ = t >> 14 & 0xFFC0;
  
  
  
              if (src >= line_end - 1) {
  
                  *y = 0x80;
  
                  src++;
  
                  line_end += stride;
  
                  y = (uint16_t *)(pic->data[0] + line * pic->linesize[0]);
  
                  u = (uint16_t *)(pic->data[1] + line * pic->linesize[1]);
  
                  v = (uint16_t *)(pic->data[2] + line * pic->linesize[2]);
  
                  break;
  
              }
  
  
  
              t = AV_RL32(src);
  
              src += 4;
  
              *y++ = t <<  6 & 0xFFC0;
  
              *u++ = t >>  4 & 0xFFC0;
  
              *y++ = t >> 14 & 0xFFC0;
  
              if (src >= line_end - 2) {
  
                  if (!(width & 1)) {
  
                      *y = 0x80;
  
                      src += 2;
  
                  }
  
                  line_end += stride;
  
                  y = (uint16_t *)(pic->data[0] + line * pic->linesize[0]);
  
                  u = (uint16_t *)(pic->data[1] + line * pic->linesize[1]);
  
                  v = (uint16_t *)(pic->data[2] + line * pic->linesize[2]);
  
                  break;
  
              }
  
  
  
              t = AV_RL32(src);
  
              src += 4;
  
              *v++ = t <<  6 & 0xFFC0;
  
              *y++ = t >>  4 & 0xFFC0;
  
              *u++ = t >> 14 & 0xFFC0;
  
  
  
              if (src >= line_end - 1) {
  
                  *y = 0x80;
  
                  src++;
  
                  line_end += stride;
  
                  y = (uint16_t *)(pic->data[0] + line * pic->linesize[0]);
  
                  u = (uint16_t *)(pic->data[1] + line * pic->linesize[1]);
  
                  v = (uint16_t *)(pic->data[2] + line * pic->linesize[2]);
  
                  break;
  
              }
  
  
  
              t = AV_RL32(src);
  
              src += 4;
  
              *y++ = t <<  6 & 0xFFC0;
  
              *v++ = t >>  4 & 0xFFC0;
  
              *y++ = t >> 14 & 0xFFC0;
  
  
  
              if (src >= line_end - 2) {
  
                  if (width & 1) {
  
                      *y = 0x80;
  
                      src += 2;
  
                  }
  
                  line_end += stride;
  
                  y = (uint16_t *)(pic->data[0] + line * pic->linesize[0]);
  
                  u = (uint16_t *)(pic->data[1] + line * pic->linesize[1]);
  
                  v = (uint16_t *)(pic->data[2] + line * pic->linesize[2]);
  
                  break;
  
              }
  
          }
  
      }
  
  
  
      *got_frame = 1;
  
  
  
      return avpkt->size;
  
  }
  