func: static int ea_read_packet(AVFormatContext *s,
  
                            AVPacket *pkt)
  
  {
  
      EaDemuxContext *ea = s->priv_data;
  
      AVIOContext *pb = s->pb;
  
      int ret = 0;
  
      int packet_read = 0;
  
      unsigned int chunk_type, chunk_size;
  
      int key = 0;
  
      int av_uninit(num_samples);
  
  
  
      while (!packet_read) {
  
          chunk_type = avio_rl32(pb);
  
          chunk_size = (ea->big_endian ? avio_rb32(pb) : avio_rl32(pb)) - 8;
  
  
  
          switch (chunk_type) {
  
          /* audio data */
  
          case ISNh_TAG:
  
              /* header chunk also contains data; skip over the header portion*/
  
              avio_skip(pb, 32);
  
              chunk_size -= 32;
  
          case ISNd_TAG:
  
          case SCDl_TAG:
  
          case SNDC_TAG:
  
          case SDEN_TAG:
  
              if (!ea->audio_codec) {
  
                  avio_skip(pb, chunk_size);
  
                  break;
  
              } else if (ea->audio_codec == CODEC_ID_PCM_S16LE_PLANAR ||
  
                         ea->audio_codec == CODEC_ID_MP3) {
  
                  num_samples = avio_rl32(pb);
  
                  avio_skip(pb, 8);
  
                  chunk_size -= 12;
  
              }
  
              ret = av_get_packet(pb, pkt, chunk_size);
  
              if (ret < 0)
  
                  return ret;
  
              pkt->stream_index = ea->audio_stream_index;
  
  
  
              switch (ea->audio_codec) {
  
              case CODEC_ID_ADPCM_EA:
  
              case CODEC_ID_ADPCM_EA_R1:
  
              case CODEC_ID_ADPCM_EA_R2:
  
              case CODEC_ID_ADPCM_IMA_EA_EACS:
  
                  pkt->duration = AV_RL32(pkt->data);
  
                  break;
  
              case CODEC_ID_ADPCM_EA_R3:
  
                  pkt->duration = AV_RB32(pkt->data);
  
                  break;
  
              case CODEC_ID_ADPCM_IMA_EA_SEAD:
  
                  pkt->duration = ret * 2 / ea->num_channels;
  
                  break;
  
              case CODEC_ID_PCM_S16LE_PLANAR:
  
              case CODEC_ID_MP3:
  
                  pkt->duration = num_samples;
  
                  break;
  
              default:
  
                  pkt->duration = chunk_size / (ea->bytes * ea->num_channels);
  
              }
  
  
  
              packet_read = 1;
  
              break;
  
  
  
          /* ending tag */
  
          case 0:
  
          case ISNe_TAG:
  
          case SCEl_TAG:
  
          case SEND_TAG:
  
          case SEEN_TAG:
  
              ret = AVERROR(EIO);
  
              packet_read = 1;
  
              break;
  
  
  
          case MVIh_TAG:
  
          case kVGT_TAG:
  
          case pQGT_TAG:
  
          case TGQs_TAG:
  
          case MADk_TAG:
  
              key = AV_PKT_FLAG_KEY;
  
          case MVIf_TAG:
  
          case fVGT_TAG:
  
          case MADm_TAG:
  
          case MADe_TAG:
  
              avio_seek(pb, -8, SEEK_CUR);     // include chunk preamble
  
              chunk_size += 8;
  
              goto get_video_packet;
  
  
  
          case mTCD_TAG:
  
              avio_skip(pb, 8);  // skip ea dct header
  
              chunk_size -= 8;
  
              goto get_video_packet;
  
  
  
          case MV0K_TAG:
  
          case MPCh_TAG:
  
          case pIQT_TAG:
  
              key = AV_PKT_FLAG_KEY;
  
          case MV0F_TAG:
  
  get_video_packet:
  
              ret = av_get_packet(pb, pkt, chunk_size);
  
              if (ret < 0)
  
                  return ret;
  
              pkt->stream_index = ea->video_stream_index;
  
              pkt->flags |= key;
  
              packet_read = 1;
  
              break;
  
  
  
          default:
  
              avio_skip(pb, chunk_size);
  
              break;
  
          }
  
      }
  
  
  
      return ret;
  
  }
  