~ubuntu-branches/ubuntu/precise/gst-plugins-bad0.10/precise-proposed

« back to all changes in this revision

Viewing changes to ext/faad/gstfaad.c

Tags: upstream-0.10.5.3
Import upstream version 0.10.5.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
323
323
            &channels) < 0)
324
324
      goto init_failed;
325
325
 
326
 
    GST_DEBUG_OBJECT (faad, "channels=%u, rate=%u", channels, samplerate);
 
326
    GST_DEBUG_OBJECT (faad, "codec_data init: channels=%u, rate=%u", channels,
 
327
        samplerate);
327
328
 
328
329
    /* not updating these here, so they are updated in the
329
330
     * chain function, and new caps are created etc. */
339
340
  } else if ((value = gst_structure_get_value (str, "framed")) &&
340
341
      g_value_get_boolean (value) == TRUE) {
341
342
    faad->packetised = TRUE;
 
343
    GST_DEBUG_OBJECT (faad, "we have packetized audio");
342
344
  } else {
343
345
    faad->init = FALSE;
344
346
  }
438
440
*/
439
441
 
440
442
static GstAudioChannelPosition *
441
 
gst_faad_chanpos_to_gst (guchar * fpos, guint num)
 
443
gst_faad_chanpos_to_gst (GstFaad * faad, guchar * fpos, guint num,
 
444
    gboolean * channel_map_failed)
442
445
{
443
446
  GstAudioChannelPosition *pos = g_new (GstAudioChannelPosition, num);
444
447
  guint n;
445
448
  gboolean unknown_channel = FALSE;
446
449
 
 
450
  *channel_map_failed = FALSE;
 
451
 
 
452
  /* special handling for the common cases for mono and stereo */
 
453
  if (num == 1 && fpos[0] == FRONT_CHANNEL_CENTER) {
 
454
    GST_DEBUG_OBJECT (faad, "mono common case; won't set channel positions");
 
455
    return NULL;
 
456
  } else if (num == 2 && fpos[0] == FRONT_CHANNEL_LEFT
 
457
      && fpos[1] == FRONT_CHANNEL_RIGHT) {
 
458
    GST_DEBUG_OBJECT (faad, "stereo common case; won't set channel positions");
 
459
    return NULL;
 
460
  }
 
461
 
447
462
  for (n = 0; n < num; n++) {
 
463
    GST_DEBUG_OBJECT (faad, "faad channel %d as %d", n, fpos[n]);
448
464
    switch (fpos[n]) {
449
465
      case FRONT_CHANNEL_LEFT:
450
466
        pos[n] = GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT;
478
494
        pos[n] = GST_AUDIO_CHANNEL_POSITION_LFE;
479
495
        break;
480
496
      default:
 
497
        GST_DEBUG_OBJECT (faad, "unknown channel %d at %d", fpos[n], n);
481
498
        unknown_channel = TRUE;
482
499
        break;
483
500
    }
484
501
  }
485
502
  if (unknown_channel) {
 
503
    g_free (pos);
 
504
    pos = NULL;
486
505
    switch (num) {
487
506
      case 1:{
488
 
        GST_DEBUG ("FAAD reports unknown 1 channel mapping. Forcing to mono");
489
 
        pos[0] = GST_AUDIO_CHANNEL_POSITION_FRONT_MONO;
 
507
        GST_DEBUG_OBJECT (faad,
 
508
            "FAAD reports unknown 1 channel mapping. Forcing to mono");
490
509
        break;
491
510
      }
492
511
      case 2:{
493
 
        GST_DEBUG ("FAAD reports unknown 2 channel mapping. Forcing to stereo");
494
 
        pos[0] = GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT;
495
 
        pos[1] = GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT;
 
512
        GST_DEBUG_OBJECT (faad,
 
513
            "FAAD reports unknown 2 channel mapping. Forcing to stereo");
496
514
        break;
497
515
      }
498
516
      default:{
499
517
        GST_WARNING ("Unsupported FAAD channel position 0x%x encountered",
500
518
            fpos[n]);
501
 
        g_free (pos);
502
 
        pos = NULL;
 
519
        *channel_map_failed = TRUE;
503
520
        break;
504
521
      }
505
522
    }
519
536
  if (!supported_positions) {
520
537
    guchar *supported_fpos = g_new0 (guchar, num_supported_positions);
521
538
    gint n;
 
539
    gboolean map_failed;
522
540
 
523
541
    for (n = 0; n < num_supported_positions; n++) {
524
542
      supported_fpos[n] = n + FRONT_CHANNEL_CENTER;
525
543
    }
526
 
    supported_positions = gst_faad_chanpos_to_gst (supported_fpos,
527
 
        num_supported_positions);
 
544
    supported_positions = gst_faad_chanpos_to_gst (faad, supported_fpos,
 
545
        num_supported_positions, &map_failed);
528
546
    g_free (supported_fpos);
529
547
  }
530
548
 
589
607
        /* put channel information here */
590
608
        if (faad->channel_positions) {
591
609
          GstAudioChannelPosition *pos;
 
610
          gboolean map_failed;
592
611
 
593
 
          pos = gst_faad_chanpos_to_gst (faad->channel_positions,
594
 
              faad->channels);
595
 
          if (!pos) {
 
612
          pos = gst_faad_chanpos_to_gst (faad, faad->channel_positions,
 
613
              faad->channels, &map_failed);
 
614
          if (map_failed) {
596
615
            gst_structure_free (str);
597
616
            continue;
598
617
          }
599
 
          gst_audio_set_channel_positions (str, pos);
600
 
          g_free (pos);
 
618
          if (pos) {
 
619
            gst_audio_set_channel_positions (str, pos);
 
620
            g_free (pos);
 
621
          }
601
622
        } else {
602
623
          gst_audio_set_structure_channel_positions_list (str,
603
624
              supported_positions, num_supported_positions);
1011
1032
{
1012
1033
  GstAudioChannelPosition *pos;
1013
1034
  gboolean ret;
 
1035
  gboolean channel_map_failed;
1014
1036
  GstCaps *caps;
1015
1037
 
1016
1038
  /* store new negotiation information */
1029
1051
 
1030
1052
  faad->bps = 16 / 8;
1031
1053
 
1032
 
  pos = gst_faad_chanpos_to_gst (faad->channel_positions, faad->channels);
1033
 
  if (!pos) {
 
1054
  channel_map_failed = FALSE;
 
1055
  pos =
 
1056
      gst_faad_chanpos_to_gst (faad, faad->channel_positions, faad->channels,
 
1057
      &channel_map_failed);
 
1058
  if (channel_map_failed) {
1034
1059
    GST_DEBUG_OBJECT (faad, "Could not map channel positions");
1035
1060
    gst_caps_unref (caps);
1036
1061
    return FALSE;
1037
1062
  }
1038
 
  gst_audio_set_channel_positions (gst_caps_get_structure (caps, 0), pos);
1039
 
  g_free (pos);
 
1063
  if (pos) {
 
1064
    gst_audio_set_channel_positions (gst_caps_get_structure (caps, 0), pos);
 
1065
    g_free (pos);
 
1066
  }
1040
1067
 
1041
 
  GST_DEBUG ("New output caps: %" GST_PTR_FORMAT, caps);
 
1068
  GST_DEBUG_OBJECT (faad, "New output caps: %" GST_PTR_FORMAT, caps);
1042
1069
 
1043
1070
  ret = gst_pad_set_caps (faad->srcpad, caps);
1044
1071
  gst_caps_unref (caps);
1132
1159
  return TRUE;
1133
1160
}
1134
1161
 
1135
 
/*
1136
 
  clips buffer to currently configured segment. Returns FALSE if the buffer 
1137
 
  has to be dropped.
1138
 
*/
1139
 
 
1140
 
static gboolean
1141
 
clip_outgoing_buffer (GstFaad * faad, GstBuffer * buffer)
1142
 
{
1143
 
  gint64 start, stop, cstart, cstop, diff;
1144
 
  gboolean res = TRUE;
1145
 
 
1146
 
  if (faad->segment->format != GST_FORMAT_TIME)
1147
 
    goto beach;
1148
 
 
1149
 
  start = GST_BUFFER_TIMESTAMP (buffer);
1150
 
  stop = start + GST_BUFFER_DURATION (buffer);
1151
 
 
1152
 
  if (gst_segment_clip (faad->segment, GST_FORMAT_TIME,
1153
 
          start, stop, &cstart, &cstop)) {
1154
 
    diff = cstart - start;
1155
 
    if (diff > 0) {
1156
 
      GST_BUFFER_TIMESTAMP (buffer) = cstart;
1157
 
      GST_BUFFER_DURATION (buffer) -= diff;
1158
 
 
1159
 
      /* time->frames->bytes */
1160
 
      diff =
1161
 
          faad->bps * faad->channels * GST_CLOCK_TIME_TO_FRAMES (diff,
1162
 
          faad->samplerate);
1163
 
      GST_BUFFER_DATA (buffer) += diff;
1164
 
      GST_BUFFER_SIZE (buffer) -= diff;
1165
 
    }
1166
 
    diff = cstop - stop;
1167
 
    if (diff > 0) {
1168
 
      GST_BUFFER_DURATION (buffer) -= diff;
1169
 
      /* time->frames->bytes */
1170
 
      diff =
1171
 
          faad->bps * faad->channels * GST_CLOCK_TIME_TO_FRAMES (diff,
1172
 
          faad->samplerate);
1173
 
      /* update size */
1174
 
      GST_BUFFER_SIZE (buffer) -= diff;
1175
 
    }
1176
 
  } else {
1177
 
    GST_DEBUG_OBJECT (faad, "buffer is outside configured segment");
1178
 
    res = FALSE;
1179
 
  }
1180
 
 
1181
 
beach:
1182
 
  return res;
1183
 
}
1184
 
 
1185
1162
static GstFlowReturn
1186
1163
gst_faad_chain (GstPad * pad, GstBuffer * buffer)
1187
1164
{
1389
1366
        faad->sum_dur_out += GST_BUFFER_DURATION (outbuf);
1390
1367
        GST_OBJECT_UNLOCK (faad);
1391
1368
 
1392
 
        if (clip_outgoing_buffer (faad, outbuf)) {
 
1369
        if ((outbuf = gst_audio_buffer_clip (outbuf, faad->segment,
 
1370
                    faad->samplerate, faad->bps * faad->channels))) {
1393
1371
          GST_LOG_OBJECT (faad,
1394
1372
              "pushing buffer, off=%" G_GUINT64_FORMAT ", ts=%" GST_TIME_FORMAT,
1395
1373
              GST_BUFFER_OFFSET (outbuf),
1397
1375
          ret = gst_pad_push (faad->srcpad, outbuf);
1398
1376
          if (ret != GST_FLOW_OK)
1399
1377
            goto out;
1400
 
        } else
1401
 
          gst_buffer_unref (outbuf);
 
1378
        }
1402
1379
      }
1403
1380
    }
1404
1381
  }
1493
1470
        return GST_STATE_CHANGE_FAILURE;
1494
1471
      break;
1495
1472
    case GST_STATE_CHANGE_READY_TO_PAUSED:
1496
 
      gst_segment_init (faad->segment, GST_FORMAT_UNDEFINED);
 
1473
      gst_segment_init (faad->segment, GST_FORMAT_TIME);
1497
1474
      break;
1498
1475
    default:
1499
1476
      break;