Send Concatinated SMS message using EasySMPP API (How to Add UDH Info) - sms

i am using c# API called EasySMPP, it is pretty great in sending single SMS, it is also good in send large SMS, but the recipient get the messages separately, which is not meaningful, what i am looking is how to modify the PDU so that i can append the UDH info.
How can i achieve adding a UHD info, here is the SubmitSM method from the API,
public int SubmitSM
(
byte sourceAddressTon,
byte sourceAddressNpi,
string sourceAddress,
byte destinationAddressTon,
byte destinationAddressNpi,
destinationAddress,
byte esmClass,
byte protocolId,
byte priorityFlag,
DateTime sheduleDeliveryTime,
DateTime validityPeriod,
byte registeredDelivery,
byte replaceIfPresentFlag,
byte dataCoding,
byte smDefaultMsgId,
byte[] message)
{
try
{
byte[] _destination_addr;
byte[] _source_addr;
byte[] _SUBMIT_SM_PDU;
byte[] _shedule_delivery_time;
byte[] _validity_period;
int _sequence_number;
int pos;
byte _sm_length;
_SUBMIT_SM_PDU = new byte[KernelParameters.MaxPduSize];
////////////////////////////////////////////////////////////////////////////////////////////////
/// Start filling PDU
Tools.CopyIntToArray(0x00000004, _SUBMIT_SM_PDU, 4);
_sequence_number = smscArray.currentSMSC.SequenceNumber;
Tools.CopyIntToArray(_sequence_number, _SUBMIT_SM_PDU, 12);
pos = 16;
_SUBMIT_SM_PDU[pos] = 0x00; //service_type
pos += 1;
_SUBMIT_SM_PDU[pos] = sourceAddressTon;
pos += 1;
_SUBMIT_SM_PDU[pos] = sourceAddressNpi;
pos += 1;
_source_addr = Tools.ConvertStringToByteArray(Tools.GetString(sourceAddress, 20, ""));
Array.Copy(_source_addr, 0, _SUBMIT_SM_PDU, pos, _source_addr.Length);
pos += _source_addr.Length;
_SUBMIT_SM_PDU[pos] = 0x00;
pos += 1;
_SUBMIT_SM_PDU[pos] = destinationAddressTon;
pos += 1;
_SUBMIT_SM_PDU[pos] = destinationAddressNpi;
pos += 1;
_destination_addr = Tools.ConvertStringToByteArray(Tools.GetString(destinationAddress, 20, ""));
Array.Copy(_destination_addr, 0, _SUBMIT_SM_PDU, pos, _destination_addr.Length);
pos += _destination_addr.Length;
_SUBMIT_SM_PDU[pos] = 0x00;
pos += 1;
_SUBMIT_SM_PDU[pos] = esmClass;
pos += 1;
_SUBMIT_SM_PDU[pos] = protocolId;
pos += 1;
_SUBMIT_SM_PDU[pos] = priorityFlag;
pos += 1;
_shedule_delivery_time = Tools.ConvertStringToByteArray(Tools.GetDateString(sheduleDeliveryTime));
Array.Copy(_shedule_delivery_time, 0, _SUBMIT_SM_PDU, pos, _shedule_delivery_time.Length);
pos += _shedule_delivery_time.Length;
_SUBMIT_SM_PDU[pos] = 0x00;
pos += 1;
_validity_period = Tools.ConvertStringToByteArray(Tools.GetDateString(validityPeriod));
Array.Copy(_validity_period, 0, _SUBMIT_SM_PDU, pos, _validity_period.Length);
pos += _validity_period.Length;
_SUBMIT_SM_PDU[pos] = 0x00;
pos += 1;
_SUBMIT_SM_PDU[pos] = registeredDelivery;
pos += 1;
_SUBMIT_SM_PDU[pos] = replaceIfPresentFlag;
pos += 1;
_SUBMIT_SM_PDU[pos] = dataCoding;
pos += 1;
_SUBMIT_SM_PDU[pos] = smDefaultMsgId;
pos += 1;
_sm_length = message.Length > 254 ? (byte)254 : (byte)message.Length;
_SUBMIT_SM_PDU[pos] = _sm_length;
pos += 1;
Array.Copy(message, 0, _SUBMIT_SM_PDU, pos, _sm_length);
pos += _sm_length;
Tools.CopyIntToArray(pos, _SUBMIT_SM_PDU, 0);
Send(_SUBMIT_SM_PDU, pos);
undeliveredMessages++;
return _sequence_number;
}
catch (Exception ex)
{
logMessage(LogLevels.LogExceptions, "SubmitSM | " + ex.ToString());
}
return -1;
}
Thanks a lot!!!!

As I can see, EasySMPP has option to split long text.
public int SendSms(String from, String to, bool splitLongText, String text, byte askDeliveryReceipt, byte esmClass, byte dataCoding)
Otherwise, smpp protocol has ability to do manually also.
Either in SAR parameters:
SAR_MSG_REF_NUM - reference, unique to all sms parts
SAR_SEGMENT_SEQNUM - sequence number (1,2,3...)
SAR_TOTAL_SEGMENTS - number of all sequences
or you can encapsulate in the beggining of the message
with UDHI set to 64
or you can set message in MESSAGE_PAYLOAD TLV and SMSC will do it for you.
Hope it helps

Here is the method where UDH is added.
public int SendSms(String from, String to,
bool splitLongText, String text,
byte askDeliveryReceipt,
byte esmClass, byte dataCoding)
{
int messageId = -1;
byte sourceAddressTon;
byte sourceAddressNpi;
string sourceAddress;
byte destinationAddressTon;
byte destinationAddressNpi;
string destinationAddress;
byte registeredDelivery;
byte maxLength;
sourceAddress = Tools.GetString(from, 20, "");
sourceAddressTon = getAddrTon(sourceAddress);
sourceAddressNpi = getAddrNpi(sourceAddress);
destinationAddress = Tools.GetString(to, 20, "");
destinationAddressTon = getAddrTon(destinationAddress);
destinationAddressNpi = getAddrNpi(destinationAddress);
registeredDelivery = askDeliveryReceipt;
if (dataCoding == 8)
{
// text = Tools.Endian2UTF(text);
maxLength = 70;
}
else
maxLength = 160;
if ((text.Length <= maxLength) || (splitLongText))
{
byte protocolId;
byte priorityFlag;
DateTime sheduleDeliveryTime;
DateTime validityPeriod;
byte replaceIfPresentFlag;
byte smDefaultMsgId;
// byte[] message = new byte[146];
byte[] udh = new byte[6];
string smsText = text;
byte[] message;
protocolId = 0;
priorityFlag = PriorityFlags.VeryUrgent;
sheduleDeliveryTime = DateTime.MinValue;
validityPeriod = DateTime.MinValue;
replaceIfPresentFlag =
ReplaceIfPresentFlags.DoNotReplace;
smDefaultMsgId = 0;
if (dataCoding == 8)
{
message = new byte[70];
}
else
{
message = new byte[146];
}
string[] lists = dataCoding == 8 ?
split_message_unicode(text) :
split_message_asci(text);
int count = 1;
foreach (string s in lists)
{
Array.Clear(message, 0, message.Length);
// while (smsText.Length > 0)
// {
int pos = 0;
// byte desc = Convert.ToByte('c');
byte headerLen = Convert.ToByte(05);
byte concat = Convert.ToByte(00);
byte refNo = Convert.ToByte(03);
byte sequenceNo = Convert.ToByte(03);
byte NoOfMessages = Convert.ToByte(lists.Length);
byte partNo = Convert.ToByte(count);
count++;
udh[pos] = headerLen;
pos++;
udh[pos] = concat;
pos++;
udh[pos] = refNo;
pos++;
udh[pos] = sequenceNo;
pos++;
udh[pos] = NoOfMessages;
pos++;
udh[pos] = partNo;
pos++;
Array.Copy(udh, 0, message, 0, pos);
if (dataCoding == 8)
{
int len = Tools.GetEthiopic(s).Length;
Array.Copy(Tools.GetEthiopic(s), 0, message,
pos, len);
//message =
Tools.GetEthiopic(smsText.Substring(0, smsText.Length >
maxLength ? maxLength : smsText.Length));
//message =
Encoding.UTF8.GetBytes(smsText.Substring(0, smsText.Length >
maxLength ? maxLength : smsText.Length));
}
else{
// message = Encoding.ASCII.GetBytes(s);
Array.Copy(Encoding.ASCII.GetBytes(s), 0,
message, pos, Encoding.ASCII.GetBytes(s).Length);
}
smsText = smsText.Remove(0, smsText.Length >
maxLength ? maxLength : smsText.Length);
messageId = SubmitSM(sourceAddressTon,
sourceAddressNpi, sourceAddress,
destinationAddressTon,
destinationAddressNpi, destinationAddress,
esmClass, protocolId,
priorityFlag,
sheduleDeliveryTime,
validityPeriod, registeredDelivery, replaceIfPresentFlag,
dataCoding, smDefaultMsgId,
message);
// }
}
}
else
{
byte[] data;
if (dataCoding == 8)
data = Tools.GetEthiopic(text);
//data = Encoding.UTF8.GetBytes(text);
else
data = Encoding.ASCII.GetBytes(text);
messageId = DataSM(sourceAddressTon, sourceAddressNpi,
sourceAddress,
destinationAddressTon,
destinationAddressNpi, destinationAddress,
esmClass, registeredDelivery,
dataCoding, data);
}
return messageId;
}
pass ems_class as 0x40, what you need to to is just to split your message in to parts, here is splitting method,
private string[] split_message_asci(string message)
{
int message_len = message.Length;
decimal val=(message.Length / 140m);
decimal parts = Math.Ceiling(val);
string[] strs = new string[(int)parts];
string str = string.Empty;
int interval=140;
int i =0;
int Count= 0;
while (i < message_len)
{
if (Count < (int)parts-1)
{
str = message.Substring(i, interval);
strs[Count] = str;
i += interval ;
}
else
{
str = message.Substring(i, message_len-i);
strs[Count] = str;
i += interval + 1;
}
Count++;
}
return strs;
}

Related

Processing code for image decoder returns þ

I'm trying to make a decoder for images in processing, but it returns þ no matter what I put in. Help would be much appreciated.
void setup() {
//size(255, 255);
colorMode(HSB);
String result = decode();
println(result);
saveStrings("output.txt", new String[]{result});
}
String decode() {
PImage img = loadImage("code.png");
//image(img, 0, 0);
img.loadPixels();
String decoded = "";
int[] chars = new int[255 * 255];
for (int i = 0; i < 255; i++) {
for (int j = 0; j < 255; j++) {
color col = img.pixels[i * 255 + j];//get(i, j);
if (hue(col) == 0 && saturation(col) == 0) {
chars[floor(hue(col) * 255 + saturation(col))] = j;
println((char) j);
}
}
}
decoded = new String(chars, 0, chars.length);
String[] list = decoded.split("\u0000");
StringBuilder builder = new StringBuilder();
for (String string : list) {
builder.append(string);
}
decoded = builder.toString();
return decoded;
}
The main problem is likely at if (hue(col) == 0 && saturation(col) == 0) {
The next line will always have 0 for hue(col) and saturation(col). This means you are always executing chars[0] = j;, and your final result has only one character (the þ you described).

NtRequestPort - parameter incorrect

I'm try to communicate with \Windows\SbApiPort port .
The problem is that I get an error from NtRequestPort (0xc000000d - status invalid parameter).
The parameters of PORT_MESSAGE are not documented so I don't know where is my problem...
I tried to change the length, CallbackId, but the same problem...
Thanks for the help !
Here is the code:
HANDLE hSection=0;
LARGE_INTEGER SecSize;
SecSize.LowPart=0x10000;
SecSize.HighPart=0x0;
if(NtCreateSection(&hSection, SECTION_ALL_ACCESS, NULL, &SecSize, PAGE_READWRITE,SEC_COMMIT ,NULL))
{
printf("couldn't create a section");
}
HANDLE hPort;
PORT_VIEW sectionInfo;
REMOTE_PORT_VIEW mapInfo;
byte ConnectDataBuffer[0x100];
DWORD Size = sizeof(ConnectDataBuffer);
UNICODE_STRING uStr;
WCHAR * uString=L"\\Windows\\SbApiPort";
DWORD maxSize;
SECURITY_QUALITY_OF_SERVICE qos;
for (int i=0 ; i < 0x100 ; i++)
{
ConnectDataBuffer[i]=0xcc;
}
memset(&sectionInfo, 0, sizeof(sectionInfo));
memset(&mapInfo, 0, sizeof(mapInfo));
memset(&mapInfo, 0, sizeof(mapInfo));
memset(&qos, 0, sizeof(qos));
qos.Length = sizeof(SECURITY_QUALITY_OF_SERVICE);
qos.ImpersonationLevel = SecurityImpersonation;
qos.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING;
qos.EffectiveOnly = TRUE;
sectionInfo.Length = sizeof(LPC_SECTION_OWNER_MEMORY);
sectionInfo.SectionHandle = hSection;
sectionInfo.SectionOffset = 0;
sectionInfo.ViewSize = 0x10000;
sectionInfo.ViewBase = NULL;
sectionInfo.ViewRemoteBase = NULL;
mapInfo.Length = sizeof(LPC_SECTION_MEMORY);
mapInfo.ViewSize = 0;
mapInfo.ViewBase = NULL;
uStr.Length = wcslen(uString)*2;
uStr.MaximumLength = wcslen(uString)*2+2;
uStr.Buffer =uString;
NTSTATUS res = NtConnectPort(&hPort,&uStr,&qos,&sectionInfo,&mapInfo,&maxSize,(DWORD*)&ConnectDataBuffer,&Size);
if (res)
{
printf("Could not connect to LPC port.\n -%x", res);
return 1;
}
PORT_MESSAGE PortMessage;
ZeroMemory(&PortMessage,sizeof(PORT_MESSAGE));
PortMessage.u1.Length = 0x20;
PortMessage.u2.s2.DataInfoOffset = 15;
PortMessage.u2.ZeroInit = 0x20;
PortMessage.MessageId = LPC_REQUEST;
PortMessage.ClientViewSize = 0x20;
PortMessage.ClientId.UniqueProcess = GetCurrentProcess();
PortMessage.ClientId.UniqueThread = GetCurrentThread();
PortMessage.CallbackId = 0;
res = NtRequestPort(hPort, &PortMessage);
if (res)
{
printf("Could not request LPC port.\n -%x", res);
return 1;
}
printf("End\n", res);

Affine Cipher Code in java that also encrypts integer

private static int firstKey = 5;
private static int secondKey = 19;
private static int module = 26;
public static void main(String[] args) {
String input = "abcdefghijklmnopqrstuvwxyz";
String cipher = encrypt(input);
String deciphered = decrypt(cipher);
System.out.println("Source: " + input);
System.out.println("Encrypted: " + cipher);
System.out.println("Decrypted: " + deciphered);
}
static String encrypt(String input) {
StringBuilder builder = new StringBuilder();
for (int in = 0; in < input.length(); in++) {
char character = input.charAt(in);
// if (Character.isLetter(character)) {
character = (char) ((firstKey * (character - 'a') + secondKey) % module + 'a');
//}
builder.append(character);
}
return builder.toString();
}
static String decrypt(String input) {
StringBuilder builder = new StringBuilder();
// compute firstKey^-1 aka "modular inverse"
BigInteger inverse = BigInteger.valueOf(firstKey).modInverse(BigInteger.valueOf(module));
// perform actual decryption
for (int in = 0; in < input.length(); in++) {
char character = input.charAt(in);
// if (Character.isLetter(character)) {
int decoded = inverse.intValue() * (character - 'a' - secondKey + module);
character = (char) (decoded % module + 'a');
//}
builder.append(character);
}
return builder.toString();
}
i got this code from this site itself
but the above code does not decrpyt the integers ..
please help
above is a code that i got from this site.
but this doesnot decrypts the integer.
please help.
I have added two more functiond that incrypt and decrypt integers that work.You can use them when you want to incrypt, decrypt integers, and the previous functions when you want to enc/dec lower case alphabets
//Code
import java.math.BigInteger;
public class main{
private static int firstKey = 5;
private static int secondKey = 19;
private static int module = 26;
public static void main(String[] args) {
String input = "abcdefghijklmnopqrstuvwxyz";
String cipher = encrypt(input);
String deciphered = decrypt(cipher);
System.out.println("Source: " + input);
System.out.println("Encrypted: " + cipher);
System.out.println("Decrypted: " + deciphered);
System.out.println("\n");
//for Integer
String input1 = "826429837598327598327549832";
String cipher1 = encryptInt(input1);
String deciphered1 = decryptInt(cipher1);
System.out.println("Source: " + input1);
System.out.println("Encrypted: " + cipher1);
System.out.println("Decrypted: " + deciphered1);
}
static String encrypt(String input) {
StringBuilder builder = new StringBuilder();
for (int in = 0; in < input.length(); in++) {
char character = input.charAt(in);
// if (Character.isLetter(character)) {
character = (char) ((firstKey * (character - 'a') + secondKey) % module + 'a');
//}
builder.append(character);
}
return builder.toString();
}
static String decrypt(String input) {
StringBuilder builder = new StringBuilder();
// compute firstKey^-1 aka "modular inverse"
BigInteger inverse = BigInteger.valueOf(firstKey).modInverse(BigInteger.valueOf(module));
// perform actual decryption
for (int in = 0; in < input.length(); in++) {
char character = input.charAt(in);
// if (Character.isLetter(character)) {
int decoded = inverse.intValue() * (character - 'a' - secondKey + module);
character = (char) (decoded % module + 'a');
//}
builder.append(character);
}
return builder.toString();
}
//ENCRIPTION DECRIPTION FOR INTEGERS
static String encryptInt(String input) {
StringBuilder builder = new StringBuilder();
for (int in = 0; in < input.length(); in++) {
char character = input.charAt(in);
// if (Character.isLetter(character)) {
character = (char) ((firstKey * (character - '0') + secondKey) % module + '0');
//}
builder.append(character);
}
return builder.toString();
}
static String decryptInt(String input) {
StringBuilder builder = new StringBuilder();
// compute firstKey^-1 aka "modular inverse"
BigInteger inverse = BigInteger.valueOf(firstKey).modInverse(BigInteger.valueOf(module));
// perform actual decryption
for (int in = 0; in < input.length(); in++) {
char character = input.charAt(in);
// if (Character.isLetter(character)) {
int decoded = inverse.intValue() * (character - '0' - secondKey + module);
character = (char) (decoded % module + '0');
//}
builder.append(character);
}
return builder.toString();
}
}

String Encoding Umlaute

I want to send a string with a webclient and i have problems with german umlaute.
Checking with Fiddler, I see that the following conversion for the post parameter is made:
ä to %E4 (which is iso-8859-1 according to online encoder tool)
Do you know how i can achive this for WP7?
I tried already:
string urlstring = HttpUtility.UrlEncode("ä");
RESULT: %c3%a4
string urlstring1 = HttpUtility.HtmlEncode("ä");
RESULT: ä
Encoding isoenc = Encoding.GetEncoding("ISO-8859-1");
byte[] utf8characters = Encoding.UTF8.GetBytes("ä");
byte[] isoArray = Encoding.Convert(Encoding.UTF8, Encoding.GetEncoding("ISO-8859-1"),utf8characters);
string finalString = isoenc.GetString(isoArray,0, isoArray.Length);
RESULT: ä
I also checked this silverlight tool where you can create custom encoding.. without success.
I'm getting really crazy about this issue, if anyone has an idea please let me know.
Thanks,
Ralf
The solution provided by nwellnhof is good, but the HttpUtility.UrlEncode overload that takes an encoding as parameter isn't available on Windows Phone. Fortunately, by decompiling the framework assemblies, it's easy to modify it to use the encoding you want:
public class HttpUtilityEx
{
public static string UrlEncode(string url, Encoding encoding)
{
if (url == null)
{
return null;
}
byte[] bytes = encoding.GetBytes(url);
int num = 0;
int num1 = 0;
int length = (int)bytes.Length;
for (int i = 0; i < length; i++)
{
char chr = (char)bytes[i];
if (chr == ' ')
{
num++;
}
else if (!IsSafe(chr))
{
num1++;
}
}
if ((num != 0 ? true : num1 != 0))
{
byte[] hex = new byte[length + num1 * 2];
int num2 = 0;
for (int j = 0; j < length; j++)
{
byte num3 = bytes[j];
char chr1 = (char)num3;
if (IsSafe(chr1))
{
int num4 = num2;
num2 = num4 + 1;
hex[num4] = num3;
}
else if (chr1 != ' ')
{
int num5 = num2;
num2 = num5 + 1;
hex[num5] = 37;
int num6 = num2;
num2 = num6 + 1;
hex[num6] = (byte)IntToHex(num3 >> 4 & 15);
int num7 = num2;
num2 = num7 + 1;
hex[num7] = (byte)IntToHex(num3 & 15);
}
else
{
int num8 = num2;
num2 = num8 + 1;
hex[num8] = 43;
}
}
bytes = hex;
}
return encoding.GetString(bytes, 0, (int)bytes.Length);
}
private static bool IsSafe(char ch)
{
if (ch >= 'a' && ch <= 'z' || ch >= 'A' && ch <= 'Z' || ch >= '0' && ch <= '9')
{
return true;
}
char chr = ch;
if (chr != '!')
{
switch (chr)
{
case '\'':
case '(':
case ')':
case '*':
case '-':
case '.':
{
break;
}
case '+':
case ',':
{
return false;
}
default:
{
if (chr != '\u005F')
{
return false;
}
else
{
break;
}
}
}
}
return true;
}
internal static char IntToHex(int n)
{
if (n <= 9)
{
return (char)(n + 48);
}
return (char)(n - 10 + 97);
}
}
From there, you just need to call it like you would for HttpUtility:
var result = HttpUtilityEx.UrlEncode("ä", Encoding.GetEncoding("ISO-8859-1"));
HttpUtility.UrlEncode has an optional second parameter which specifies the encoding. The following should work:
Encoding isoenc = Encoding.GetEncoding("ISO-8859-1");
String urlstring = HttpUtility.UrlEncode("ä", isoenc);

Audio encoding using avcodec_fill_audio_frame() and memory leaks

As a part of encoding decoded audio packets, I'm using avcodec_fill_audio_frame(). I'm passing allocated AVFrame pointer to along with buffer containing the decoded samples and other parameters number of channels, sample format, buffer size. Though the encoding is working fine I'm not able to completely eliminate the memory leaks. I've taken care of most of things but still I'm not able detect the leakage.
Below is the function which I'm using for encoding. Please suggest something.
AudioSample contains decoded data and it is completely managed in different class(free in class destructor). I'm freeing the AVFrame in FFmpegEncoder destructor and AVPacket is freed every time using av_free_packet() with av_packet_destruct enabled. What more do I need to free?
void FfmpegEncoder::WriteAudioSample(AudioSample *audS)
{
int num_audio_frame = 0;
AVCodecContext *c = NULL;
// AVFrame *frame;
AVPacket pkt;
av_init_packet(&pkt);
pkt.destruct = av_destruct_packet;
pkt.data = NULL;
pkt.size = 0;
int ret = 0, got_packet = 0;
c = m_out_aud_strm->codec;
static int64_t aud_pts_in = -1;
if((audS != NULL) && (audS->GetSampleLength() > 0) )
{
int byte_per_sample = av_get_bytes_per_sample(c->sample_fmt);
PRINT_VAL("Byte Per Sample ", byte_per_sample)
m_frame->nb_samples = (audS->GetSampleLength())/(c->channels*av_get_bytes_per_sample(c->sample_fmt));
if(m_frame->nb_samples == c->frame_size)
{
#if 1
if(m_need_resample && (c->channels >= 2))
{
uint8_t * t_buff1 = new uint8_t[audS->GetSampleLength()];
if(t_buff1 != NULL)
{
for(int64_t i = 0; i< m_frame->nb_samples; i++)
{
memcpy(t_buff1 + i*byte_per_sample, (uint8_t*)((uint8_t*)audS->GetAudioSampleData() + i*byte_per_sample*c->channels), byte_per_sample);
memcpy(t_buff1 + (audS->GetSampleLength())/2 + i*byte_per_sample, (uint8_t*)((uint8_t*)audS->GetAudioSampleData() + i*byte_per_sample*c->channels+ byte_per_sample), byte_per_sample);
}
audS->FillAudioSample(t_buff1, audS->GetSampleLength());
delete[] t_buff1;
}
}
#endif
ret = avcodec_fill_audio_frame(m_frame, c->channels, c->sample_fmt, (uint8_t*)audS->GetAudioSampleData(),m_frame->nb_samples*byte_per_sample*c->channels, 0);
//ret = avcodec_fill_audio_frame(&frame, c->channels, c->sample_fmt, t_buff,frame.nb_samples*byte_per_sample*c->channels, 0);
if(ret != 0)
{
PRINT_MSG("Avcodec Fill Audio Failed ")
}
else
{
got_packet = 0;
ret = avcodec_encode_audio2(c, &pkt, m_frame, &got_packet);
if(ret < 0 || got_packet == 0)
{
PRINT_MSG("failed to encode audio ")
}
else
{
PRINT_MSG("Audio Packet Encoded ");
aud_pts_in++;
pkt.pts = aud_pts_in;
pkt.dts = pkt.pts;
pkt.stream_index = m_out_aud_strm->index;
ret = av_interleaved_write_frame(oc, &pkt);
if(ret != 0)
{
PRINT_MSG("Error Write Audio PKT ")
}
else
{
PRINT_MSG("Audio PKT Writen ")
}
}
}
}
avcodec_flush_buffers(c);
// avcodec_free_frame(&frame);
}
av_free_packet(&pkt);
}
Thanks,
Pradeep
//================== SEND AUDIO OUTPUT =======================
void AVOutputStream::sendAudioOutput (AVFrame* inputFrame)
{
AVCodecContext *codecCtx = pOutputAudioStream->codec;
// set source data variables
sourceNumberOfChannels = inputFrame->channels;
sourceChannelLayout = inputFrame->channel_layout;
sourceSampleRate = inputFrame->sample_rate;
_sourceSampleFormat = (AVSampleFormat)inputFrame->format;
sourceNumberOfSamples = inputFrame->nb_samples;
// set destination data variables
destinationNumberOfChannels = codecCtx->channels;
destinationChannelLayout = codecCtx->channel_layout;
destinationSampleRate = codecCtx->sample_rate;
destinationSampleFormat = codecCtx->sample_fmt;//AV_SAMPLE_FMT_FLTP;//EncodecCtx->sample_fmt;
destinationLineSize = 0;
destinationData = NULL;
int returnVal = 0;
if (startDecode == false)
{
startDecode = true;
resamplerCtx = swr_alloc_set_opts(NULL,
destinationChannelLayout,
destinationSampleFormat,
destinationSampleRate,
sourceChannelLayout,
_sourceSampleFormat,
sourceSampleRate,
0,
NULL);
if (resamplerCtx == NULL)
{
std::cout << "Unable to create the resampler context for the audio frame";
isConnected = false;
}
// initialize the resampling context
returnVal = swr_init(resamplerCtx);
if (returnVal < 0)
{
std::cout << "Unable to init the resampler context, error:";
isConnected = false;
}
} //if (startDecode == false)
if (sourceSampleRate != 0)
destinationNumberOfSamples = destinationSampleRate/sourceSampleRate * sourceNumberOfSamples;
// allocate the destination samples buffer
returnVal = av_samples_alloc_array_and_samples(&destinationData,
&destinationLineSize,
destinationNumberOfChannels,
destinationNumberOfSamples,
destinationSampleFormat,
0);
if (returnVal < 0)
{
std::cout << "Unable to allocate destination samples, error";
isConnected = false;
}
// convert to destination format
returnVal = swr_convert(resamplerCtx,
destinationData,
destinationNumberOfSamples,
(const uint8_t **)inputFrame->data, //sourceData,
sourceNumberOfSamples);
if (returnVal < 0)
{
std::cout << "Resampling failed, error \n";
isConnected = false;
}
int bufferSize = av_samples_get_buffer_size(&destinationLineSize,
destinationNumberOfChannels,
destinationNumberOfSamples,
destinationSampleFormat,
0);
//whithout fifo
pOutputAudioFrame = av_frame_alloc();
pOutputAudioFrame->nb_samples = codecCtx->frame_size;//frameNumberOfSamples;
pOutputAudioFrame->format = codecCtx->sample_fmt;
pOutputAudioFrame->channel_layout = codecCtx->channel_layout;
pOutputAudioFrame->channels = codecCtx->channels;
pOutputAudioFrame->sample_rate = codecCtx->sample_rate;
returnVal = avcodec_fill_audio_frame(pOutputAudioFrame,
pOutputAudioFrame->channels,
(AVSampleFormat)pOutputAudioFrame->format,
(const uint8_t *)destinationData[0],
bufferSize,0);
pOutputAudioFrame->pts = inputFrame->pts;
if (returnVal < 0)
{
std::cout << "Unable to fill the audio frame wsampleIndexith captured audio data,error";
isConnected = false;
}
// encode the audio frame, fill a packet for streaming
av_init_packet(&outAudioPacket);
outAudioPacket.data = NULL;
outAudioPacket.size = 0;
outAudioPacket.dts = outAudioPacket.pts = 0;
int gotPacket;
// encoding
returnVal = avcodec_encode_audio2(codecCtx, &outAudioPacket, pOutputAudioFrame, &gotPacket);
// free buffers
av_freep(&destinationData[0]);
av_freep(&destinationData);
av_frame_free(&pOutputAudioFrame);
if (gotPacket)
{
outAudioPacket.stream_index = pOutputAudioStream->index;
outAudioPacket.flags |= AV_PKT_FLAG_KEY;
returnVal = av_interleaved_write_frame(pOutputFormatCtx, &outAudioPacket);
//returnVal = av_write_frame(pOutputFormatCtx, &outAudioPacket);
if (returnVal != 0)
{
std::cout << "Cannot write audio packet \n";
isConnected = false;
}
av_free_packet(&outAudioPacket);
} // if (gotPacket)
}
You can see after resample i free used buffers.
// free buffers
av_freep(&destinationData[0]);
av_freep(&destinationData);

Resources